Bug 1424974 - Honor mShell as top-level window, r?jhorak draft
authorMartin Stransky <stransky@redhat.com>
Wed, 20 Dec 2017 11:10:36 +0100
changeset 714022 4407fc6c4dcdd99988592157200e02595148eda8
parent 713183 2d580aeac901ce5c61a4e5445b46906ce3cf33d8
child 744490 98bb9143fdca9f2932603c31d60ff858df75c7ff
push id93813
push userstransky@redhat.com
push dateThu, 21 Dec 2017 13:39:11 +0000
reviewersjhorak
bugs1424974
milestone59.0a1
Bug 1424974 - Honor mShell as top-level window, r?jhorak When drawing to mContainer we still need to honor mShell as top-level window. It means we have to listen property-notify-event there (as it's window specific), get _NET_FRAME_EXTENTS here and use at nsWindow::SetWindowClass(). MozReview-Commit-ID: HYbNS0Lfyjy
widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -1515,30 +1515,30 @@ nsWindow::GetClientBounds()
     return rect;
 }
 
 void
 nsWindow::UpdateClientOffset()
 {
     AUTO_PROFILER_LABEL("nsWindow::UpdateClientOffset", GRAPHICS);
 
-    if (!mIsTopLevel || !mShell || !mGdkWindow || !mIsX11Display ||
+    if (!mIsTopLevel || !mShell || !mIsX11Display ||
         gtk_window_get_window_type(GTK_WINDOW(mShell)) == GTK_WINDOW_POPUP) {
         mClientOffset = nsIntPoint(0, 0);
         return;
     }
 
     GdkAtom cardinal_atom = gdk_x11_xatom_to_atom(XA_CARDINAL);
 
     GdkAtom type_returned;
     int format_returned;
     int length_returned;
     long *frame_extents;
 
-    if (!gdk_property_get(mGdkWindow,
+    if (!gdk_property_get(gtk_widget_get_window(mShell),
                           gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE),
                           cardinal_atom,
                           0, // offset
                           4*4, // length
                           FALSE, // delete
                           &type_returned,
                           &format_returned,
                           &length_returned,
@@ -3797,16 +3797,18 @@ nsWindow::Create(nsIWidget* aParent,
         GtkStyleContext* style = gtk_widget_get_style_context(mShell);
         drawToContainer =
             (mIsCSDAvailable && GetCSDSupportLevel() == CSD_SUPPORT_FLAT ) ||
             gtk_style_context_has_class(style, "csd");
 #endif
         eventWidget = (drawToContainer) ? container : mShell;
 
         gtk_widget_add_events(eventWidget, kEvents);
+        if (drawToContainer)
+            gtk_widget_add_events(mShell, GDK_PROPERTY_CHANGE_MASK);
 
         // Prevent GtkWindow from painting a background to avoid flickering.
         gtk_widget_set_app_paintable(eventWidget, TRUE);
 
         // If we draw to mContainer window then configure it now because
         // gtk_container_add() realizes the child widget.
         gtk_widget_set_has_window(container, drawToContainer);
 
@@ -3887,16 +3889,22 @@ nsWindow::Create(nsIWidget* aParent,
     }
         break;
     default:
         break;
     }
 
     // label the drawing window with this object so we can find our way home
     g_object_set_data(G_OBJECT(mGdkWindow), "nsWindow", this);
+    if (drawToContainer) {
+        // Also label mShell toplevel window,
+        // property_notify_event_cb callback also needs to find its way home
+        g_object_set_data(G_OBJECT(gtk_widget_get_window(mShell)),
+                          "nsWindow", this);
+    }
 
     if (mContainer)
         g_object_set_data(G_OBJECT(mContainer), "nsWindow", this);
 
     if (mShell)
         g_object_set_data(G_OBJECT(mShell), "nsWindow", this);
 
     // attach listeners for events
@@ -3904,22 +3912,22 @@ nsWindow::Create(nsIWidget* aParent,
         g_signal_connect(mShell, "configure_event",
                          G_CALLBACK(configure_event_cb), nullptr);
         g_signal_connect(mShell, "delete_event",
                          G_CALLBACK(delete_event_cb), nullptr);
         g_signal_connect(mShell, "window_state_event",
                          G_CALLBACK(window_state_event_cb), nullptr);
         g_signal_connect(mShell, "check-resize",
                          G_CALLBACK(check_resize_cb), nullptr);
+        g_signal_connect(mShell, "composited-changed",
+                         G_CALLBACK(widget_composited_changed_cb), nullptr);
+        g_signal_connect(mShell, "property-notify-event",
+                         G_CALLBACK(property_notify_event_cb), nullptr);
 
         GdkScreen *screen = gtk_widget_get_screen(mShell);
-
-        g_signal_connect(mShell, "composited-changed",
-                         G_CALLBACK(widget_composited_changed_cb), nullptr);
-
         if (!g_signal_handler_find(screen, G_SIGNAL_MATCH_FUNC,
                                    0, 0, nullptr,
                                    FuncToGpointer(screen_composited_changed_cb), 0)) {
             g_signal_connect(screen, "composited-changed",
                              G_CALLBACK(screen_composited_changed_cb), nullptr);
         }
 
         GtkSettings* default_settings = gtk_settings_get_default();
@@ -4019,18 +4027,16 @@ nsWindow::Create(nsIWidget* aParent,
         g_signal_connect(eventWidget, "leave-notify-event",
                          G_CALLBACK(leave_notify_event_cb), nullptr);
         g_signal_connect(eventWidget, "motion-notify-event",
                          G_CALLBACK(motion_notify_event_cb), nullptr);
         g_signal_connect(eventWidget, "button-press-event",
                          G_CALLBACK(button_press_event_cb), nullptr);
         g_signal_connect(eventWidget, "button-release-event",
                          G_CALLBACK(button_release_event_cb), nullptr);
-        g_signal_connect(eventWidget, "property-notify-event",
-                         G_CALLBACK(property_notify_event_cb), nullptr);
         g_signal_connect(eventWidget, "scroll-event",
                          G_CALLBACK(scroll_event_cb), nullptr);
 #if GTK_CHECK_VERSION(3,4,0)
         g_signal_connect(eventWidget, "touch-event",
                          G_CALLBACK(touch_event_cb), nullptr);
 #endif
     }
 
@@ -4093,33 +4099,34 @@ nsWindow::SetWindowClass(const nsAString
       role = c + 1;
     }
     else if (!isascii(*c) || (!isalnum(*c) && ('_' != *c) && ('-' != *c)))
       *c = '_';
   }
   res_name[0] = toupper(res_name[0]);
   if (!role) role = res_name;
 
-  gdk_window_set_role(mGdkWindow, role);
+  GdkWindow* gdkWindow = gtk_widget_get_window(mShell);
+  gdk_window_set_role(gdkWindow, role);
 
 #ifdef MOZ_X11
   if (mIsX11Display) {
       XClassHint *class_hint = XAllocClassHint();
       if (!class_hint) {
         free(res_name);
         return;
       }
       class_hint->res_name = res_name;
       class_hint->res_class = const_cast<char*>(res_class);
 
       // Can't use gtk_window_set_wmclass() for this; it prints
       // a warning & refuses to make the change.
       GdkDisplay *display = gdk_display_get_default();
       XSetClassHint(GDK_DISPLAY_XDISPLAY(display),
-                    gdk_x11_window_get_xid(mGdkWindow),
+                    gdk_x11_window_get_xid(gdkWindow),
                     class_hint);
       XFree(class_hint);
   }
 #endif /* MOZ_X11 */
 
   free(res_name);
 }