Bug 1365218 - Add support for drawing decorated windows on GTK 3.20, r?karlt draft
authorMartin Stransky <stransky@redhat.com>
Wed, 17 May 2017 10:55:43 +0200
changeset 579381 0b39d2de699ab61f5330395a36b10a01fa90a315
parent 577814 74d3c3b32584605b4d787bc897aed54a772424c6
child 628985 ffb09d02f8bb3ac7d1c734b793e3124f1afd3c6c
push id59229
push userstransky@redhat.com
push dateWed, 17 May 2017 08:56:09 +0000
reviewerskarlt
bugs1365218
milestone55.0a1
Bug 1365218 - Add support for drawing decorated windows on GTK 3.20, r?karlt MozReview-Commit-ID: 8e92tDm5RsM
gfx/src/nsThemeConstants.h
layout/style/nsCSSKeywordList.h
layout/style/nsCSSProps.cpp
widget/gtk/WidgetStyleCache.cpp
widget/gtk/gtk3drawing.cpp
widget/gtk/gtkdrawing.h
widget/gtk/nsNativeThemeGTK.cpp
widget/gtk/nsWindow.h
--- a/gfx/src/nsThemeConstants.h
+++ b/gfx/src/nsThemeConstants.h
@@ -292,8 +292,9 @@
 #define NS_THEME_MAC_VIBRANCY_DARK                         244
 #define NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN                245
 #define NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED              246
 
 #define NS_THEME_GTK_INFO_BAR                              247
 #define NS_THEME_MAC_SOURCE_LIST                           248
 #define NS_THEME_MAC_SOURCE_LIST_SELECTION                 249
 #define NS_THEME_MAC_ACTIVE_SOURCE_LIST_SELECTION          250
+#define NS_THEME_GTK_WINDOW_DECORATION                     251
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -68,16 +68,17 @@ CSS_KEY(-moz-fixed, _moz_fixed)
 CSS_KEY(-moz-grabbing, _moz_grabbing)
 CSS_KEY(-moz-grab, _moz_grab)
 CSS_KEY(-moz-grid-group, _moz_grid_group)
 CSS_KEY(-moz-grid-line, _moz_grid_line)
 CSS_KEY(-moz-grid, _moz_grid)
 CSS_KEY(-moz-groupbox, _moz_groupbox)
 CSS_KEY(-moz-gtk-info-bar, _moz_gtk_info_bar)
 CSS_KEY(-moz-gtk-info-bar-text, _moz_gtk_info_bar_text)
+CSS_KEY(-moz-gtk-window-decoration, _moz_gtk_window_decoration)
 CSS_KEY(-moz-hidden-unscrollable, _moz_hidden_unscrollable)
 CSS_KEY(-moz-hyperlinktext, _moz_hyperlinktext)
 CSS_KEY(-moz-html-cellhighlight, _moz_html_cellhighlight)
 CSS_KEY(-moz-html-cellhighlighttext, _moz_html_cellhighlighttext)
 CSS_KEY(-moz-image-rect, _moz_image_rect)
 CSS_KEY(-moz-info, _moz_info)
 CSS_KEY(-moz-inline-box, _moz_inline_box)
 CSS_KEY(-moz-inline-grid, _moz_inline_grid)
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -863,16 +863,17 @@ const KTableEntry nsCSSProps::kMozAppear
   { eCSSKeyword__moz_window_button_box,         NS_THEME_WINDOW_BUTTON_BOX },
   { eCSSKeyword__moz_window_button_box_maximized, NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED },
   { eCSSKeyword__moz_win_exclude_glass,         NS_THEME_WIN_EXCLUDE_GLASS },
   { eCSSKeyword__moz_mac_vibrancy_light,        NS_THEME_MAC_VIBRANCY_LIGHT },
   { eCSSKeyword__moz_mac_vibrancy_dark,         NS_THEME_MAC_VIBRANCY_DARK },
   { eCSSKeyword__moz_mac_disclosure_button_open,   NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN },
   { eCSSKeyword__moz_mac_disclosure_button_closed, NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED },
   { eCSSKeyword__moz_gtk_info_bar,              NS_THEME_GTK_INFO_BAR },
