From 472f2a4b8e139c9c1d651d2e5705bc03f77335de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 24 Sep 2014 00:07:21 +0200 Subject: [PATCH] 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 --- src/ui/frames.c | 44 +++++++++++++++++------------------ src/ui/frames.h | 4 ++-- src/ui/theme-private.h | 26 ++++++++++++++++++--- src/ui/theme.c | 52 ++++++++++++++++++++++++++++++++++-------- 4 files changed, 89 insertions(+), 37 deletions(-) diff --git a/src/ui/frames.c b/src/ui/frames.c index 18c34a8d7..04a033359 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -170,41 +170,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); } @@ -217,7 +217,7 @@ meta_frames_init (MetaFrames *frames) frames->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_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); @@ -258,7 +258,7 @@ meta_frames_destroy (GtkWidget *object) if (frames->normal_style) { - g_object_unref (frames->normal_style); + meta_style_info_unref (frames->normal_style); frames->normal_style = NULL; } @@ -531,8 +531,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, @@ -541,10 +541,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 @@ -562,7 +562,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 */ @@ -602,7 +602,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); @@ -1833,7 +1833,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, diff --git a/src/ui/frames.h b/src/ui/frames.h index 5503ba918..784285558 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 GHashTable *frames; MetaUIFrame *last_motion_frame; - GtkStyleContext *normal_style; + MetaStyleInfo *normal_style; GHashTable *style_variants; MetaGrabOp current_grab_op; diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h index a57ab60ad..7b0936f65 100644 --- a/src/ui/theme-private.h +++ b/src/ui/theme-private.h @@ -27,6 +27,11 @@ #include #include +/** + * MetaStyleInfo: (skip) + * + */ +typedef struct _MetaStyleInfo MetaStyleInfo; /** * MetaFrameStyle: (skip) * @@ -676,6 +681,19 @@ typedef enum META_BUTTON_TYPE_LAST } MetaButtonType; +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. @@ -1024,11 +1042,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, diff --git a/src/ui/theme.c b/src/ui/theme.c index 8129987d1..326ac1898 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -4158,7 +4158,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, @@ -4327,7 +4327,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); @@ -4368,7 +4368,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, 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); @@ -4999,11 +4999,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; @@ -5011,11 +5012,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) @@ -5030,12 +5037,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, @@ -5069,7 +5101,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,