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
This commit is contained in:
Florian Müllner 2014-09-24 00:07:21 +02:00 committed by Jasper St. Pierre
parent db04ac9eb7
commit 472f2a4b8e
4 changed files with 89 additions and 37 deletions

View File

@ -170,41 +170,41 @@ prefs_changed_callback (MetaPreference pref,
} }
} }
static GtkStyleContext * static MetaStyleInfo *
meta_frames_get_theme_variant (MetaFrames *frames, meta_frames_get_theme_variant (MetaFrames *frames,
const gchar *variant) const gchar *variant)
{ {
GtkStyleContext *style; MetaStyleInfo *style_info;
style = g_hash_table_lookup (frames->style_variants, variant); style_info = g_hash_table_lookup (frames->style_variants, variant);
if (style == NULL) if (style_info == NULL)
{ {
style = meta_theme_create_style_context (gtk_widget_get_screen (GTK_WIDGET (frames)), variant); 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); g_hash_table_insert (frames->style_variants, g_strdup (variant), style_info);
} }
return style; return style_info;
} }
static void static void
update_style_contexts (MetaFrames *frames) update_style_contexts (MetaFrames *frames)
{ {
GtkStyleContext *style; MetaStyleInfo *style_info;
GList *variants, *variant; GList *variants, *variant;
GdkScreen *screen; GdkScreen *screen;
screen = gtk_widget_get_screen (GTK_WIDGET (frames)); screen = gtk_widget_get_screen (GTK_WIDGET (frames));
if (frames->normal_style) if (frames->normal_style)
g_object_unref (frames->normal_style); meta_style_info_unref (frames->normal_style);
frames->normal_style = meta_theme_create_style_context (screen, NULL); frames->normal_style = meta_theme_create_style_info (screen, NULL);
variants = g_hash_table_get_keys (frames->style_variants); variants = g_hash_table_get_keys (frames->style_variants);
for (variant = variants; variant; variant = variants->next) 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_hash_table_insert (frames->style_variants,
g_strdup (variant->data), style); g_strdup (variant->data), style_info);
} }
g_list_free (variants); 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->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, 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); update_style_contexts (frames);
@ -258,7 +258,7 @@ meta_frames_destroy (GtkWidget *object)
if (frames->normal_style) if (frames->normal_style)
{ {
g_object_unref (frames->normal_style); meta_style_info_unref (frames->normal_style);
frames->normal_style = NULL; frames->normal_style = NULL;
} }
@ -531,8 +531,8 @@ meta_frames_attach_style (MetaFrames *frames,
gboolean has_frame; gboolean has_frame;
char *variant = NULL; char *variant = NULL;
if (frame->style != NULL) if (frame->style_info != NULL)
g_object_unref (frame->style); meta_style_info_unref (frame->style_info);
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
frame->xwindow, frame->xwindow,
@ -541,9 +541,9 @@ meta_frames_attach_style (MetaFrames *frames,
META_CORE_GET_END); META_CORE_GET_END);
if (variant == NULL || strcmp(variant, "normal") == 0) 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 else
frame->style = g_object_ref (meta_frames_get_theme_variant (frames, frame->style_info = meta_style_info_ref (meta_frames_get_theme_variant (frames,
variant)); variant));
} }
@ -562,7 +562,7 @@ meta_frames_manage_window (MetaFrames *frames,
gdk_window_set_user_data (frame->window, 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 */ /* 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_hash_table_remove (frames->frames, &frame->xwindow);
g_object_unref (frame->style); meta_style_info_unref (frame->style_info);
gdk_window_destroy (frame->window); gdk_window_destroy (frame->window);
@ -1833,7 +1833,7 @@ meta_frames_paint (MetaFrames *frames,
meta_prefs_get_button_layout (&button_layout); meta_prefs_get_button_layout (&button_layout);
meta_theme_draw_frame (meta_theme_get_current (), meta_theme_draw_frame (meta_theme_get_current (),
frame->style, frame->style_info,
cr, cr,
type, type,
flags, flags,

View File

@ -74,7 +74,7 @@ struct _MetaUIFrame
{ {
Window xwindow; Window xwindow;
GdkWindow *window; GdkWindow *window;
GtkStyleContext *style; MetaStyleInfo *style_info;
MetaFrameStyle *cache_style; MetaFrameStyle *cache_style;
PangoLayout *layout; PangoLayout *layout;
int text_height; int text_height;
@ -97,7 +97,7 @@ struct _MetaFrames
GHashTable *frames; GHashTable *frames;
MetaUIFrame *last_motion_frame; MetaUIFrame *last_motion_frame;
GtkStyleContext *normal_style; MetaStyleInfo *normal_style;
GHashTable *style_variants; GHashTable *style_variants;
MetaGrabOp current_grab_op; MetaGrabOp current_grab_op;

View File

@ -27,6 +27,11 @@
#include <meta/common.h> #include <meta/common.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
/**
* MetaStyleInfo: (skip)
*
*/
typedef struct _MetaStyleInfo MetaStyleInfo;
/** /**
* MetaFrameStyle: (skip) * MetaFrameStyle: (skip)
* *
@ -676,6 +681,19 @@ typedef enum
META_BUTTON_TYPE_LAST META_BUTTON_TYPE_LAST
} MetaButtonType; } MetaButtonType;
typedef enum
{
META_STYLE_ELEMENT_FRAME,
META_STYLE_ELEMENT_LAST
} MetaStyleElement;
struct _MetaStyleInfo
{
int refcount;
GtkStyleContext *styles[META_STYLE_ELEMENT_LAST];
};
typedef enum typedef enum
{ {
/* Listed in the order in which the textures are drawn. /* Listed in the order in which the textures are drawn.
@ -1024,11 +1042,13 @@ double meta_theme_get_title_scale (MetaTheme *theme,
MetaFrameType type, MetaFrameType type,
MetaFrameFlags flags); MetaFrameFlags flags);
GtkStyleContext * meta_theme_create_style_context (GdkScreen *screen, MetaStyleInfo * meta_theme_create_style_info (GdkScreen *screen,
const gchar *variant); 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, void meta_theme_draw_frame (MetaTheme *theme,
GtkStyleContext *style_gtk, MetaStyleInfo *style_info,
cairo_t *cr, cairo_t *cr,
MetaFrameType type, MetaFrameType type,
MetaFrameFlags flags, MetaFrameFlags flags,

View File

@ -4158,7 +4158,7 @@ get_button_rect (MetaButtonType type,
static void static void
meta_frame_style_draw_with_style (MetaFrameStyle *style, meta_frame_style_draw_with_style (MetaFrameStyle *style,
GtkStyleContext *style_gtk, MetaStyleInfo *style_info,
cairo_t *cr, cairo_t *cr,
const MetaFrameGeometry *fgeom, const MetaFrameGeometry *fgeom,
int client_width, int client_width,
@ -4327,7 +4327,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style,
MetaRectangle m_rect; MetaRectangle m_rect;
m_rect = meta_rect (rect.x, rect.y, rect.width, rect.height); m_rect = meta_rect (rect.x, rect.y, rect.width, rect.height);
meta_draw_op_list_draw_with_style (op_list, meta_draw_op_list_draw_with_style (op_list,
style_gtk, style_info->styles[META_STYLE_ELEMENT_FRAME],
cr, cr,
&draw_info, &draw_info,
m_rect); m_rect);
@ -4368,7 +4368,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style,
rect.width, rect.height); rect.width, rect.height);
meta_draw_op_list_draw_with_style (op_list, meta_draw_op_list_draw_with_style (op_list,
style_gtk, style_info->styles[META_STYLE_ELEMENT_FRAME],
cr, cr,
&draw_info, &draw_info,
m_rect); m_rect);
@ -4999,11 +4999,12 @@ meta_theme_get_title_scale (MetaTheme *theme,
return style->layout->title_scale; return style->layout->title_scale;
} }
GtkStyleContext * MetaStyleInfo *
meta_theme_create_style_context (GdkScreen *screen, meta_theme_create_style_info (GdkScreen *screen,
const gchar *variant) const gchar *variant)
{ {
GtkWidgetPath *path; GtkWidgetPath *path;
MetaStyleInfo *style_info;
GtkStyleContext *style; GtkStyleContext *style;
char *theme_name; char *theme_name;
@ -5011,11 +5012,17 @@ meta_theme_create_style_context (GdkScreen *screen,
"gtk-theme-name", &theme_name, "gtk-theme-name", &theme_name,
NULL); NULL);
style = gtk_style_context_new (); style_info = g_new0 (MetaStyleInfo, 1);
style_info->refcount = 1;
path = gtk_widget_path_new (); 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_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, GTK_STYLE_CLASS_BACKGROUND);
gtk_widget_path_iter_add_class (path, -1, "window-frame");
gtk_style_context_set_path (style, path); gtk_style_context_set_path (style, path);
gtk_widget_path_unref (path); gtk_widget_path_unref (path);
if (theme_name && *theme_name) if (theme_name && *theme_name)
@ -5030,12 +5037,37 @@ meta_theme_create_style_context (GdkScreen *screen,
g_free (theme_name); 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 void
meta_theme_draw_frame (MetaTheme *theme, meta_theme_draw_frame (MetaTheme *theme,
GtkStyleContext *style_gtk, MetaStyleInfo *style_info,
cairo_t *cr, cairo_t *cr,
MetaFrameType type, MetaFrameType type,
MetaFrameFlags flags, MetaFrameFlags flags,
@ -5069,7 +5101,7 @@ meta_theme_draw_frame (MetaTheme *theme,
theme); theme);
meta_frame_style_draw_with_style (style, meta_frame_style_draw_with_style (style,
style_gtk, style_info,
cr, cr,
&fgeom, &fgeom,
client_width, client_height, client_width, client_height,