summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Müllner <fmuellner@gnome.org>2011-03-18 13:56:30 +0100
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2014-10-08 18:37:30 +0300
commit04d8135fc62889d690f947d798d555e4aa8543ef (patch)
treeeb6cde414f1ccb629d95fdcc445d9ffabe7acd5e
parentee0568531ccdad69ea095b3c80742b332e607d83 (diff)
downloadmetacity-04d8135fc62889d690f947d798d555e4aa8543ef.tar.gz
ui-frame: Add support for style variants
Rather than sharing a single style context between all frames, use a default style and one style per encountered variant. The value of the _GTK_THEME_VARIANT property should determine which style is attached to a particular frame, though for the time being the default style is used for every frame, as the window property cannot be accessed at the time the style is attached. This will be fixed in a later commit. https://bugzilla.gnome.org/show_bug.cgi?id=645355
-rw-r--r--src/ui/frames.c93
-rw-r--r--src/ui/frames.h3
2 files changed, 95 insertions, 1 deletions
diff --git a/src/ui/frames.c b/src/ui/frames.c
index db189f03..518a46b8 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -23,6 +23,7 @@
#include <config.h>
#include <math.h>
+#include <string.h>
#include "boxes.h"
#include "frames.h"
#include "util.h"
@@ -185,6 +186,75 @@ 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);
+ }
+
+ if (theme_name)
+ 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)
{
@@ -200,6 +270,9 @@ 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);
+
meta_prefs_add_listener (prefs_changed_callback, frames);
}
@@ -237,6 +310,9 @@ meta_frames_destroy (GtkWidget *widget)
}
g_slist_free (winlist);
+ g_object_unref (frames->normal_style);
+ g_hash_table_destroy (frames->style_variants);
+
GTK_WIDGET_CLASS (meta_frames_parent_class)->destroy (widget);
}
@@ -425,6 +501,8 @@ 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);
@@ -570,10 +648,23 @@ 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);
- frame->style = g_object_ref (gtk_widget_get_style_context (GTK_WIDGET (frames)));
+ 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));
}
void
diff --git a/src/ui/frames.h b/src/ui/frames.h
index 25f3d750..ec83cd44 100644
--- a/src/ui/frames.h
+++ b/src/ui/frames.h
@@ -97,6 +97,9 @@ struct _MetaFrames
guint tooltip_timeout;
MetaUIFrame *last_motion_frame;
+ GtkStyleContext *normal_style;
+ GHashTable *style_variants;
+
int expose_delay_count;
int invalidate_cache_timeout_id;