diff options
author | Victor Kareh <[email protected]> | 2019-05-21 13:55:53 -0400 |
---|---|---|
committer | Victor Kareh <[email protected]> | 2019-06-05 10:49:37 -0400 |
commit | b08c0e992141ffb321289fefe88200b2de3c9c72 (patch) | |
tree | f4d2fe25c0afe6d36714c3d01daef6364fb5b23a | |
parent | 22aca3fcb271f557a65d474bce4eb2a115dd09fb (diff) | |
download | marco-b08c0e992141ffb321289fefe88200b2de3c9c72.tar.bz2 marco-b08c0e992141ffb321289fefe88200b2de3c9c72.tar.xz |
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
upstream commit:
https://gitlab.gnome.org/GNOME/metacity/commit/04d8135f
-rw-r--r-- | src/ui/frames.c | 95 | ||||
-rw-r--r-- | src/ui/frames.h | 2 |
2 files changed, 93 insertions, 4 deletions
diff --git a/src/ui/frames.c b/src/ui/frames.c index 02613210..ebf46392 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -25,6 +25,7 @@ #include <config.h> #include <math.h> +#include <string.h> #include "boxes.h" #include "frames.h" #include "util.h" @@ -180,6 +181,74 @@ 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) { @@ -194,6 +263,8 @@ meta_frames_init (MetaFrames *frames) frames->invalidate_cache_timeout_id = 0; 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); } @@ -208,13 +279,13 @@ listify_func (gpointer key, gpointer value, gpointer data) } static void -meta_frames_destroy (GtkWidget *object) +meta_frames_destroy (GtkWidget *widget) { GSList *winlist; GSList *tmp; MetaFrames *frames; - frames = META_FRAMES (object); + frames = META_FRAMES (widget); clear_tip (frames); @@ -232,7 +303,10 @@ meta_frames_destroy (GtkWidget *object) } g_slist_free (winlist); - GTK_WIDGET_CLASS (meta_frames_parent_class)->destroy (object); + g_object_unref (frames->normal_style); + g_hash_table_destroy (frames->style_variants); + + GTK_WIDGET_CLASS (meta_frames_parent_class)->destroy (widget); } static void @@ -409,6 +483,7 @@ meta_frames_style_set (GtkWidget *widget, meta_frames_font_changed (frames); + update_style_contexts (frames); g_hash_table_foreach (frames->frames, reattach_style_func, frames); @@ -557,10 +632,22 @@ 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 6689cc1a..b27f3b11 100644 --- a/src/ui/frames.h +++ b/src/ui/frames.h @@ -99,6 +99,8 @@ struct _MetaFrames guint tooltip_timeout; MetaUIFrame *last_motion_frame; + GtkStyleContext *normal_style; + GHashTable *style_variants; int expose_delay_count; int invalidate_cache_timeout_id; |