Bug 1489463 - [Linux/Gtk] Call OnSizeAllocate() explicitly also from OnConfigureEvent(), r=jhorak
☠☠ backed out by c105b062c298 ☠ ☠
authorMartin Stransky <stransky@redhat.com>
Mon, 16 Dec 2019 09:52:27 +0000
changeset 507061 c9c256a84d8de828e6af4f04183ee8d0eb039a20
parent 507060 feb0e7470c707b14852f75e4cb4b362aa6030ce7
child 507062 d98ef30b82f7afbe50122ba5e259a01000d94980
push id36922
push userncsoregi@mozilla.com
push dateMon, 16 Dec 2019 17:21:47 +0000
treeherdermozilla-central@27d0d6cc2131 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjhorak
bugs1489463
milestone73.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1489463 - [Linux/Gtk] Call OnSizeAllocate() explicitly also from OnConfigureEvent(), r=jhorak Usually we update mBounds from OnSizeAllocate() which is called by Gtk when mContainer changes its actual size. However we need to set mBounds in advance at Resize() as JS code expect immediate window size change. When Resize() is called between SetSizeMode() calls (which maximize/unmaximize the window) we can miss OnSizeAllocate() Gtk call as actual mContainer size may not change from Gtk perspective and we end up with incorrect mBounds. To compensate it call OnSizeAllocate() explicitly also from OnConfigureEvent(). Differential Revision: https://phabricator.services.mozilla.com/D55941
widget/gtk/mozgtk/mozgtk.c
widget/gtk/nsWindow.cpp
--- a/widget/gtk/mozgtk/mozgtk.c
+++ b/widget/gtk/mozgtk/mozgtk.c
@@ -96,16 +96,17 @@ STUB(gdk_window_get_display)
 STUB(gdk_window_get_events)
 STUB(gdk_window_get_geometry)
 STUB(gdk_window_get_height)
 STUB(gdk_window_get_origin)
 STUB(gdk_window_get_parent)
 STUB(gdk_window_get_position)
 STUB(gdk_window_get_root_origin)
 STUB(gdk_window_get_screen)
+STUB(gtk_window_get_size)
 STUB(gdk_window_get_state)
 STUB(gdk_window_get_toplevel)
 STUB(gdk_window_get_update_area)
 STUB(gdk_window_get_user_data)
 STUB(gdk_window_get_visual)
 STUB(gdk_window_get_width)
 STUB(gdk_window_get_window_type)
 STUB(gdk_window_hide)
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -2532,19 +2532,16 @@ gboolean nsWindow::OnConfigureEvent(GtkW
       mWindowType == eWindowType_dialog) {
     // This check avoids unwanted rollup on spurious configure events from
     // Cygwin/X (bug 672103).
     if (mBounds.x != screenBounds.x || mBounds.y != screenBounds.y) {
       CheckForRollup(0, 0, false, true);
     }
   }
 
-  // This event indicates that the window position may have changed.
-  // mBounds.Size() is updated in OnSizeAllocate().
-
   NS_ASSERTION(GTK_IS_WINDOW(aWidget),
                "Configure event on widget that is not a GtkWindow");
   if (gtk_window_get_window_type(GTK_WINDOW(aWidget)) == GTK_WINDOW_POPUP) {
     // Override-redirect window
     //
     // These windows should not be moved by the window manager, and so any
     // change in position is a result of our direction.  mBounds has
     // already been set in std::move() or Resize(), and that is more
@@ -2559,16 +2556,34 @@ gboolean nsWindow::OnConfigureEvent(GtkW
   }
 
   mBounds.MoveTo(screenBounds.TopLeft());
 
   // XXX mozilla will invalidate the entire window after this move
   // complete.  wtf?
   NotifyWindowMoved(mBounds.x, mBounds.y);
 
+  // A GTK app would usually update its client area size in response to
+  // a "size-allocate" signal.
+  // However, we need to set mBounds in advance at Resize()
+  // as JS code expects immediate window size change.
+  // If Gecko requests a resize from GTK, but subsequently,
+  // before a corresponding "size-allocate" signal is emitted, the window is
+  // resized to its former size via other means, such as maximizing,
+  // then there is no "size-allocate" signal from which to update
+  // the value of mBounds. Similarly, if Gecko's resize request is refused
+  // by the window manager, then there will be no "size-allocate" signal.
+  // In the refused request case, the window manager is required to dispatch
+  // a ConfigureNotify event. mBounds can then be updated here.
+  // This seems to also be sufficient to update mBounds when Gecko resizes
+  // the window from maximized size and then immediately maximizes again.
+  GtkAllocation allocation = {-1, -1, 0, 0};
+  gtk_window_get_size(GTK_WINDOW(mShell), &allocation.width,
+                      &allocation.height);
+  OnSizeAllocate(&allocation);
   return FALSE;
 }
 
 void nsWindow::OnContainerUnrealize() {
   // The GdkWindows are about to be destroyed (but not deleted), so remove
   // their references back to their container widget while the GdkWindow
   // hierarchy is still available.
 
@@ -2581,18 +2596,20 @@ void nsWindow::OnContainerUnrealize() {
 }
 
 void nsWindow::OnSizeAllocate(GtkAllocation* aAllocation) {
   LOG(("nsWindow::OnSizeAllocate [%p] %d,%d -> %d x %d\n", (void*)this,
        aAllocation->x, aAllocation->y, aAllocation->width,
        aAllocation->height));
 
   LayoutDeviceIntSize size = GdkRectToDevicePixels(*aAllocation).Size();
-
-  if (mBounds.Size() == size) return;
+  if (mBounds.Size() == size) {
+    // We were already resized at nsWindow::OnConfigureEvent() so skip it.
+    return;
+  }
 
   // Invalidate the new part of the window now for the pending paint to
   // minimize background flashes (GDK does not do this for external resizes
   // of toplevels.)
   if (mBounds.width < size.width) {
     GdkRectangle rect = DevicePixelsToGdkRectRoundOut(LayoutDeviceIntRect(
         mBounds.width, 0, size.width - mBounds.width, size.height));
     gdk_window_invalidate_rect(mGdkWindow, &rect, FALSE);