bug 1280951 copy tooltip style context and cache that instead of widget r?stransky
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 09 Jun 2016 16:18:54 +1200
changeset 785195 e8705ee011170c87ff5c01042d441514150a91f0
parent 784664 3c5025f98e561a20e24d97c91a9e4e0ec28015ea
child 785197 dfdc725935a9f47b297b1be5c675de86f12bc908
child 785198 0b0cadc3842805b010c9c901036d0367eede3b46
push id130508
push userktomlinson@mozilla.com
push dateTue, 21 Jun 2016 07:05:30 +0000
treeherdertry@874e8b04f42e [default view] [failures only]
reviewersstransky
bugs1280951
milestone50.0a1
bug 1280951 copy tooltip style context and cache that instead of widget r?stransky MozReview-Commit-ID: K3kUv7cROPr
widget/gtk/WidgetStyleCache.cpp
--- a/widget/gtk/WidgetStyleCache.cpp
+++ b/widget/gtk/WidgetStyleCache.cpp
@@ -101,27 +101,16 @@ static GtkWidget*
 CreateProgressWidget()
 {
   GtkWidget* widget = gtk_progress_bar_new();
   AddToWindowContainer(widget);
   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();
-  GtkStyleContext* style = gtk_widget_get_style_context(widget);
-  gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
-  return widget;
-}
-
-static GtkWidget*
 CreateWidget(WidgetNodeType aWidgetType)
 {
   switch (aWidgetType) {
     case MOZ_GTK_WINDOW:
       return CreateWindowWidget();
     case MOZ_GTK_WINDOW_CONTAINER:
       return CreateWindowContainerWidget();
     case MOZ_GTK_CHECKBUTTON_CONTAINER:
@@ -139,18 +128,16 @@ CreateWidget(WidgetNodeType aWidgetType)
     case MOZ_GTK_MENUBAR:
       return CreateMenuBarWidget();
     case MOZ_GTK_MENUPOPUP:
       return CreateMenuPopupWidget();
     case MOZ_GTK_MENUBARITEM:
       return CreateMenuItemWidget(MOZ_GTK_MENUBAR);
     case MOZ_GTK_MENUITEM:
       return CreateMenuItemWidget(MOZ_GTK_MENUPOPUP);
-    case MOZ_GTK_TOOLTIP:
-      return CreateTooltipWidget();
     default:
       /* Not implemented */
       return nullptr;
   }
 }
 
 GtkWidget*
 GetWidget(WidgetNodeType aWidgetType)
@@ -161,18 +148,19 @@ GetWidget(WidgetNodeType aWidgetType)
     sWidgetStorage[aWidgetType] = widget;
   }
   return widget;
 }
 
 GtkStyleContext*
 CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle)
 {
-  GtkWidgetPath* path =
-    gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle));
+  GtkWidgetPath* path = aParentStyle ?
+    gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)) :
+    gtk_widget_path_new();
 
   // Work around https://bugzilla.gnome.org/show_bug.cgi?id=767312
   // which exists in GTK+ 3.20.
   gtk_widget_get_style_context(aWidget);
 
   gtk_widget_path_append_for_widget(path, aWidget);
   // Release any floating reference on aWidget.
   g_object_ref_sink(aWidget);
