[mutter/wip/cb2eb3: 12/55] ui: Move theme variant code loading into theme.c



commit af242b27b28ed06322083f56987c1f48e9335ea2
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Sun Mar 11 16:08:41 2012 -0400

    ui: Move theme variant code loading into theme.c
    
    As we'll have a new API that draws using GtkStyleContext, it makes sense
    to put all API using GtkStyleContext where the theme code is. Note that
    the MetaThemeVariant code is just a stop-gap right now - in the future,
    we'll have per-window theming, using CSS infrastructure like includes
    for code reuse.

 src/ui/frames.c        |  209 +++---------------------------------------------
 src/ui/frames.h        |    8 +--
 src/ui/theme-private.h |   14 +++
 src/ui/theme.c         |   80 ++++++++++++++++++
 4 files changed, 109 insertions(+), 202 deletions(-)
---
diff --git a/src/ui/frames.c b/src/ui/frames.c
index a5757e9..75f3340 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -35,6 +35,8 @@
 #include <meta/prefs.h>
 #include "ui.h"
 
+#include "theme-private.h"
+
 #include <cairo-xlib.h>
 
 #ifdef HAVE_SHAPE
@@ -74,9 +76,6 @@ static void meta_frames_paint        (MetaFrames   *frames,
                                       MetaUIFrame  *frame,
                                       cairo_t      *cr);
 
-static void meta_frames_set_window_background (MetaFrames   *frames,
-                                               MetaUIFrame  *frame);
-
 static void meta_frames_calc_geometry (MetaFrames        *frames,
                                        MetaUIFrame         *frame,
                                        MetaFrameGeometry *fgeom);
@@ -186,74 +185,6 @@ prefs_changed_callback (MetaPreference pref,
     }
 }
 
-static GtkStyleContext *
-create_style_context (MetaFrames  *frames,
-                      const gchar *variant)
-{
-  GtkStyleContext *style;
-  GdkScreen *screen;
-  char *theme_name;
-
-  screen = gtk_widget_get_screen (GTK_WIDGET (frames));
-  g_object_get (gtk_settings_get_for_screen (screen),
-                "gtk-theme-name", &theme_name,
-                NULL);
-
-  style = gtk_style_context_new ();
-  gtk_style_context_set_path (style,
-                              gtk_widget_get_path (GTK_WIDGET (frames)));
-
-  if (theme_name && *theme_name)
-    {
-      GtkCssProvider *provider;
-
-      provider = gtk_css_provider_get_named (theme_name, variant);
-      gtk_style_context_add_provider (style,
-                                      GTK_STYLE_PROVIDER (provider),
-                                      GTK_STYLE_PROVIDER_PRIORITY_THEME);
-    }
-
-  g_free (theme_name);
-
-  return style;
-}
-
-static GtkStyleContext *
-meta_frames_get_theme_variant (MetaFrames  *frames,
-                               const gchar *variant)
-{
-  GtkStyleContext *style;
-
-  style = g_hash_table_lookup (frames->style_variants, variant);
-  if (style == NULL)
-    {
-      style = create_style_context (frames, variant);
-      g_hash_table_insert (frames->style_variants, g_strdup (variant), style);
-    }
-
-  return style;
-}
-
-static void
-update_style_contexts (MetaFrames *frames)
-{
-  GtkStyleContext *style;
-  GList *variants, *variant;
-
-  if (frames->normal_style)
-    g_object_unref (frames->normal_style);
-  frames->normal_style = create_style_context (frames, NULL);
-
-  variants = g_hash_table_get_keys (frames->style_variants);
-  for (variant = variants; variant; variant = variants->next)
-    {
-      style = create_style_context (frames, (char *)variant->data);
-      g_hash_table_insert (frames->style_variants,
-                           g_strdup (variant->data), style);
-    }
-  g_list_free (variants);
-}
-
 static void
 meta_frames_init (MetaFrames *frames)
 {
@@ -267,10 +198,6 @@ meta_frames_init (MetaFrames *frames)
   frames->invalidate_frames = NULL;
   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);
-  update_style_contexts (frames);
-
   gtk_widget_set_double_buffered (GTK_WIDGET (frames), FALSE);
 
   meta_prefs_add_listener (prefs_changed_callback, frames);
@@ -308,18 +235,6 @@ meta_frames_destroy (GtkWidget *object)
     }
   g_slist_free (winlist);
 
-  if (frames->normal_style)
-    {
-      g_object_unref (frames->normal_style);
-      frames->normal_style = NULL;
-    }
-
-  if (frames->style_variants)
-    {
-      g_hash_table_destroy (frames->style_variants);
-      frames->style_variants = NULL;
-    }
-
   GTK_WIDGET_CLASS (meta_frames_parent_class)->destroy (object);
 }
 
