[metacity/wip/gtk-theme: 14/51] theme: Add MetaStyleInfo for wrapping frame style context



commit 1837fd7759dd84b99e32573de9ea13753f78b5d4
Author: Florian Müllner <fmuellner gnome org>
Date:   Wed Sep 24 00:07:21 2014 +0200

    theme: Add MetaStyleInfo for wrapping frame style context
    
    Our current use of style contexts is fairly limited - we don't
    use them for much more than picking up some color information.
    We will soon start to make more elaborate use of GTK style
    information, but a single context will no longer be enough
    to draw a frame then.
    To prepare for this, add a simple ref-counted type to wrap
    style information.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=741917
    
    NOTE: Updated for metacity in way it does not break existing themes.

 src/ui/frames.c         |   49 ++++++++++++++++++++++---------------------
 src/ui/frames.h         |    4 +-
 src/ui/preview-widget.c |   12 +++++++---
 src/ui/preview-widget.h |    2 +-
 src/ui/theme-viewer.c   |   28 +++++++++++++-----------
 src/ui/theme.c          |   52 +++++++++++++++++++++++++++++++++++++---------
 src/ui/theme.h          |   26 ++++++++++++++++++++--
 7 files changed, 116 insertions(+), 57 deletions(-)
---
diff --git a/src/ui/frames.c b/src/ui/frames.c
index 43d476a..9ea60a9 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -181,41 +181,41 @@ prefs_changed_callback (MetaPreference pref,
     }
 }
 
-static GtkStyleContext *
+static MetaStyleInfo *
 meta_frames_get_theme_variant (MetaFrames  *frames,
                                const gchar *variant)
 {
-  GtkStyleContext *style;
+  MetaStyleInfo *style_info;
 
-  style = g_hash_table_lookup (frames->style_variants, variant);
-  if (style == NULL)
+  style_info = g_hash_table_lookup (frames->style_variants, variant);
+  if (style_info == NULL)
     {
-      style = meta_theme_create_style_context (gtk_widget_get_screen (GTK_WIDGET (frames)), variant);
-      g_hash_table_insert (frames->style_variants, g_strdup (variant), style);
+      style_info = meta_theme_create_style_info (gtk_widget_get_screen (GTK_WIDGET (frames)), variant);
+      g_hash_table_insert (frames->style_variants, g_strdup (variant), style_info);
     }
 
-  return style;
+  return style_info;
 }
 
 static void
 update_style_contexts (MetaFrames *frames)
 {
-  GtkStyleContext *style;
+  MetaStyleInfo *style_info;
   GList *variants, *variant;
   GdkScreen *screen;
 
   screen = gtk_widget_get_screen (GTK_WIDGET (frames));
 
   if (frames->normal_style)
-    g_object_unref (frames->normal_style);
-  frames->normal_style = meta_theme_create_style_context (screen, NULL);
+    meta_style_info_unref (frames->normal_style);
+  frames->normal_style = meta_theme_create_style_info (screen, NULL);
 
   variants = g_hash_table_get_keys (frames->style_variants);
   for (variant = variants; variant; variant = variants->next)
     {
-      style = meta_theme_create_style_context (screen, (char *)variant->data);
+      style_info = meta_theme_create_style_info (screen, (char *)variant->data);
       g_hash_table_insert (frames->style_variants,
-                           g_strdup (variant->data), style);
+                           g_strdup (variant->data), style_info);
     }
   g_list_free (variants);
 }
@@ -236,7 +236,7 @@ meta_frames_init (MetaFrames *frames)
   frames->cache = g_hash_table_new (g_direct_hash, g_direct_equal);
 
   frames->style_variants = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                                  g_free, g_object_unref);
+                                                  g_free, (GDestroyNotify)meta_style_info_unref);
   update_style_contexts (frames);
 
   meta_prefs_add_listener (prefs_changed_callback, frames);