+  { eCSSKeyword__moz_gtk_window_decoration,     NS_THEME_GTK_WINDOW_DECORATION },
   { eCSSKeyword__moz_mac_source_list,           NS_THEME_MAC_SOURCE_LIST },
   { eCSSKeyword__moz_mac_source_list_selection, NS_THEME_MAC_SOURCE_LIST_SELECTION },
   { eCSSKeyword__moz_mac_active_source_list_selection, NS_THEME_MAC_ACTIVE_SOURCE_LIST_SELECTION },
   { eCSSKeyword_UNKNOWN,                        -1 }
 };
 
 const KTableEntry nsCSSProps::kBackfaceVisibilityKTable[] = {
   { eCSSKeyword_visible, NS_STYLE_BACKFACE_VISIBILITY_VISIBLE },
--- a/widget/gtk/WidgetStyleCache.cpp
+++ b/widget/gtk/WidgetStyleCache.cpp
@@ -21,20 +21,31 @@ static GtkWidget* sWidgetStorage[MOZ_GTK
 static GtkStyleContext* sStyleStorage[MOZ_GTK_WIDGET_NODE_COUNT];
 
 static GtkStyleContext*
 GetWidgetRootStyle(WidgetNodeType aNodeType);
 static GtkStyleContext*
 GetCssNodeStyleInternal(WidgetNodeType aNodeType);
 
 static GtkWidget*
-CreateWindowWidget()
+CreateWindowWidget(WidgetNodeType type)
 {
   GtkWidget *widget = gtk_window_new(GTK_WINDOW_POPUP);
   gtk_widget_set_name(widget, "MozillaGtkWidget");
+  GtkStyleContext* style = gtk_widget_get_style_context(widget);
+  switch (type) {
+  case MOZ_GTK_WINDOW_CSD:
+    gtk_style_context_add_class(style, "csd");
+    break;
+  case MOZ_GTK_WINDOW_SOLID_CSD:
+    gtk_style_context_add_class(style, "solid-csd");
+    break;
+  default:
+    break;
+  }
   return widget;
 }
 
 static GtkWidget*
 CreateWindowContainerWidget()
 {
   GtkWidget *widget = gtk_fixed_new();
   gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_WINDOW)), widget);
