Bug 1449166: Trick GTK into using values from gtk_window_resize when showing maximized windows. r?karlt draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 19 Apr 2018 14:35:37 +0200
changeset 787827 195b98d766c2f8d01a53b50e02f78290d756fed5
parent 787826 949ea58cd1d56a3310bcabc36f2271f05c621577
child 788237 05842fb0948244e40f61b1c17905a0d41dec0b1b
child 788238 ea6db3f9c20af0af3c1ec22a61a3e370b1f1fce6
push id107796
push userbmo:emilio@crisal.io
push dateWed, 25 Apr 2018 10:57:04 +0000
reviewerskarlt
bugs1449166
milestone61.0a1
Bug 1449166: Trick GTK into using values from gtk_window_resize when showing maximized windows. r?karlt So as to provide a sensible size for the window when the user exits maximized state. MozReview-Commit-ID: DSXawb85xmL
widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -3322,16 +3322,43 @@ nsWindow::OnWindowStateEvent(GtkWidget *
               (GDK_WINDOW_STATE_ICONIFIED|GDK_WINDOW_STATE_WITHDRAWN));
         if (mHasMappedToplevel != mapped) {
             SetHasMappedToplevel(mapped);
         }
         return;
     }
     // else the widget is a shell widget.
 
+    // The block below is a bit evil.
+    //
+    // When a window is resized before it is shown, gtk_window_resize() delays
+    // resizes until the window is shown.  If gtk_window_state_event() sees a
+    // GDK_WINDOW_STATE_MAXIMIZED change [1] before the window is shown, then
+    // gtk_window_compute_configure_request_size() ignores the values from the
+    // resize [2].  See bug 1449166 for an example of how this could happen.
+    //
+    // [1] https://gitlab.gnome.org/GNOME/gtk/blob/3.22.30/gtk/gtkwindow.c#L7967
+    // [2] https://gitlab.gnome.org/GNOME/gtk/blob/3.22.30/gtk/gtkwindow.c#L9377
+    //
+    // In order to provide a sensible size for the window when the user exits
+    // maximized state, we hide the GDK_WINDOW_STATE_MAXIMIZED change from
+    // gtk_window_state_event() so as to trick GTK into using the values from
+    // gtk_window_resize() in its configure request.
+    //
+    // We instead notify gtk_window_state_event() of the maximized state change
+    // once the window is shown.
+    if (!mIsShown) {
+        aEvent->changed_mask = static_cast<GdkWindowState>
+            (aEvent->changed_mask & ~GDK_WINDOW_STATE_MAXIMIZED);
+    } else if (aEvent->changed_mask & GDK_WINDOW_STATE_WITHDRAWN &&
+               aEvent->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
+        aEvent->changed_mask = static_cast<GdkWindowState>
+            (aEvent->changed_mask | GDK_WINDOW_STATE_MAXIMIZED);
+    }
+
     // We don't care about anything but changes in the maximized/icon/fullscreen
     // states
     if ((aEvent->changed_mask
          & (GDK_WINDOW_STATE_ICONIFIED |
             GDK_WINDOW_STATE_MAXIMIZED |
             GDK_WINDOW_STATE_FULLSCREEN)) == 0) {
         return;
     }