@@ -278,7 +278,7 @@ meta_frames_destroy (GtkWidget *widget)
 
   if (frames->normal_style)
     {
-      g_object_unref (frames->normal_style);
+      meta_style_info_unref (frames->normal_style);
       frames->normal_style = NULL;
     }
 
@@ -641,8 +641,8 @@ meta_frames_attach_style (MetaFrames  *frames,
   gboolean has_frame;
   char *variant = NULL;
 
-  if (frame->style != NULL)
-    g_object_unref (frame->style);
+  if (frame->style_info != NULL)
+    meta_style_info_unref (frame->style_info);
 
   meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
                  frame->xwindow,
@@ -651,10 +651,10 @@ meta_frames_attach_style (MetaFrames  *frames,
                  META_CORE_GET_END);
 
   if (variant == NULL || strcmp(variant, "normal") == 0)
-    frame->style = g_object_ref (frames->normal_style);
+    frame->style_info = meta_style_info_ref (frames->normal_style);
   else
-    frame->style = g_object_ref (meta_frames_get_theme_variant (frames,
-                                                                variant));
+    frame->style_info = meta_style_info_ref (meta_frames_get_theme_variant (frames,
+                                                                            variant));
 }
 
 void
@@ -672,7 +672,7 @@ meta_frames_manage_window (MetaFrames *frames,
 
   gdk_window_set_user_data (frame->window, frames);
 
-  frame->style = NULL;
+  frame->style_info = NULL;
 
   /* Don't set event mask here, it's in frame.c */
 
@@ -724,7 +724,7 @@ meta_frames_unmanage_window (MetaFrames *frames,
 
       g_hash_table_remove (frames->frames, &frame->xwindow);
 
-      g_object_unref (frame->style);
+      meta_style_info_unref (frame->style_info);
 
       gdk_window_destroy (frame->window);
 
@@ -2500,7 +2500,7 @@ meta_frames_paint (MetaFrames   *frames,
   meta_prefs_get_button_layout (&button_layout);
 
   meta_theme_draw_frame (meta_theme_get_current (),
-                         frame->style,
+                         frame->style_info,
                          cr,
                          type,
                          flags,
@@ -2541,7 +2541,7 @@ meta_frames_set_window_background (MetaFrames   *frames,
       GdkVisual *visual;
 
       meta_color_spec_render (style->window_background_color,
-                              frame->style,
+                              frame->style_info->styles[META_STYLE_ELEMENT_FRAME],
                               &color);
 
       /* Set A in ARGB to window_background_alpha, if we have ARGB */
@@ -2556,7 +2556,8 @@ meta_frames_set_window_background (MetaFrames   *frames,
     }
   else
     {
-      gtk_style_context_set_background (frame->style, frame->window);
+      gtk_style_context_set_background (frame->style_info->styles[META_STYLE_ELEMENT_FRAME],
+                                        frame->window);
     }
  }
 
diff --git a/src/ui/frames.h b/src/ui/frames.h
index ec83cd4..d4b2dee 100644
--- a/src/ui/frames.h
+++ b/src/ui/frames.h
@@ -74,7 +74,7 @@ struct _MetaUIFrame
 {
   Window xwindow;
   GdkWindow *window;
-  GtkStyleContext *style;
+  MetaStyleInfo *style_info;
   MetaFrameStyle *cache_style;
   PangoLayout *layout;
   int text_height;
@@ -97,7 +97,7 @@ struct _MetaFrames
   guint tooltip_timeout;
   MetaUIFrame *last_motion_frame;
 
-  GtkStyleContext *normal_style;
+  MetaStyleInfo *normal_style;
   GHashTable *style_variants;
 
   int expose_delay_count;
diff --git a/src/ui/preview-widget.c b/src/ui/preview-widget.c
index 1d7aeb6..9b18441 100644
--- a/src/ui/preview-widget.c
+++ b/src/ui/preview-widget.c
@@ -113,7 +113,11 @@ meta_preview_dispose (GObject *object)
 {
   MetaPreview *preview = META_PREVIEW (object);
 
-  g_clear_object (&preview->style_context);
+  if (preview->style_info)
+    {
+      meta_style_info_unref (preview->style_info);
+      preview->style_info = NULL;
+    }
 
   G_OBJECT_CLASS (meta_preview_parent_class)->dispose (object);
 }
@@ -231,7 +235,7 @@ meta_preview_draw (GtkWidget *widget,
       border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
 
       meta_theme_draw_frame (preview->theme,
-                             preview->style_context,
+                             preview->style_info,
                              cr,
                              preview->type,
                              preview->flags,
@@ -257,8 +261,8 @@ meta_preview_realize (GtkWidget *widget)
 
   GTK_WIDGET_CLASS (meta_preview_parent_class)->realize (widget);
 
-  preview->style_context = meta_theme_create_style_context (gtk_widget_get_screen (widget),
-                                                            NULL);
+  preview->style_info = meta_theme_create_style_info (gtk_widget_get_screen (widget),
+                                                      NULL);
 }
 
 #define NO_CHILD_WIDTH 80
diff --git a/src/ui/preview-widget.h b/src/ui/preview-widget.h
index db85b13..753707a 100644
--- a/src/ui/preview-widget.h
+++ b/src/ui/preview-widget.h
@@ -39,7 +39,7 @@ struct _MetaPreview
 {
   GtkBin bin;
 
-  GtkStyleContext *style_context;
+  MetaStyleInfo *style_info;
 
   MetaTheme *theme;
   char *title;
diff --git a/src/ui/theme-viewer.c b/src/ui/theme-viewer.c
index 22c618a..9516b79 100644
--- a/src/ui/theme-viewer.c
+++ b/src/ui/theme-viewer.c
@@ -837,7 +837,7 @@ main (int argc, char **argv)
 {
   GtkWidget *window;
   GtkWidget *collection;
-  GtkStyleContext *style;
+  MetaStyleInfo *style_info;
   PangoFontDescription *font_desc;
   GError *err;
   clock_t start, end;
@@ -914,10 +914,11 @@ main (int argc, char **argv)
 
   gtk_widget_realize (window);
 
-  style = meta_theme_create_style_context (gtk_widget_get_screen (window), NULL);
-  gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, "font", &font_desc, NULL);
+  style_info = meta_theme_create_style_info (gtk_widget_get_screen (window), NULL);
+  gtk_style_context_get (style_info->styles[META_STYLE_ELEMENT_FRAME],
+                         GTK_STATE_FLAG_NORMAL, "font", &font_desc, NULL);
+  meta_style_info_unref (style_info);
 
-  g_assert (style);
   g_assert (font_desc);
 
   notebook = gtk_notebook_new ();
@@ -987,13 +988,14 @@ get_flags (GtkWidget *widget)
 }
 
 static int
-get_text_height (GtkWidget       *widget,
-                 GtkStyleContext *style)
+get_text_height (GtkWidget     *widget,
+                 MetaStyleInfo *style_info)
 {
   PangoFontDescription *font_desc;
   int                   text_height;
 
-  gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, "font", &font_desc, NULL);
+  gtk_style_context_get (style_info->styles[META_STYLE_ELEMENT_FRAME],
+                         GTK_STATE_FLAG_NORMAL, "font", &font_desc, NULL);
   text_height = meta_pango_font_desc_get_text_height (font_desc, gtk_widget_get_pango_context (widget));
   pango_font_description_free (font_desc);
 
@@ -1014,7 +1016,7 @@ static void
 run_theme_benchmark (void)
 {
   GtkWidget* widget;
-  GtkStyleContext *style_context;
+  MetaStyleInfo *style_info;
   cairo_surface_t *pixmap;
   MetaFrameBorders borders;
   MetaButtonState button_states[META_BUTTON_TYPE_LAST] =
@@ -1039,11 +1041,11 @@ run_theme_benchmark (void)
   widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_widget_realize (widget);
 
-  style_context = meta_theme_create_style_context (gtk_widget_get_screen (widget), NULL);
+  style_info = meta_theme_create_style_info (gtk_widget_get_screen (widget), NULL);
 
   meta_theme_get_frame_borders (global_theme,
                                 META_FRAME_TYPE_NORMAL,
-                                get_text_height (widget, style_context),
+                                get_text_height (widget, style_info),
                                 get_flags (widget),
                                 &borders);
 
@@ -1085,13 +1087,13 @@ run_theme_benchmark (void)
       cr = cairo_create (pixmap);
 
       meta_theme_draw_frame (global_theme,
-                             style_context,
+                             style_info,
                              cr,
                              META_FRAME_TYPE_NORMAL,
                              get_flags (widget),
                              client_width, client_height,
                              layout,
-                             get_text_height (widget, style_context),
+                             get_text_height (widget, style_info),
                              &button_layout,
                              button_states,
                              meta_preview_get_mini_icon (),
@@ -1119,7 +1121,7 @@ run_theme_benchmark (void)
 
   g_timer_destroy (timer);
   g_object_unref (G_OBJECT (layout));
-  g_object_unref (style_context);
+  meta_style_info_unref (style_info);
   gtk_widget_destroy (widget);
 
 #undef ITERATIONS
diff --git a/src/ui/theme.c b/src/ui/theme.c
index ccc383c..061e4b7 100644
--- a/src/ui/theme.c
+++ b/src/ui/theme.c
@@ -4645,7 +4645,7 @@ get_button_rect (MetaButtonType           type,
 
 static void
 meta_frame_style_draw_with_style (MetaFrameStyle          *style,
-                                  GtkStyleContext         *style_gtk,
+                                  MetaStyleInfo           *style_info,
                                   cairo_t                 *cr,
                                   const MetaFrameGeometry *fgeom,
                                   int                      client_width,
@@ -4811,7 +4811,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle          *style,
               MetaRectangle m_rect;
               m_rect = meta_rect (rect.x, rect.y, rect.width, rect.height);
               meta_draw_op_list_draw_with_style (op_list,
-                                                 style_gtk,
+                                                 style_info->styles[META_STYLE_ELEMENT_FRAME],
                                                  cr,
                                                  &draw_info,
                                                  m_rect);
@@ -4849,7 +4849,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle          *style,
                       m_rect = meta_rect (rect.x, rect.y,
                                           rect.width, rect.height);
                       meta_draw_op_list_draw_with_style (op_list,
-                                                         style_gtk,
+                                                         style_info->styles[META_STYLE_ELEMENT_FRAME],
                                                          cr,
                                                          &draw_info,
                                                          m_rect);
@@ -5479,11 +5479,12 @@ meta_theme_get_title_scale (MetaTheme     *theme,
   return style->layout->title_scale;
 }
 
-GtkStyleContext *
-meta_theme_create_style_context (GdkScreen   *screen,
-                                 const gchar *variant)
+MetaStyleInfo *
+meta_theme_create_style_info (GdkScreen   *screen,
+                              const gchar *variant)
 {
   GtkWidgetPath *path;
+  MetaStyleInfo *style_info;
   GtkStyleContext *style;
   char *theme_name;
 
@@ -5491,11 +5492,17 @@ meta_theme_create_style_context (GdkScreen   *screen,
                 "gtk-theme-name", &theme_name,
                 NULL);
 
-  style = gtk_style_context_new ();
+  style_info = g_new0 (MetaStyleInfo, 1);
+  style_info->refcount = 1;
+
   path = gtk_widget_path_new ();
+
+  style_info->styles[META_STYLE_ELEMENT_FRAME] = style = gtk_style_context_new ();
   gtk_widget_path_append_type (path, META_TYPE_FRAMES);
   gtk_widget_path_iter_add_class (path, -1, GTK_STYLE_CLASS_BACKGROUND);
+  gtk_widget_path_iter_add_class (path, -1, "window-frame");
   gtk_style_context_set_path (style, path);
+
   gtk_widget_path_unref (path);
 
   if (theme_name && *theme_name)
@@ -5510,12 +5517,37 @@ meta_theme_create_style_context (GdkScreen   *screen,
 
   g_free (theme_name);
 
-  return style;
+  return style_info;
+}
+
+MetaStyleInfo *
+meta_style_info_ref (MetaStyleInfo *style_info)
+{
+  g_return_val_if_fail (style_info != NULL, NULL);
+  g_return_val_if_fail (style_info->refcount > 0, NULL);
+
+  g_atomic_int_inc ((volatile int *)&style_info->refcount);
+  return style_info;
+}
+
+void
+meta_style_info_unref (MetaStyleInfo *style_info)
+{
+  g_return_if_fail (style_info != NULL);
+  g_return_if_fail (style_info->refcount > 0);
+
+  if (g_atomic_int_dec_and_test ((volatile int *)&style_info->refcount))
+    {
+      int i;
+      for (i = 0; i < META_STYLE_ELEMENT_LAST; i++)
+        g_object_unref (style_info->styles[i]);
+      g_free (style_info);
+    }
 }
 
 void
 meta_theme_draw_frame (MetaTheme              *theme,
-                       GtkStyleContext        *style_gtk,
+                       MetaStyleInfo          *style_info,
                        cairo_t                *cr,
                        MetaFrameType           type,
                        MetaFrameFlags          flags,
@@ -5548,7 +5580,7 @@ meta_theme_draw_frame (MetaTheme              *theme,
                                    theme);
 
   meta_frame_style_draw_with_style (style,
-                                    style_gtk,
+                                    style_info,
                                     cr,
                                     &fgeom,
                                     client_width, client_height,
diff --git a/src/ui/theme.h b/src/ui/theme.h
index eb766fd..d85af48 100644
--- a/src/ui/theme.h
+++ b/src/ui/theme.h
@@ -27,6 +27,11 @@
 #include "common.h"
 #include <gtk/gtk.h>
 
+/**
+ * MetaStyleInfo: (skip)
+ *
+ */
+typedef struct _MetaStyleInfo MetaStyleInfo;
 typedef struct _MetaFrameStyle MetaFrameStyle;
 typedef struct _MetaFrameStyleSet MetaFrameStyleSet;
 typedef struct _MetaDrawOp MetaDrawOp;
@@ -682,6 +687,19 @@ typedef enum
 
 typedef enum
 {
+  META_STYLE_ELEMENT_FRAME,
+  META_STYLE_ELEMENT_LAST
+} MetaStyleElement;
+
+struct _MetaStyleInfo
+{
+  int refcount;
+
+  GtkStyleContext *styles[META_STYLE_ELEMENT_LAST];
+};
+
+typedef enum
+{
   /* Listed in the order in which the textures are drawn.
    * (though this only matters for overlaps of course.)
    * Buttons are drawn after the frame textures.
@@ -1040,11 +1058,13 @@ double meta_theme_get_title_scale (MetaTheme     *theme,
                                    MetaFrameType  type,
                                    MetaFrameFlags flags);
 
-GtkStyleContext* meta_theme_create_style_context (GdkScreen   *screen,
-                                                  const gchar *variant);
+MetaStyleInfo* meta_theme_create_style_info (GdkScreen     *screen,
+                                             const gchar   *variant);
+MetaStyleInfo* meta_style_info_ref          (MetaStyleInfo *style);
+void           meta_style_info_unref        (MetaStyleInfo *style_info);
 
 void meta_theme_draw_frame (MetaTheme              *theme,
-                            GtkStyleContext        *style_gtk,
+                            MetaStyleInfo          *style_info,
                             cairo_t                *cr,
                             MetaFrameType           type,
                             MetaFrameFlags          flags,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]