@@ -96,17 +107,17 @@ CreateProgressWidget()
   return widget;
 }
 
 static GtkWidget*
 CreateTooltipWidget()
 {
   MOZ_ASSERT(gtk_check_version(3, 20, 0) != nullptr,
              "CreateTooltipWidget should be used for Gtk < 3.20 only.");
-  GtkWidget* widget = CreateWindowWidget();
+  GtkWidget* widget = CreateWindowWidget(MOZ_GTK_WINDOW);
   GtkStyleContext* style = gtk_widget_get_style_context(widget);
   gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
   return widget;
 }
 
 static GtkWidget*
 CreateExpanderWidget()
 {
@@ -583,17 +594,19 @@ CreateHeaderBarButton(WidgetNodeType aWi
   return widget;
 }
 
 static GtkWidget*
 CreateWidget(WidgetNodeType aWidgetType)
 {
   switch (aWidgetType) {
     case MOZ_GTK_WINDOW:
-      return CreateWindowWidget();
+    case MOZ_GTK_WINDOW_CSD:
+    case MOZ_GTK_WINDOW_SOLID_CSD:
+      return CreateWindowWidget(aWidgetType);
     case MOZ_GTK_WINDOW_CONTAINER:
       return CreateWindowContainerWidget();
     case MOZ_GTK_CHECKBUTTON_CONTAINER:
       return CreateCheckboxWidget();
     case MOZ_GTK_PROGRESSBAR:
       return CreateProgressWidget();
     case MOZ_GTK_RADIOBUTTON_CONTAINER:
       return CreateRadiobuttonWidget();
@@ -1088,16 +1101,24 @@ GetCssNodeStyleInternal(WidgetNodeType a
     case MOZ_GTK_NOTEBOOK_HEADER:
     case MOZ_GTK_TABPANELS:
     case MOZ_GTK_TAB_SCROLLARROW:
     { 
       // TODO - create from CSS node
       GtkWidget* widget = GetWidget(MOZ_GTK_NOTEBOOK);
       return gtk_widget_get_style_context(widget);
     }
+    case MOZ_GTK_WINDOW_DECORATION:
+      style = CreateChildCSSNode("decoration",
+                                 MOZ_GTK_WINDOW_CSD);
+      break;
+    case MOZ_GTK_WINDOW_DECORATION_SOLID:
+      style = CreateChildCSSNode("decoration",
+                                 MOZ_GTK_WINDOW_SOLID_CSD);
+      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
@@ -34,19 +34,35 @@ static ScrollbarGTKMetrics sScrollbarMet
 
 static gint
 moz_gtk_get_tab_thickness(GtkStyleContext *style);
 
 static gint
 moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
                         GtkWidgetState* state, GtkTextDirection direction);
 
+static void
+moz_gtk_add_style_margin(GtkStyleContext* style,
+                         gint* left, gint* top, gint* right, gint* bottom);
+static void
+moz_gtk_add_style_border(GtkStyleContext* style,
+                         gint* left, gint* top, gint* right, gint* bottom);
+static void
+moz_gtk_add_style_padding(GtkStyleContext* style,
+                          gint* left, gint* top, gint* right, gint* bottom);
+static void moz_gtk_add_margin_border_padding(GtkStyleContext *style,
+                                              gint* left, gint* top,
+                                              gint* right, gint* bottom);
+static void moz_gtk_add_border_padding(GtkStyleContext *style,
+                                       gint* left, gint* top,
+                                       gint* right, gint* bottom);
 static GtkBorder
 GetMarginBorderPadding(GtkStyleContext* aStyle);
 
+
 // GetStateFlagsFromGtkWidgetState() can be safely used for the specific
 // GtkWidgets that set both prelight and active flags.  For other widgets,
 // either the GtkStateFlags or Gecko's GtkWidgetState need to be carefully
 // adjusted to match GTK behavior.  Although GTK sets insensitive and focus
 // flags in the generic GtkWidget base class, GTK adds prelight and active
 // flags only to widgets that are expected to demonstrate prelight or active
 // states.  This contrasts with HTML where any element may have :active and
 // :hover states, and so Gecko's GtkStateFlags do not necessarily map to GTK
@@ -235,16 +251,56 @@ moz_gtk_splitter_get_metrics(gint orient
     } else {
         style = ClaimStyleContext(MOZ_GTK_SPLITTER_VERTICAL);
     }
     gtk_style_context_get_style(style, "handle_size", size, NULL);
     ReleaseStyleContext(style);
     return MOZ_GTK_SUCCESS;
 }
 
+void
+moz_gtk_get_window_border(gint* top, gint* right, gint* bottom, gint* left)
+{
+  MOZ_ASSERT(gtk_check_version(3, 20, 0) == nullptr,
+             "Window decorations are only supported on GTK 3.20+.");
+
+  GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW);
+
+  *top = *right = *bottom = *left = 0;
+  moz_gtk_add_border_padding(style, left, top, right, bottom);
+  GtkBorder windowMargin;
+  gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &windowMargin);
+
+  ReleaseStyleContext(style);
+
+  style = ClaimStyleContext(MOZ_GTK_WINDOW_DECORATION);
+
+  // Available on GTK 3.20+.
+  static auto sGtkRenderBackgroundGetClip =
+    (void (*)(GtkStyleContext*, gdouble, gdouble, gdouble, gdouble, GdkRectangle*))
+    dlsym(RTLD_DEFAULT, "gtk_render_background_get_clip");
+
+  GdkRectangle shadowClip;
+  sGtkRenderBackgroundGetClip(style, 0, 0, 0, 0, &shadowClip);
+  ReleaseStyleContext(style);
+
+  // Transfer returned inset rectangle to GtkBorder
+  GtkBorder shadowBorder = {
+      static_cast<gint16>(-shadowClip.x),                    // left
+      static_cast<gint16>(shadowClip.width + shadowClip.x),  // right
+      static_cast<gint16>(-shadowClip.y),                    // top
+      static_cast<gint16>(shadowClip.height + shadowClip.y), // bottom
+  };
+
+  *left += MAX(windowMargin.left, shadowBorder.left);
+  *right += MAX(windowMargin.right, shadowBorder.right);
+  *top += MAX(windowMargin.top, shadowBorder.top);
+  *bottom += MAX(windowMargin.bottom, shadowBorder.bottom);
+}
+
 static gint
 moz_gtk_window_paint(cairo_t *cr, GdkRectangle* rect,
                      GtkTextDirection direction)
 {
     GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction);
 
     gtk_style_context_save(style);
     gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