@@ -214,19 +202,18 @@ CreateChildCSSNode(const char* aName, Wi
 {
   return CreateCSSNode(aName, GetCssNodeStyleInternal(aParentNodeType));
 }
 
 /* GetCssNodeStyleInternal is used by Gtk >= 3.20 */
 static GtkStyleContext*
 GetCssNodeStyleInternal(WidgetNodeType aNodeType)
 {
-  GtkStyleContext* style = sStyleStorage[aNodeType];
-  if (style)
-    return style;
+  MOZ_ASSERT(!sStyleStorage[aNodeType]);
+  GtkStyleContext* style;
 
   switch (aNodeType) {
     case MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL:
       style = CreateChildCSSNode("contents",
                                  MOZ_GTK_SCROLLBAR_HORIZONTAL);
       break;
     case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL:
       style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
@@ -271,23 +258,19 @@ GetCssNodeStyleInternal(WidgetNodeType a
       gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
       break; 
     default:
       // TODO - create style from style path
       GtkWidget* widget = GetWidget(aNodeType);
       return gtk_widget_get_style_context(widget);
   }
 
-  if (style) {
-    sStyleStorage[aNodeType] = style;
-    return style;
-  }
-
-  MOZ_ASSERT_UNREACHABLE("missing style context for node type");
-  return nullptr;
+  MOZ_ASSERT(style, "missing style context for node type");
+  sStyleStorage[aNodeType] = style;
+  return style;
 }
 
 static GtkStyleContext*
 GetWidgetStyleWithClass(WidgetNodeType aWidgetType, const gchar* aStyleClass)
 {
   GtkStyleContext* style = gtk_widget_get_style_context(GetWidget(aWidgetType));
   gtk_style_context_save(style);
   MOZ_ASSERT(!sStyleContextNeedsRestore);
@@ -317,16 +300,28 @@ GetWidgetStyleInternal(WidgetNodeType aN
       return GetWidgetStyleWithClass(MOZ_GTK_RADIOBUTTON_CONTAINER,
                                      GTK_STYLE_CLASS_RADIO);
     case MOZ_GTK_CHECKBUTTON:
       return GetWidgetStyleWithClass(MOZ_GTK_CHECKBUTTON_CONTAINER,
                                      GTK_STYLE_CLASS_CHECK);
     case MOZ_GTK_PROGRESS_TROUGH:
       return GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR,
                                      GTK_STYLE_CLASS_TROUGH);
+    case MOZ_GTK_TOOLTIP: {
+      GtkWidget* window = CreateWindowWidget();
+      // The style class is first added so that
+      // gtk_widget_path_append_for_widget() in CreateStyleForWidget() will
+      // find it.
+      GtkStyleContext* windowStyle = gtk_widget_get_style_context(window);
+      gtk_style_context_add_class(windowStyle, GTK_STYLE_CLASS_TOOLTIP);
+      GtkStyleContext* pathStyle = CreateStyleForWidget(window, nullptr);
+      gtk_widget_destroy(window); // Release GtkWindow self-reference.
+      sStyleStorage[aNodeType] = pathStyle;
+      return pathStyle;
+    }
     default:
       GtkWidget* widget = GetWidget(aNodeType);
       MOZ_ASSERT(widget);
       return gtk_widget_get_style_context(widget);
   }
 }
 
 void
@@ -351,21 +346,23 @@ ResetWidgetCache(void)
   mozilla::PodArrayZero(sWidgetStorage);
 }
 
 GtkStyleContext*
 ClaimStyleContext(WidgetNodeType aNodeType, GtkTextDirection aDirection,
                   GtkStateFlags aStateFlags, StyleFlags aFlags)
 {
   MOZ_ASSERT(!sStyleContextNeedsRestore);
-  GtkStyleContext* style;
-  if (gtk_check_version(3, 20, 0) != nullptr) {
-    style = GetWidgetStyleInternal(aNodeType);
-  } else {
-    style = GetCssNodeStyleInternal(aNodeType);
+  GtkStyleContext* style = sStyleStorage[aNodeType];
+  if (!style) {
+    if (gtk_check_version(3, 20, 0) != nullptr) {
+      style = GetWidgetStyleInternal(aNodeType);
+    } else {
+      style = GetCssNodeStyleInternal(aNodeType);
+    }
   }
 #ifdef DEBUG
   MOZ_ASSERT(!sCurrentStyleContext);
   sCurrentStyleContext = style;
 #endif
   GtkStateFlags oldState = gtk_style_context_get_state(style);
   GtkTextDirection oldDirection = gtk_style_context_get_direction(style);
   if (oldState != aStateFlags || oldDirection != aDirection) {