From 6582c8a7b2d32a0e231771bb6206e289ddaf46cc 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: 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. --- src/ui/frames.c | 44 ++++++++++++++++++++--------------------- 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, 113 insertions(+), 55 deletions(-) diff --git a/src/ui/frames.c b/src/ui/frames.c index 36b13e8c..d45f9978 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -176,41 +176,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); } @@ -231,7 +231,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); @@ -273,7 +273,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; } @@ -624,8 +624,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, @@ -634,10 +634,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 @@ -655,7 +655,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 */ @@ -702,7 +702,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); @@ -2610,7 +2610,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 4f8705e5..fccd0373 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 10324861..32c07e86 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 db85b130..753707a9 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 7e2946b7..c772ff2d 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 d77f31da..b89cad59 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -4613,7 +4613,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, @@ -4782,7 +4782,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); @@ -4820,7 +4820,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); @@ -5439,11 +5439,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; @@ -5451,11 +5452,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) @@ -5470,12 +5477,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, @@ -5509,7 +5541,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 ffec77c5..3966d928 100644 --- a/src/ui/theme.h +++ b/src/ui/theme.h @@ -27,6 +27,11 @@ #include "common.h" #include +/** + * MetaStyleInfo: (skip) + * + */ +typedef struct _MetaStyleInfo MetaStyleInfo; typedef struct _MetaFrameStyle MetaFrameStyle; typedef struct _MetaFrameStyleSet MetaFrameStyleSet; typedef struct _MetaDrawOp MetaDrawOp; @@ -632,6 +637,19 @@ typedef enum META_MENU_ICON_TYPE_LAST } MetaMenuIconType; +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. @@ -977,11 +995,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, -- cgit v1.2.1