Bug 1449166: Trick GTK into using values from gtk_window_resize when showing maximized windows. r=karlt
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 19 Apr 2018 14:35:37 +0200
changeset 460824 c2f10e92f864353ba95e5f48243f452b3d975bcc
parent 460823 1ce48405e58a609299a84192df04d340cd90de63
child 460825 7e1f48fed0da8bcdb8e7306510b22dadcb800090
push id165
push userfmarier@mozilla.com
push dateMon, 30 Apr 2018 23:50:51 +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;
     }