@@ -425,12 +340,6 @@ queue_recalc_func (gpointer key, gpointer value, gpointer data)
 
   frames = META_FRAMES (data);
   frame = value;
-
-  /* If a resize occurs it will cause a redraw, but the
-   * resize may not actually be needed so we always redraw
-   * in case of color change.
-   */
-  meta_frames_set_window_background (frames, frame);
   
   invalidate_whole_window (frames, frame);
   meta_core_queue_frame_resize (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
@@ -471,12 +380,6 @@ queue_draw_func (gpointer key, gpointer value, gpointer data)
   frames = META_FRAMES (data);
   frame = value;
 
-  /* If a resize occurs it will cause a redraw, but the
-   * resize may not actually be needed so we always redraw
-   * in case of color change.
-   */
-  meta_frames_set_window_background (frames, frame);
-
   invalidate_whole_window (frames, frame);
 }
 
@@ -508,8 +411,6 @@ meta_frames_style_updated  (GtkWidget *widget)
 
   meta_frames_font_changed (frames);
 
-  update_style_contexts (frames);
-
   g_hash_table_foreach (frames->frames,
                         reattach_style_func, frames);
 
@@ -523,7 +424,6 @@ meta_frames_ensure_layout (MetaFrames  *frames,
   GtkWidget *widget;
   MetaFrameFlags flags;
   MetaFrameType type;
-  MetaFrameStyle *style;
 
   widget = GTK_WIDGET (frames);
 
@@ -533,25 +433,6 @@ meta_frames_ensure_layout (MetaFrames  *frames,
                  META_CORE_GET_FRAME_FLAGS, &flags,
                  META_CORE_GET_FRAME_TYPE, &type,
                  META_CORE_GET_END);
-
-  style = meta_theme_get_frame_style (meta_theme_get_current (),
-                                      type, flags);
-
-  if (style != frame->cache_style)
-    {
-      if (frame->layout)
-        {
-          /* save title to recreate layout */
-          g_free (frame->title);
-          
-          frame->title = g_strdup (pango_layout_get_text (frame->layout));
-
-          g_object_unref (G_OBJECT (frame->layout));
-          frame->layout = NULL;
-        }
-    }
-
-  frame->cache_style = style;
   
   if (frame->layout == NULL)
     {
@@ -560,10 +441,10 @@ meta_frames_ensure_layout (MetaFrames  *frames,
       double scale;
       int size;
       
-      scale = meta_theme_get_title_scale (meta_theme_get_current (),
+      scale = meta_theme_get_title_scale (frame->tv->theme,
                                           type,
                                           flags);
-      
+
       frame->layout = gtk_widget_create_pango_layout (widget, frame->title);
 
       pango_layout_set_ellipsize (frame->layout, PANGO_ELLIPSIZE_END);
@@ -623,7 +504,7 @@ meta_frames_calc_geometry (MetaFrames        *frames,
 
   meta_prefs_get_button_layout (&button_layout);
   
-  meta_theme_calc_geometry (meta_theme_get_current (),
+  meta_theme_calc_geometry (frame->tv->theme,
                             type,
                             frame->text_height,
                             flags,
@@ -655,23 +536,15 @@ static void
 meta_frames_attach_style (MetaFrames  *frames,
                           MetaUIFrame *frame)
 {
-  gboolean has_frame;
   char *variant = NULL;
 
-  if (frame->style != NULL)
-    g_object_unref (frame->style);
-
   meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
                  frame->xwindow,
-                 META_CORE_WINDOW_HAS_FRAME, &has_frame,
                  META_CORE_GET_THEME_VARIANT, &variant,
                  META_CORE_GET_END);
 
-  if (variant == NULL || strcmp(variant, "normal") == 0)
-    frame->style = g_object_ref (frames->normal_style);
-  else
-    frame->style = g_object_ref (meta_frames_get_theme_variant (frames,
-                                                                variant));
+  frame->tv = meta_theme_get_variant (meta_theme_get_current (),
+                                      variant);
 }
 
 void
@@ -689,12 +562,9 @@ meta_frames_manage_window (MetaFrames *frames,
 
   gdk_window_set_user_data (frame->window, frames);
 
-  frame->style = NULL;
-
   /* Don't set event mask here, it's in frame.c */
   
   frame->xwindow = xwindow;
-  frame->cache_style = NULL;
   frame->layout = NULL;
   frame->text_height = -1;
   frame->title = NULL;
@@ -739,8 +609,6 @@ meta_frames_unmanage_window (MetaFrames *frames,
       
       g_hash_table_remove (frames->frames, &frame->xwindow);
 
-      g_object_unref (frame->style);
-
       gdk_window_destroy (frame->window);
 
       if (frame->layout)
@@ -810,7 +678,7 @@ meta_frames_get_borders (MetaFrames *frames,
    * by the core move/resize code to decide on the client
    * window size
    */
-  meta_theme_get_frame_borders (meta_theme_get_current (),
+  meta_theme_get_frame_borders (frame->tv->theme,
                                 type,
                                 frame->text_height,
                                 flags,
@@ -855,11 +723,6 @@ void
 meta_frames_reset_bg (MetaFrames *frames,
                       Window  xwindow)
 {
-  MetaUIFrame *frame;
-  
-  frame = meta_frames_lookup_window (frames, xwindow);
-
-  meta_frames_set_window_background (frames, frame);
 }
 
 static void
@@ -1966,7 +1829,7 @@ populate_cache (MetaFrames *frames,
       return;
     }
   
-  meta_theme_get_frame_borders (meta_theme_get_current (),
+  meta_theme_get_frame_borders (frame->tv->theme,
                                 frame_type,
                                 frame->text_height,
                                 frame_flags,
@@ -2082,7 +1945,7 @@ subtract_client_area (cairo_region_t *region,
                  META_CORE_GET_CLIENT_WIDTH, &area.width,
                  META_CORE_GET_CLIENT_HEIGHT, &area.height,
                  META_CORE_GET_END);
-  meta_theme_get_frame_borders (meta_theme_get_current (),
+  meta_theme_get_frame_borders (frame->tv->theme,
                                 type, frame->text_height, flags, 
                                 &borders);
 
@@ -2203,7 +2066,7 @@ meta_frames_paint (MetaFrames   *frames,
   MetaButtonLayout button_layout;
   MetaGrabOp grab_op;
   Display *display;
-  
+
   display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
 
   for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
@@ -2300,8 +2163,8 @@ meta_frames_paint (MetaFrames   *frames,
 
   meta_prefs_get_button_layout (&button_layout);
 
-  meta_theme_draw_frame_with_style (meta_theme_get_current (),
-                                    frame->style,
+  meta_theme_draw_frame_with_style (frame->tv->theme,
+                                    frame->tv->style_context,
                                     cr,
                                     type,
                                     flags,
@@ -2313,52 +2176,6 @@ meta_frames_paint (MetaFrames   *frames,
                                     mini_icon, icon);
 }
 
-static void
-meta_frames_set_window_background (MetaFrames   *frames,
-                                   MetaUIFrame  *frame)
-{
-  MetaFrameFlags flags;
-  MetaFrameType type;
-  MetaFrameStyle *style = NULL;
-  gboolean frame_exists;
-
-  meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
-                 META_CORE_WINDOW_HAS_FRAME, &frame_exists,
-                 META_CORE_GET_FRAME_FLAGS, &flags,
-                 META_CORE_GET_FRAME_TYPE, &type,
-                 META_CORE_GET_END);
-
-  if (frame_exists)
-    {
-      style = meta_theme_get_frame_style (meta_theme_get_current (),
-                                          type, flags);
-    }
-
-  if (frame_exists && style->window_background_color != NULL)
-    {
-      GdkRGBA color;
-      GdkVisual *visual;
-
-      meta_color_spec_render (style->window_background_color,
-                              frame->style,
-                              &color);
-
-      /* Set A in ARGB to window_background_alpha, if we have ARGB */
-
-      visual = gtk_widget_get_visual (GTK_WIDGET (frames));
-      if (gdk_visual_get_depth (visual) == 32) /* we have ARGB */
-        {
-          color.alpha = style->window_background_alpha / 255.0;
-        }
-
-      gdk_window_set_background_rgba (frame->window, &color);
-    }
-  else
-    {
-      gtk_style_context_set_background (frame->style, frame->window);
-    }
- }
-
 static gboolean
 meta_frames_enter_notify_event      (GtkWidget           *widget,
                                      GdkEventCrossing    *event)
diff --git a/src/ui/frames.h b/src/ui/frames.h
index 02d6b5b..c7d54bf 100644
--- a/src/ui/frames.h
+++ b/src/ui/frames.h
@@ -75,14 +75,13 @@ struct _MetaUIFrame
 {
   Window xwindow;
   GdkWindow *window;
-  GtkStyleContext *style;
-  MetaFrameStyle *cache_style;
+  MetaThemeVariant *tv;
   PangoLayout *layout;
   int text_height;
   char *title; /* NULL once we have a layout */
   guint expose_delayed : 1;
   guint shape_applied : 1;
-  
+
   /* FIXME get rid of this, it can just be in the MetaFrames struct */
   MetaFrameControl prelit_control;
 };
@@ -96,9 +95,6 @@ struct _MetaFrames
   GHashTable *frames;
   MetaUIFrame *last_motion_frame;
 
-  GtkStyleContext *normal_style;
-  GHashTable *style_variants;
-
   int expose_delay_count;
 
   int invalidate_cache_timeout_id;
diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h
index 2c9f19e..f197045 100644
--- a/src/ui/theme-private.h
+++ b/src/ui/theme-private.h
@@ -29,6 +29,8 @@
 #include <meta/common.h>
 #include <gtk/gtk.h>
 
+typedef struct _MetaThemeVariant MetaThemeVariant;
+
 /**
  * MetaFrameStyle: (skip)
  *
@@ -893,6 +895,15 @@ struct _MetaTheme
   GQuark quark_title_height;
   GQuark quark_frame_x_center;
   GQuark quark_frame_y_center;
+
+  GHashTable *theme_variants;
+  MetaThemeVariant *normal_variant;
+};
+
+struct _MetaThemeVariant
+{
+  MetaTheme *theme;
+  GtkStyleContext *style_context;
 };
 
 struct _MetaPositionExprEnv
@@ -1188,6 +1199,9 @@ void                  meta_gtk_style_get_dark_color    (GtkStyleContext      *st
 guint meta_theme_earliest_version_with_button (MetaButtonType type);
 
 
+MetaThemeVariant * meta_theme_get_variant (MetaTheme *theme,
+                                           gchar     *variant);
+
 #define META_THEME_ALLOWS(theme, feature) (theme->format_version >= feature)
 
 /* What version of the theme file format were various features introduced in? */
diff --git a/src/ui/theme.c b/src/ui/theme.c
index 02b2b60..dc83560 100644
--- a/src/ui/theme.c
+++ b/src/ui/theme.c
@@ -4596,6 +4596,82 @@ meta_theme_set_current (const char *name,
     }
 }
 
+/* owns style context */
+static MetaThemeVariant *
+meta_theme_variant_new (MetaTheme *theme,
+                        GtkStyleContext *style_context)
+{
+  MetaThemeVariant *tv = g_slice_new (MetaThemeVariant);
+  tv->theme = theme;
+  tv->style_context = style_context;
+  return tv;
+}
+
+static void
+meta_theme_variant_free (gpointer data)
+{
+  MetaThemeVariant *tv = data;
+
+  g_object_unref (tv->style_context);
+  g_slice_free (MetaThemeVariant, tv);
+}
+
+static GtkStyleContext *
+create_style_context (gchar *variant)
+{
+  GtkStyleContext *style;
+  GdkScreen *screen;
+  GtkWidgetPath *path;
+  char *theme_name;
+
+  screen = gdk_screen_get_default ();
+  g_object_get (gtk_settings_get_for_screen (screen),
+                "gtk-theme-name", &theme_name,
+                NULL);
+
+  path = gtk_widget_path_new ();
+  gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
+
+  style = gtk_style_context_new ();
+  gtk_style_context_set_path (style, path);
+
+  gtk_widget_path_unref (path);
+
+  if (theme_name && *theme_name)
+    {
+      GtkCssProvider *provider;
+
+      provider = gtk_css_provider_get_named (theme_name, variant);
+      gtk_style_context_add_provider (style,
+                                      GTK_STYLE_PROVIDER (provider),
+                                      GTK_STYLE_PROVIDER_PRIORITY_THEME);
+    }
+
+  g_free (theme_name);
+
+  return style;
+}
+
+MetaThemeVariant *
+meta_theme_get_variant (MetaTheme *theme,
+                        gchar     *variant)
+{
+  MetaThemeVariant *tv;
+
+  if (variant == NULL || strcmp (variant, "normal") == 0)
+    return theme->normal_variant;
+
+  tv = g_hash_table_lookup (theme->theme_variants, variant);
+  if (tv == NULL)
+    {
+      GtkStyleContext *style = create_style_context (variant);
+      tv = meta_theme_variant_new (theme, style);
+      g_hash_table_insert (theme->theme_variants, g_strdup (variant), tv);
+    }
+
+  return tv;
+}
+
 /**
  * meta_theme_new: (skip)
  *
@@ -4636,6 +4712,10 @@ meta_theme_new (void)
                            g_str_equal,
                            g_free,
                            (GDestroyNotify) meta_frame_style_set_unref);
+
+  theme->normal_variant = meta_theme_variant_new (theme, create_style_context (NULL));
+  theme->theme_variants = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                 g_free, meta_theme_variant_free);
   
   /* Create our variable quarks so we can look up variables without
      having to strcmp for the names */


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