@@ -252,16 +308,55 @@ moz_gtk_window_paint(cairo_t *cr, GdkRec
     gtk_style_context_restore(style);
 
     ReleaseStyleContext(style);
 
     return MOZ_GTK_SUCCESS;
 }
 
 static gint
+moz_gtk_window_decoration_paint(cairo_t *cr, GdkRectangle* rect,
+                                GtkTextDirection direction)
+{
+    gint top, right, bottom, left;
+    moz_gtk_get_window_border(&top, &right, &bottom, &left);
+
+    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW_DECORATION,
+                                               direction);
+
+    rect->x += left;
+    rect->y += top;
+    rect->width -= left + right;
+    rect->height -= top + bottom;
+
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+
+    ReleaseStyleContext(style);
+
+    return MOZ_GTK_SUCCESS;
+}
+
+static gint
+moz_gtk_window_decoration_solid_paint(cairo_t *cr, GdkRectangle* rect,
+                                      GtkTextDirection direction)
+{
+    GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW_DECORATION_SOLID,
+                                               direction);
+
+    gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+    gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+
+    ReleaseStyleContext(style);
+
+    return MOZ_GTK_SUCCESS;
+
+}
+
+static gint
 moz_gtk_button_paint(cairo_t *cr, GdkRectangle* rect,
                      GtkWidgetState* state,
                      GtkReliefStyle relief, GtkWidget* widget,
                      GtkTextDirection direction)
 {
     GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
     GtkStyleContext* style = gtk_widget_get_style_context(widget);    
     gint x = rect->x, y=rect->y, width=rect->width, height=rect->height;
@@ -2310,16 +2405,28 @@ moz_gtk_get_widget_border(WidgetNodeType
 
             GtkStyleContext* labelStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
             moz_gtk_add_margin_border_padding(labelStyle,
                                               left, top, right, bottom);
             ReleaseStyleContext(labelStyle);
 
             return MOZ_GTK_SUCCESS;
         }
+    case MOZ_GTK_WINDOW_DECORATION:
+        {
+            moz_gtk_get_window_border(top, right, bottom, left);
+            return MOZ_GTK_SUCCESS;
+        }
+    case MOZ_GTK_WINDOW_DECORATION_SOLID:
+        {
+            style = ClaimStyleContext(MOZ_GTK_WINDOW_DECORATION_SOLID);
+            moz_gtk_add_border_padding(style, left, top, right, bottom);
+            ReleaseStyleContext(style);
+            return MOZ_GTK_SUCCESS;
+        }
     case MOZ_GTK_HEADER_BAR:
     case MOZ_GTK_HEADER_BAR_MAXIMIZED:
         {
             style = ClaimStyleContext(widget);
             moz_gtk_add_border_padding(style, left, top, right, bottom);
             ReleaseStyleContext(style);
             return MOZ_GTK_SUCCESS;
         }
@@ -3016,16 +3123,22 @@ moz_gtk_widget_paint(WidgetNodeType widg
         return moz_gtk_vpaned_paint(cr, rect, state);
         break;
     case MOZ_GTK_SPLITTER_VERTICAL:
         return moz_gtk_hpaned_paint(cr, rect, state);
         break;
     case MOZ_GTK_WINDOW:
         return moz_gtk_window_paint(cr, rect, direction);
         break;
+    case MOZ_GTK_WINDOW_DECORATION:
+        return moz_gtk_window_decoration_paint(cr, rect, direction);
+        break;
+    case MOZ_GTK_WINDOW_DECORATION_SOLID:
+        return moz_gtk_window_decoration_solid_paint(cr, rect, direction);
+        break;
     case MOZ_GTK_INFO_BAR:
         return moz_gtk_info_bar_paint(cr, rect, state);
         break;
     case MOZ_GTK_HEADER_BAR:
     case MOZ_GTK_HEADER_BAR_MAXIMIZED:
         return moz_gtk_header_bar_paint(widget, cr, rect, state);
         break;
     default:
--- a/widget/gtk/gtkdrawing.h
+++ b/widget/gtk/gtkdrawing.h
@@ -265,16 +265,24 @@ typedef enum {
   /* Paints a GtkVPaned separator */
   MOZ_GTK_SPLITTER_SEPARATOR_HORIZONTAL,
   /* Paints a GtkHPaned separator */
   MOZ_GTK_SPLITTER_SEPARATOR_VERTICAL,
   /* Paints the background of a window, dialog or page. */
   MOZ_GTK_WINDOW,
   /* Window container for all widgets */
   MOZ_GTK_WINDOW_CONTAINER,
+  /* Window with the 'csd' style class. */
+  MOZ_GTK_WINDOW_CSD,
+  /* Window with the 'csd' style class. */
+  MOZ_GTK_WINDOW_SOLID_CSD,
+  /* Client-side window decoration node. Available on GTK 3.20+. */
+  MOZ_GTK_WINDOW_DECORATION,
+  /* Solid client-side window decoration node. Available on GTK 3.20+. */
+  MOZ_GTK_WINDOW_DECORATION_SOLID,
   /* Paints a GtkInfoBar, for notifications. */
   MOZ_GTK_INFO_BAR,
   /* Used for widget tree construction. */
   MOZ_GTK_COMBOBOX,
   /* Paints a GtkComboBox button widget. */
   MOZ_GTK_COMBOBOX_BUTTON,
   /* Paints a GtkComboBox arrow widget. */
   MOZ_GTK_COMBOBOX_ARROW,
@@ -546,16 +554,25 @@ gint moz_gtk_get_menu_separator_height(g
  * Get the desired size of a splitter
  * orientation:   [IN]  GTK_ORIENTATION_HORIZONTAL or GTK_ORIENTATION_VERTICAL
  * size:          [OUT] width or height of the splitter handle
  *
  * returns:    MOZ_GTK_SUCCESS if there was no error, an error code otherwise
  */
 gint moz_gtk_splitter_get_metrics(gint orientation, gint* size);
 
+#if (MOZ_WIDGET_GTK == 3)
+/**
+ * Gets the margins to be used for window decorations, typically the extra space
+ * required to draw a drop shadow (obtained from gtk_render_background_get_clip).
+ * Only available on GTK 3.20+.
+ */
+void moz_gtk_get_window_border(gint* top, gint* right, gint* bottom, gint* left);
+#endif
+
 /**
  * Get the YTHICKNESS of a tab (notebook extension).
  */
 gint
 moz_gtk_get_tab_thickness(WidgetNodeType aNodeType);
 
 #if (MOZ_WIDGET_GTK == 2)
 #ifdef __cplusplus
--- a/widget/gtk/nsNativeThemeGTK.cpp
+++ b/widget/gtk/nsNativeThemeGTK.cpp
@@ -19,16 +19,17 @@
 #include "nsGfxCIID.h"
 #include "nsTransform2D.h"
 #include "nsMenuFrame.h"
 #include "prlink.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsRenderingContext.h"
 #include "nsGkAtoms.h"
 #include "nsAttrValueInlines.h"
+#include "nsWindow.h"
 
 #include "mozilla/EventStates.h"
 #include "mozilla/Services.h"
 
 #include <gdk/gdkprivate.h>
 #include <gtk/gtk.h>
 
 #include "gfxContext.h"
@@ -693,16 +694,26 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
     break;
   case NS_THEME_RADIOMENUITEM:
     aGtkWidgetType = MOZ_GTK_RADIOMENUITEM;
     break;
   case NS_THEME_WINDOW:
   case NS_THEME_DIALOG:
     aGtkWidgetType = MOZ_GTK_WINDOW;
     break;
+  case NS_THEME_GTK_WINDOW_DECORATION:
+    {
+      nsWindow* window = static_cast<nsWindow*>(aFrame->GetNearestWidget());
+      if (window && window->IsComposited()) {
+        aGtkWidgetType = MOZ_GTK_WINDOW_DECORATION;
+      } else {
+        aGtkWidgetType = MOZ_GTK_WINDOW_DECORATION_SOLID;
+      }
+      break;
+    }
   case NS_THEME_GTK_INFO_BAR:
     aGtkWidgetType = MOZ_GTK_INFO_BAR;
     break;
   case NS_THEME_WINDOW_TITLEBAR:
     aGtkWidgetType = MOZ_GTK_HEADER_BAR;
     break;
   case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
     aGtkWidgetType = MOZ_GTK_HEADER_BAR_MAXIMIZED;
@@ -1898,16 +1909,17 @@ nsNativeThemeGTK::ThemeSupportsWidget(ns
   case NS_THEME_MENUSEPARATOR:
   case NS_THEME_CHECKMENUITEM:
   case NS_THEME_RADIOMENUITEM:
   case NS_THEME_SPLITTER:
   case NS_THEME_WINDOW:
   case NS_THEME_DIALOG:
 #if (MOZ_WIDGET_GTK == 3)
   case NS_THEME_GTK_INFO_BAR:
+  case NS_THEME_GTK_WINDOW_DECORATION:
 #endif
     return !IsWidgetStyled(aPresContext, aFrame, aWidgetType);
 
   case NS_THEME_WINDOW_BUTTON_CLOSE:
   case NS_THEME_WINDOW_BUTTON_MINIMIZE:
   case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
   case NS_THEME_WINDOW_BUTTON_RESTORE:
   case NS_THEME_WINDOW_TITLEBAR:
@@ -1995,12 +2007,19 @@ nsNativeThemeGTK::GetWidgetTransparency(
   // Tooltips use gtk_paint_flat_box() on Gtk2
   // but are shaped on Gtk3
   case NS_THEME_TOOLTIP:
 #if (MOZ_WIDGET_GTK == 2)
     return eOpaque;
 #else
     return eTransparent;
 #endif
+  case NS_THEME_GTK_WINDOW_DECORATION:
+  {
+    nsWindow* window = static_cast<nsWindow*>(aFrame->GetNearestWidget());
+    if (window)
+      return window->IsComposited() ? eTransparent : eOpaque;
+    return eOpaque;
+  }
   }
 
   return eUnknownTransparency;
 }
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -120,16 +120,17 @@ public:
                                          double aHeight,
                                          bool   aRepaint) override;
     virtual void       Resize           (double aX,
                                          double aY,
                                          double aWidth,
                                          double aHeight,
                                          bool   aRepaint) override;
     virtual bool       IsEnabled() const override;
+    bool               IsComposited() const;
 
     void               SetZIndex(int32_t aZIndex) override;
     virtual void       SetSizeMode(nsSizeMode aMode) override;
     virtual void       Enable(bool aState) override;
     virtual nsresult   SetFocus(bool aRaise = false) override;
     virtual LayoutDeviceIntRect GetScreenBounds() override;
     virtual LayoutDeviceIntRect GetClientBounds() override;
     virtual LayoutDeviceIntSize GetClientSize() override;
@@ -432,17 +433,16 @@ private:
       CheckForRollup(0, 0, false, true);
     }
 
     bool               GetDragInfo(mozilla::WidgetMouseEvent* aMouseEvent,
                                    GdkWindow** aWindow, gint* aButton,
                                    gint* aRootX, gint* aRootY);
     void               ClearCachedResources();
     nsIWidgetListener* GetListener();
-    bool               IsComposited() const;
 
 
     GtkWidget          *mShell;
     MozContainer       *mContainer;
     GdkWindow          *mGdkWindow;
 
     uint32_t            mHasMappedToplevel : 1,
                         mIsFullyObscured : 1,