Bug 1456898 - Implement and use solid-csd decoration style to get window offset when solid-csd is used by mShell toplevel window, r?jhorak draft
authorMartin Stransky <stransky@redhat.com>
Thu, 26 Apr 2018 13:55:41 +0200
changeset 788352 b47ab45f66ecc0cbb7815bca91943ac7c68167db
parent 788336 8d85e4da25463ccdcf902ac5a846773b8b642553
child 788356 da3733590760733c38a43cfa4d9b1416bc313e14
child 788358 2b81c20c204f3fd5653ebb7053acd3f412f9af9a
push id107972
push userstransky@redhat.com
push dateThu, 26 Apr 2018 12:29:15 +0000
reviewersjhorak
bugs1456898
milestone61.0a1
Bug 1456898 - Implement and use solid-csd decoration style to get window offset when solid-csd is used by mShell toplevel window, r?jhorak Implement and use solid-csd decoration style to get window offset when solid-csd is used by mShell toplevel window. Also does not apply margin (resize handler sizes) on popup window as well as Gtk+ do in get_shadow_width(). MozReview-Commit-ID: 9xozp9CCVJj
widget/gtk/WidgetStyleCache.cpp
widget/gtk/gtk3drawing.cpp
widget/gtk/gtkdrawing.h
widget/gtk/nsWindow.cpp
--- a/widget/gtk/WidgetStyleCache.cpp
+++ b/widget/gtk/WidgetStyleCache.cpp
@@ -1288,16 +1288,24 @@ GetCssNodeStyleInternal(WidgetNodeType a
     case MOZ_GTK_WINDOW_DECORATION:
     {
       GtkStyleContext* parentStyle =
           CreateSubStyleWithClass(MOZ_GTK_WINDOW, "csd");
       style = CreateCSSNode("decoration", parentStyle);
       g_object_unref(parentStyle);
       break;
     }
+    case MOZ_GTK_WINDOW_DECORATION_SOLID:
+    {
+      GtkStyleContext* parentStyle =
+          CreateSubStyleWithClass(MOZ_GTK_WINDOW, "solid-csd");
+      style = CreateCSSNode("decoration", parentStyle);
+      g_object_unref(parentStyle);
+      break;
+    }
     default:
       return GetWidgetRootStyle(aNodeType);
   }
 
   MOZ_ASSERT(style, "missing style context for node type");
   sStyleStorage[aNodeType] = style;
   return style;
 }
--- a/widget/gtk/gtk3drawing.cpp
+++ b/widget/gtk/gtk3drawing.cpp
@@ -3115,19 +3115,23 @@ GetActiveScrollbarMetrics(GtkOrientation
   return metrics;
 }
 
 /*
  * get_shadow_width() from gtkwindow.c is not public so we need
  * to implement it.
  */
 bool
-GetCSDDecorationSize(GtkBorder* aDecorationSize)
+GetCSDDecorationSize(GtkWindow *aGtkWindow, GtkBorder* aDecorationSize)
 {
-    GtkStyleContext* context = GetStyleContext(MOZ_GTK_WINDOW_DECORATION);
+    GtkStyleContext* context = gtk_widget_get_style_context(GTK_WIDGET(aGtkWindow));
+    bool solidDecorations = gtk_style_context_has_class(context, "solid-csd");
+    context = GetStyleContext(solidDecorations ?
+                              MOZ_GTK_WINDOW_DECORATION_SOLID :
+                              MOZ_GTK_WINDOW_DECORATION);
 
     /* Always sum border + padding */
     GtkBorder padding;
     GtkStateFlags state = gtk_style_context_get_state(context);
     gtk_style_context_get_border(context, state, aDecorationSize);
     gtk_style_context_get_padding(context, state, &padding);
     *aDecorationSize += padding;
 
@@ -3146,20 +3150,24 @@ GetCSDDecorationSize(GtkBorder* aDecorat
         GdkRectangle clip;
         sGtkRenderBackgroundGetClip(context, 0, 0, 0, 0, &clip);
 
         extents.top = -clip.y;
         extents.right = clip.width + clip.x;
         extents.bottom = clip.height + clip.y;
         extents.left = -clip.x;
 
-        extents.top = MAX(extents.top, margin.top);
-        extents.right = MAX(extents.right, margin.right);
-        extents.bottom = MAX(extents.bottom, margin.bottom);
-        extents.left = MAX(extents.left, margin.left);
+        // Margin is used for resize grip size - it's not present on
+        // popup windows.
+        if (gtk_window_get_window_type(aGtkWindow) != GTK_WINDOW_POPUP) {
+            extents.top = MAX(extents.top, margin.top);
+            extents.right = MAX(extents.right, margin.right);
+            extents.bottom = MAX(extents.bottom, margin.bottom);
+            extents.left = MAX(extents.left, margin.left);
+        }
     } else {
         /* If we can't get shadow extents use decoration-resize-handle instead
          * as a workaround. This is inspired by update_border_windows()
          * from gtkwindow.c although this is not 100% accurate as we emulate
          * the extents here.
          */
         gint handle;
         gtk_widget_style_get(GetWidget(MOZ_GTK_WINDOW),
--- a/widget/gtk/gtkdrawing.h
+++ b/widget/gtk/gtkdrawing.h
@@ -334,16 +334,17 @@ typedef enum {
   /* MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE_RESTORE is a state of
    * MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE button and it's used as
    * an icon placeholder only.
    */
   MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE_RESTORE,
 
   /* Client-side window decoration node. Available on GTK 3.20+. */
   MOZ_GTK_WINDOW_DECORATION,
+  MOZ_GTK_WINDOW_DECORATION_SOLID,
 
   MOZ_GTK_WIDGET_NODE_COUNT
 } WidgetNodeType;
 
 /*** General library functions ***/
 /**
  * Initializes the drawing library.  You must call this function
  * prior to using any other functionality.
@@ -614,20 +615,21 @@ GetToolbarButtonMetrics(WidgetNodeType a
                         TOOLBAR_BUTTONS wide.
  *
  * returns:    Number of returned entries at aButtonLayout.
  */
 int
 GetGtkHeaderBarButtonLayout(WidgetNodeType* aButtonLayout, int aMaxButtonNums);
 
 /**
- * Get size of CSD window extents.
+ * Get size of CSD window extents of given GtkWindow.
  *
+ * aGtkWindow      [IN]  Decorated window.
  * aDecorationSize [OUT] Returns calculated (or estimated) decoration
- *                       size of CSD window.
+ *                       size of given aGtkWindow.
  *
  * returns:    True if we have extract decoration size (for GTK 3.20+)
  *             False if we have only an estimation (for GTK+ before  3.20+)
  */
 bool
-GetCSDDecorationSize(GtkBorder* aDecorationSize);
+GetCSDDecorationSize(GtkWindow *aGtkWindow, GtkBorder* aDecorationSize);
 
 #endif
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -6603,17 +6603,17 @@ nsWindow::ClearCachedResources()
  */
 void
 nsWindow::UpdateClientOffsetForCSDWindow()
 {
     // _NET_FRAME_EXTENTS is not set on client decorated windows,
     // so we need to read offset between mContainer and toplevel mShell
     // window.
     GtkBorder decorationSize;
-    GetCSDDecorationSize(&decorationSize);
+    GetCSDDecorationSize(GTK_WINDOW(mShell), &decorationSize);
     mClientOffset = nsIntPoint(decorationSize.left, decorationSize.top);
 
     // Send a WindowMoved notification. This ensures that TabParent
     // picks up the new client offset and sends it to the child process
     // if appropriate.
     NotifyWindowMoved(mBounds.x, mBounds.y);
 }