Repository: electron/electron (language: cpp)

Issue:
[Bug]: BrowserWindow.maximize Doesn't Fire show Event for Unshown Window
### Preflight Checklist

- [X] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
- [X] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
- [X] I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a bug report that matches the one I want to file, without success.

### Electron Version

19.0.0-nightly.20220207

### What operating system are you using?

Windows

### Operating System Version

Windows 10

### What arch are you using?

x64

### Last Known Working Electron version

_No response_

### Expected Behavior

An unshown window becomes shown if `maximize()` is called, so a 'show' event should be fired.

### Actual Behavior

A 'show' event is not fired.

### Testcase Gist URL

https://gist.github.com/b86e40446891294b1d1f3cfc19202c89

### Additional Information

I've only tested this on Windows so far. On macOS, #32947 means the window isn't shown anyway, so this issue is not applicable there for the moment.


Discussion / hints:

Fix patch:
diff --git a/shell/browser/native_window_views.cc b/shell/browser/native_window_views.cc
index 2d3d866fa71dc..a5c58964016c3 100644
--- a/shell/browser/native_window_views.cc
+++ b/shell/browser/native_window_views.cc
@@ -580,11 +580,13 @@ void NativeWindowViews::SetEnabledInternal(bool enable) {
 
 #if BUILDFLAG(IS_LINUX)
 void NativeWindowViews::Maximize() {
-  if (IsVisible())
+  if (IsVisible()) {
     widget()->Maximize();
-  else
+  } else {
     widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
                                             gfx::Rect());
+    NotifyWindowShow();
+  }
 }
 #endif
 
diff --git a/shell/browser/native_window_views_win.cc b/shell/browser/native_window_views_win.cc
index 0b4706f1cc198..747d7d064db61 100644
--- a/shell/browser/native_window_views_win.cc
+++ b/shell/browser/native_window_views_win.cc
@@ -178,12 +178,13 @@ HHOOK NativeWindowViews::mouse_hook_ = NULL;
 void NativeWindowViews::Maximize() {
   // Only use Maximize() when window is NOT transparent style
   if (!transparent()) {
-    if (IsVisible())
+    if (IsVisible()) {
       widget()->Maximize();
-    else
+    } else {
       widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
                                               gfx::Rect());
-    return;
+      NotifyWindowShow();
+    }
   } else {
     restore_bounds_ = GetBounds();
     auto display = display::Screen::GetScreen()->GetDisplayNearestWindow(
diff --git a/spec-main/api-browser-window-spec.ts b/spec-main/api-browser-window-spec.ts
index 5f3657001ab8c..8846507f80827 100644
--- a/spec-main/api-browser-window-spec.ts
+++ b/spec-main/api-browser-window-spec.ts
@@ -3509,6 +3509,29 @@ describe('BrowserWindow module', () => {
     });
   });
 
+  // TODO(dsanders11): Enable once maximize event works on Linux again on CI
+  ifdescribe(process.platform !== 'linux')('BrowserWindow.maximize()', () => {
+    afterEach(closeAllWindows);
+    // TODO(dsanders11): Disabled on macOS, see https://github.com/electron/electron/issues/32947
+    ifit(process.platform !== 'darwin')('should show the window if it is not currently shown', async () => {
+      const w = new BrowserWindow({ show: false });
+      const hidden = emittedOnce(w, 'hide');
+      const shown = emittedOnce(w, 'show');
+      const maximize = emittedOnce(w, 'maximize');
+      expect(w.isVisible()).to.be.false('visible');
+      w.maximize();
+      await maximize;
+      expect(w.isVisible()).to.be.true('visible');
+      // Even if the window is already maximized
+      w.hide();
+      await hidden;
+      expect(w.isVisible()).to.be.false('visible');
+      w.maximize();
+      await shown; // Ensure a 'show' event happens when it becomes visible
+      expect(w.isVisible()).to.be.true('visible');
+    });
+  });
+
   describe('BrowserWindow.unmaximize()', () => {
     afterEach(closeAllWindows);
     it('should restore the previous window position', () => {


Test patch: