Bug 1411018 - Rename shellHasCSD to drawToContainer and mark our rendering widget by gtk_widget_set_app_paintable(), r?jhorak draft
authorMartin Stransky <stransky@redhat.com>
Mon, 23 Oct 2017 21:44:02 +0200
changeset 688714 b6423f0bdba25ae8f561d80751f0bca2133b67d2
parent 688650 515407ebfa1433c31144374313bbfd8b942af41c
child 738144 b8ae7eaa02e828ef0143727fc149180e9f5f9965
push id86829
push userstransky@redhat.com
push dateMon, 30 Oct 2017 15:07:18 +0000
reviewersjhorak
bugs1411018
milestone58.0a1
Bug 1411018 - Rename shellHasCSD to drawToContainer and mark our rendering widget by gtk_widget_set_app_paintable(), r?jhorak Rename shellHasCSD to drawToContainer for better understanding and always mark our rendering widget by gtk_widget_set_app_paintable() to make sure Gtk+ does not draw default background for it. MozReview-Commit-ID: 4mhxrG7C34i
widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -3596,17 +3596,17 @@ nsWindow::Create(nsIWidget* aParent,
 
     // figure out our parent window
     GtkWidget      *parentMozContainer = nullptr;
     GtkContainer   *parentGtkContainer = nullptr;
     GdkWindow      *parentGdkWindow = nullptr;
     GtkWindow      *topLevelParent = nullptr;
     nsWindow       *parentnsWindow = nullptr;
     GtkWidget      *eventWidget = nullptr;
-    bool            shellHasCSD = false;
+    bool            drawToContainer = false;
 
     if (aParent) {
         parentnsWindow = static_cast<nsWindow*>(aParent);
         parentGdkWindow = parentnsWindow->mGdkWindow;
     } else if (aNativeParent && GDK_IS_WINDOW(aNativeParent)) {
         parentGdkWindow = GDK_WINDOW(aNativeParent);
         parentnsWindow = get_window_for_gdk_window(parentGdkWindow);
         if (!parentnsWindow)
@@ -3772,31 +3772,39 @@ nsWindow::Create(nsIWidget* aParent,
         GtkWidget *container = moz_container_new();
         mContainer = MOZ_CONTAINER(container);
 
 #if (MOZ_WIDGET_GTK == 3)
         // "csd" style is set when widget is realized so we need to call
         // it explicitly now.
         gtk_widget_realize(mShell);
 
-        // We can't draw directly to top-level window when client side
-        // decorations are enabled. We use container with GdkWindow instead.
+        /* There are two cases here:
+         *
+         * 1) We're running on Gtk+ without client side decorations.
+         *    Content is rendered to mShell window and we listen
+         *    to the Gtk+ events on mShell
+         * 2) We're running on Gtk+ > 3.20 and client side decorations
+         *    are drawn by Gtk+ to mShell. Content is rendered to mContainer
+         *    and we listen to the Gtk+ events on mContainer.
+         */
         GtkStyleContext* style = gtk_widget_get_style_context(mShell);
-        shellHasCSD = gtk_style_context_has_class(style, "csd");
+        drawToContainer = gtk_style_context_has_class(style, "csd");
 #endif
-        if (!shellHasCSD) {
-            // Use mShell's window for drawing and events.
-            gtk_widget_set_has_window(container, FALSE);
-            // Prevent GtkWindow from painting a background to flicker.
-            gtk_widget_set_app_paintable(mShell, TRUE);
-        }
-        // Set up event widget
-        eventWidget = shellHasCSD ? container : mShell;
+        eventWidget = (drawToContainer) ? container : mShell;
+
         gtk_widget_add_events(eventWidget, kEvents);
 
+        // 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);
+
         gtk_container_add(GTK_CONTAINER(mShell), container);
         gtk_widget_realize(container);
 
         // make sure this is the focus widget in the container
         gtk_widget_show(container);
         gtk_widget_grab_focus(container);
 
         // the drawing window
@@ -3955,17 +3963,17 @@ nsWindow::Create(nsIWidget* aParent,
         g_signal_connect(mContainer, "drag_leave",
                          G_CALLBACK(drag_leave_event_cb), nullptr);
         g_signal_connect(mContainer, "drag_drop",
                          G_CALLBACK(drag_drop_event_cb), nullptr);
         g_signal_connect(mContainer, "drag_data_received",
                          G_CALLBACK(drag_data_received_event_cb), nullptr);
 
         GtkWidget *widgets[] = { GTK_WIDGET(mContainer),
-                                 !shellHasCSD ? mShell : nullptr };
+                                 !drawToContainer ? mShell : nullptr };
         for (size_t i = 0; i < ArrayLength(widgets) && widgets[i]; ++i) {
             // Visibility events are sent to the owning widget of the relevant
             // window but do not propagate to parent widgets so connect on
             // mShell (if it exists) as well as mContainer.
             g_signal_connect(widgets[i], "visibility-notify-event",
                              G_CALLBACK(visibility_notify_event_cb), nullptr);
             // Similarly double buffering is controlled by the window's owning
             // widget.  Disable double buffering for painting directly to the