Browse Source

fix: restoring X11 window should not remove previous maximize state (#37360)

* fix: restoring X11 window should not remove previous maximize state

Co-authored-by: Cheng Zhao <[email protected]>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <[email protected]>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
trop[bot] 2 years ago
parent
commit
87ec774248

+ 1 - 0
patches/chromium/.patches

@@ -127,3 +127,4 @@ cherry-pick-3235c1d1955b.patch
 expose_v8initializer_codegenerationcheckcallbackinmainthread.patch
 cherry-pick-43637378b14e.patch
 axselectedtextmarkerrange_should_not_be_backwards.patch
+fix_x11_window_restore_minimized_maximized_window.patch

+ 55 - 0
patches/chromium/fix_x11_window_restore_minimized_maximized_window.patch

@@ -0,0 +1,55 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Cheng Zhao <[email protected]>
+Date: Wed, 15 Feb 2023 11:30:56 +0900
+Subject: fix: restoring a X11 window should not remove its previous maximized
+ state
+
+On Linux after minimizing a maximized window, it will have both the
+"maximized" and "hidden" states, and restoring the window should only remove
+the "hidden" state, which makes it back a maximized window.
+
+However in the implementation of `X11Window::Restore`, both "maximized" and
+"hidden" states are removed, and a maximized window that was minimized will
+be resized to its normal size after calling Restore, while the correct
+behavior should be going back to the maximized state.
+
+Backported from:
+https://chromium-review.googlesource.com/c/chromium/src/+/4252946
+
+diff --git a/ui/ozone/platform/x11/x11_window.cc b/ui/ozone/platform/x11/x11_window.cc
+index 45e0a75a643c2d7a70af37cbf38dcbde52fdd0cf..b229800eafabb0c810430d615cc165ff1e356491 100644
+--- a/ui/ozone/platform/x11/x11_window.cc
++++ b/ui/ozone/platform/x11/x11_window.cc
+@@ -729,11 +729,16 @@ void X11Window::Minimize() {
+ }
+ 
+ void X11Window::Restore() {
+-  should_maximize_after_map_ = false;
+-  restore_in_flight_ = true;
+-  SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
+-                 x11::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
+-  SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_HIDDEN"), x11::Atom::None);
++  if (IsMinimized()) {
++    restore_in_flight_ = true;
++    SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_HIDDEN"),
++                   x11::Atom::None);
++  } else if (IsMaximized()) {
++    restore_in_flight_ = true;
++    should_maximize_after_map_ = false;
++    SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
++                   x11::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
++  }
+ }
+ 
+ PlatformWindowState X11Window::GetPlatformWindowState() const {
+@@ -1884,6 +1889,10 @@ bool X11Window::IsMinimized() const {
+ }
+ 
+ bool X11Window::IsMaximized() const {
++  // In X11, if a maximized window is minimized, it will have both the "hidden"
++  // and "maximized" states.
++  if (IsMinimized())
++    return false;
+   return (HasWMSpecProperty(window_properties_,
+                             x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT")) &&
+           HasWMSpecProperty(window_properties_,

+ 18 - 0
spec/api-browser-window-spec.ts

@@ -3977,6 +3977,24 @@ describe('BrowserWindow module', () => {
       w.hide();
       w.show();
     });
+
+    // TODO(zcbenz):
+    // This test does not run on Linux CI. See:
+    // https://github.com/electron/electron/issues/28699
+    ifit(process.platform === 'linux' && !process.env.CI)('should bring a minimized maximized window back to maximized state', async () => {
+      const w = new BrowserWindow({});
+      const maximize = emittedOnce(w, 'maximize');
+      w.maximize();
+      await maximize;
+      const minimize = emittedOnce(w, 'minimize');
+      w.minimize();
+      await minimize;
+      expect(w.isMaximized()).to.equal(false);
+      const restore = emittedOnce(w, 'restore');
+      w.restore();
+      await restore;
+      expect(w.isMaximized()).to.equal(true);
+    });
   });
 
   // TODO(dsanders11): Enable once maximize event works on Linux again on CI