diff options
-rw-r--r-- | libmetacity/meta-style-info-private.h | 26 | ||||
-rw-r--r-- | libmetacity/meta-style-info.c | 267 | ||||
-rw-r--r-- | libmetacity/meta-theme-gtk.c | 18 | ||||
-rw-r--r-- | libmetacity/meta-theme-metacity.c | 24 | ||||
-rw-r--r-- | libmetacity/meta-theme.c | 61 |
5 files changed, 270 insertions, 126 deletions
diff --git a/libmetacity/meta-style-info-private.h b/libmetacity/meta-style-info-private.h index 7f4a7b08..dfdcff71 100644 --- a/libmetacity/meta-style-info-private.h +++ b/libmetacity/meta-style-info-private.h @@ -1,5 +1,4 @@ /* - * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2016 Alberts Muktupāvels * * This program is free software: you can redistribute it and/or modify @@ -34,27 +33,22 @@ typedef enum META_STYLE_ELEMENT_LAST } MetaStyleElement; -typedef struct -{ - int refcount; - - GtkStyleContext *styles[META_STYLE_ELEMENT_LAST]; -} MetaStyleInfo; - -G_GNUC_INTERNAL -MetaStyleInfo *meta_style_info_new (const gchar *theme_name, - const gchar *variant, - gboolean composited); +#define META_TYPE_STYLE_INFO meta_style_info_get_type () +G_DECLARE_FINAL_TYPE (MetaStyleInfo, meta_style_info, META, STYLE_INFO, GObject) G_GNUC_INTERNAL -MetaStyleInfo *meta_style_info_ref (MetaStyleInfo *style_info); +MetaStyleInfo *meta_style_info_new (const gchar *gtk_theme_name, + const gchar *gtk_theme_variant, + gboolean composited, + gint window_scale); G_GNUC_INTERNAL -void meta_style_info_unref (MetaStyleInfo *style_info); +GtkStyleContext *meta_style_info_get_style (MetaStyleInfo *style_info, + MetaStyleElement element); G_GNUC_INTERNAL -void meta_style_info_set_flags (MetaStyleInfo *style_info, - MetaFrameFlags flags); +void meta_style_info_set_flags (MetaStyleInfo *style_info, + MetaFrameFlags flags); G_END_DECLS diff --git a/libmetacity/meta-style-info.c b/libmetacity/meta-style-info.c index d4af8730..1b0777dd 100644 --- a/libmetacity/meta-style-info.c +++ b/libmetacity/meta-style-info.c @@ -1,5 +1,4 @@ /* - * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2016 Alberts Muktupāvels * * This program is free software: you can redistribute it and/or modify @@ -17,11 +16,42 @@ */ #include "config.h" - +#include "meta-css-provider-private.h" #include "meta-frame-enums.h" #include "meta-style-info-private.h" #include "meta-theme-impl-private.h" +struct _MetaStyleInfo +{ + GObject parent; + + gchar *gtk_theme_name; + gchar *gtk_theme_variant; + gboolean composited; + gint window_scale; + + GtkCssProvider *theme_provider; + GtkCssProvider *user_provider; + + GtkStyleContext *styles[META_STYLE_ELEMENT_LAST]; +}; + +enum +{ + PROP_0, + + PROP_GTK_THEME_NAME, + PROP_GTK_THEME_VARIANT, + PROP_COMPOSITED, + PROP_WINDOW_SCALE, + + LAST_PROP +}; + +static GParamSpec *properties[LAST_PROP] = { NULL }; + +G_DEFINE_TYPE (MetaStyleInfo, meta_style_info, G_TYPE_OBJECT) + static void add_toplevel_class (GtkStyleContext *style, const gchar *class_name) @@ -57,16 +87,17 @@ remove_toplevel_class (GtkStyleContext *style, } static GtkStyleContext * -create_style_context (GtkStyleContext *parent, - GtkCssProvider *provider, - const char *object_name, - const char *first_class, +create_style_context (MetaStyleInfo *style_info, + GtkStyleContext *parent, + const gchar *object_name, + const gchar *first_class, ...) { GtkWidgetPath *path; GtkStyleContext *context; - const char *name; + const gchar *name; va_list ap; + GtkStyleProvider *provider; if (parent) path = gtk_widget_path_copy (gtk_style_context_get_path (parent)); @@ -77,111 +108,245 @@ create_style_context (GtkStyleContext *parent, gtk_widget_path_iter_set_object_name (path, -1, object_name); va_start (ap, first_class); - for (name = first_class; name; name = va_arg (ap, const char *)) + for (name = first_class; name; name = va_arg (ap, const gchar *)) gtk_widget_path_iter_add_class (path, -1, name); va_end (ap); context = gtk_style_context_new (); gtk_style_context_set_path (context, path); gtk_style_context_set_parent (context, parent); - gtk_style_context_set_scale (context, get_window_scaling_factor ()); + gtk_style_context_set_scale (context, style_info->window_scale); gtk_widget_path_unref (path); - gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), + provider = GTK_STYLE_PROVIDER (style_info->theme_provider); + gtk_style_context_add_provider (context, provider, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); + provider = GTK_STYLE_PROVIDER (style_info->user_provider); + gtk_style_context_add_provider (context, provider, + GTK_STYLE_PROVIDER_PRIORITY_USER); + return context; } -MetaStyleInfo * -meta_style_info_new (const gchar *theme_name, - const gchar *variant, - gboolean composited) +static void +load_user_provider (GtkCssProvider *provider) +{ + gchar *path; + + path = g_build_filename (g_get_user_config_dir (), + "gtk-3.0", "gtk.css", + NULL); + + if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) + gtk_css_provider_load_from_path (provider, path, NULL); + + g_free (path); +} + +static void +meta_style_info_constructed (GObject *object) { MetaStyleInfo *style_info; - GtkCssProvider *provider; - if (theme_name && *theme_name) - provider = gtk_css_provider_get_named (theme_name, variant); - else - provider = gtk_css_provider_get_default (); + G_OBJECT_CLASS (meta_style_info_parent_class)->constructed (object); + + style_info = META_STYLE_INFO (object); - style_info = g_new0 (MetaStyleInfo, 1); - style_info->refcount = 1; + style_info->theme_provider = meta_css_provider_new (style_info->gtk_theme_name, + style_info->gtk_theme_variant); + + style_info->user_provider = gtk_css_provider_new (); + load_user_provider (style_info->user_provider); style_info->styles[META_STYLE_ELEMENT_WINDOW] = - create_style_context (NULL, - provider, + create_style_context (style_info, + NULL, "window", GTK_STYLE_CLASS_BACKGROUND, - composited == TRUE ? "ssd" : "solid-csd", + style_info->composited == TRUE ? "ssd" : "solid-csd", NULL); + style_info->styles[META_STYLE_ELEMENT_DECORATION] = - create_style_context (style_info->styles[META_STYLE_ELEMENT_WINDOW], - provider, + create_style_context (style_info, + style_info->styles[META_STYLE_ELEMENT_WINDOW], "decoration", NULL); + style_info->styles[META_STYLE_ELEMENT_TITLEBAR] = - create_style_context (style_info->styles[META_STYLE_ELEMENT_DECORATION], - provider, + create_style_context (style_info, + style_info->styles[META_STYLE_ELEMENT_DECORATION], "headerbar", GTK_STYLE_CLASS_TITLEBAR, GTK_STYLE_CLASS_HORIZONTAL, "default-decoration", NULL); + style_info->styles[META_STYLE_ELEMENT_TITLE] = - create_style_context (style_info->styles[META_STYLE_ELEMENT_TITLEBAR], - provider, + create_style_context (style_info, + style_info->styles[META_STYLE_ELEMENT_TITLEBAR], "label", GTK_STYLE_CLASS_TITLE, NULL); + style_info->styles[META_STYLE_ELEMENT_BUTTON] = - create_style_context (style_info->styles[META_STYLE_ELEMENT_TITLEBAR], - provider, + create_style_context (style_info, + style_info->styles[META_STYLE_ELEMENT_TITLEBAR], "button", "titlebutton", NULL); + style_info->styles[META_STYLE_ELEMENT_IMAGE] = - create_style_context (style_info->styles[META_STYLE_ELEMENT_BUTTON], - provider, + create_style_context (style_info, + style_info->styles[META_STYLE_ELEMENT_BUTTON], "image", NULL); +} + +static void +meta_style_info_dispose (GObject *object) +{ + MetaStyleInfo *style_info; + gint i; + + style_info = META_STYLE_INFO (object); + + g_clear_object (&style_info->theme_provider); + g_clear_object (&style_info->user_provider); - return style_info; + for (i = 0; i < META_STYLE_ELEMENT_LAST; i++) + g_clear_object (&style_info->styles[i]); + + G_OBJECT_CLASS (meta_style_info_parent_class)->dispose (object); } -MetaStyleInfo * -meta_style_info_ref (MetaStyleInfo *style_info) +static void +meta_style_info_finalize (GObject *object) { - g_return_val_if_fail (style_info != NULL, NULL); - g_return_val_if_fail (style_info->refcount > 0, NULL); + MetaStyleInfo *style_info; - g_atomic_int_inc ((volatile int *)&style_info->refcount); - return style_info; + style_info = META_STYLE_INFO (object); + + g_free (style_info->gtk_theme_name); + g_free (style_info->gtk_theme_variant); + + G_OBJECT_CLASS (meta_style_info_parent_class)->finalize (object); } -void -meta_style_info_unref (MetaStyleInfo *style_info) +static void +meta_style_info_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - g_return_if_fail (style_info != NULL); - g_return_if_fail (style_info->refcount > 0); + MetaStyleInfo *style_info; - if (g_atomic_int_dec_and_test ((volatile int *)&style_info->refcount)) + style_info = META_STYLE_INFO (object); + + switch (property_id) { - int i; - for (i = 0; i < META_STYLE_ELEMENT_LAST; i++) - g_object_unref (style_info->styles[i]); - g_free (style_info); + case PROP_GTK_THEME_NAME: + style_info->gtk_theme_name = g_value_dup_string (value); + break; + + case PROP_GTK_THEME_VARIANT: + style_info->gtk_theme_variant = g_value_dup_string (value); + break; + + case PROP_COMPOSITED: + style_info->composited = g_value_get_boolean (value); + break; + + case PROP_WINDOW_SCALE: + style_info->window_scale = g_value_get_int (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; } } +static void +meta_style_info_class_init (MetaStyleInfoClass *style_info_class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (style_info_class); + + object_class->constructed = meta_style_info_constructed; + object_class->dispose = meta_style_info_dispose; + object_class->finalize = meta_style_info_finalize; + object_class->set_property = meta_style_info_set_property; + + properties[PROP_GTK_THEME_NAME] = + g_param_spec_string ("gtk-theme-name", + "GTK+ Theme Name", + "GTK+ Theme Name", + "Adwaita", + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_GTK_THEME_VARIANT] = + g_param_spec_string ("gtk-theme-variant", + "GTK+ Theme Variant", + "GTK+ Theme Variant", + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_COMPOSITED] = + g_param_spec_boolean ("composited", + "Composited", + "Composited", + TRUE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_WINDOW_SCALE] = + g_param_spec_int ("window-scale", + "Window Scaling Factor", + "Window Scaling Factor", + 1, G_MAXINT, 1, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, LAST_PROP, properties); +} + +static void +meta_style_info_init (MetaStyleInfo *style_info) +{ +} + +MetaStyleInfo * +meta_style_info_new (const gchar *gtk_theme_name, + const gchar *gtk_theme_variant, + gboolean composited, + gint window_scale) +{ + return g_object_new (META_TYPE_STYLE_INFO, + "gtk-theme-name", gtk_theme_name, + "gtk-theme-variant", gtk_theme_variant, + "composited", composited, + "window-scale", window_scale, + NULL); +} + +GtkStyleContext * +meta_style_info_get_style (MetaStyleInfo *style_info, + MetaStyleElement element) +{ + return style_info->styles[element]; +} + void meta_style_info_set_flags (MetaStyleInfo *style_info, MetaFrameFlags flags) { GtkStyleContext *style; gboolean backdrop; - int i; + gint i; backdrop = !(flags & META_FRAME_HAS_FOCUS); if (flags & META_FRAME_IS_FLASHING) diff --git a/libmetacity/meta-theme-gtk.c b/libmetacity/meta-theme-gtk.c index 21f093e0..4b2d9565 100644 --- a/libmetacity/meta-theme-gtk.c +++ b/libmetacity/meta-theme-gtk.c @@ -178,7 +178,7 @@ frame_layout_sync_with_style (MetaFrameLayout *layout, meta_style_info_set_flags (style_info, flags); - style = style_info->styles[META_STYLE_ELEMENT_DECORATION]; + style = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_DECORATION); get_padding_and_border (style, &layout->gtk.frame_border); scale_border (&layout->gtk.frame_border, layout->title_scale); @@ -236,16 +236,16 @@ frame_layout_sync_with_style (MetaFrameLayout *layout, if (!layout->has_title && layout->hide_buttons) return; /* border-only - be done */ - style = style_info->styles[META_STYLE_ELEMENT_TITLEBAR]; + style = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_TITLEBAR); get_min_size (style, &layout->gtk.titlebar_min_size); get_padding_and_border (style, &layout->gtk.titlebar_border); scale_border (&layout->gtk.titlebar_border, layout->title_scale); - style = style_info->styles[META_STYLE_ELEMENT_TITLE]; + style = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_TITLE); get_margin (style, &layout->gtk.title_margin); scale_border (&layout->gtk.title_margin, layout->title_scale); - style = style_info->styles[META_STYLE_ELEMENT_BUTTON]; + style = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_BUTTON); get_min_size (style, &layout->gtk.button_min_size); get_padding_and_border (style, &layout->button_border); scale_border (&layout->button_border, layout->title_scale); @@ -253,7 +253,7 @@ frame_layout_sync_with_style (MetaFrameLayout *layout, get_margin (style, &layout->gtk.button_margin); scale_border (&layout->gtk.button_margin, layout->title_scale); - style = style_info->styles[META_STYLE_ELEMENT_IMAGE]; + style = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_IMAGE); get_min_size (style, &requisition); get_padding_and_border (style, &border); scale_border (&border, layout->title_scale); @@ -845,7 +845,7 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, meta_style_info_set_flags (style_info, flags); - context = style_info->styles[META_STYLE_ELEMENT_DECORATION]; + context = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_DECORATION); gtk_render_background (context, cr, visible_rect.x, visible_rect.y, visible_rect.width, visible_rect.height); @@ -861,7 +861,7 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, titlebar_rect.width = visible_rect.width - (borders->visible.left + borders->visible.right) / scale; titlebar_rect.height = (borders->visible.top / scale) - style->layout->gtk.frame_border.top; - context = style_info->styles[META_STYLE_ELEMENT_TITLEBAR]; + context = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_TITLEBAR); gtk_render_background (context, cr, titlebar_rect.x, titlebar_rect.y, titlebar_rect.width, titlebar_rect.height); @@ -891,11 +891,11 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, else if (x + text_width > (fgeom->title_rect.x + fgeom->title_rect.width) / scale) x = (fgeom->title_rect.x + fgeom->title_rect.width) / scale - text_width; - context = style_info->styles[META_STYLE_ELEMENT_TITLE]; + context = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_TITLE); gtk_render_layout (context, cr, x, y, title_layout); } - context = style_info->styles[META_STYLE_ELEMENT_BUTTON]; + context = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_BUTTON); state = gtk_style_context_get_state (context); for (button_type = META_BUTTON_TYPE_CLOSE; button_type < META_BUTTON_TYPE_LAST; button_type++) { diff --git a/libmetacity/meta-theme-metacity.c b/libmetacity/meta-theme-metacity.c index 72a2ac54..35c3791f 100644 --- a/libmetacity/meta-theme-metacity.c +++ b/libmetacity/meta-theme-metacity.c @@ -5452,11 +5452,13 @@ meta_theme_metacity_draw_frame (MetaThemeImpl *impl, if (op_list) { - meta_draw_op_list_draw_with_style (op_list, - style_info->styles[META_STYLE_ELEMENT_WINDOW], - cr, - &draw_info, - rect); + GtkStyleContext *context; + + context = meta_style_info_get_style (style_info, + META_STYLE_ELEMENT_WINDOW); + + meta_draw_op_list_draw_with_style (op_list, context, cr, + &draw_info, rect); } } @@ -5492,11 +5494,13 @@ meta_theme_metacity_draw_frame (MetaThemeImpl *impl, if (gdk_cairo_get_clip_rectangle (cr, NULL)) { - meta_draw_op_list_draw_with_style (op_list, - style_info->styles[META_STYLE_ELEMENT_WINDOW], - cr, - &draw_info, - rect); + GtkStyleContext *context; + + context = meta_style_info_get_style (style_info, + META_STYLE_ELEMENT_WINDOW); + + meta_draw_op_list_draw_with_style (op_list, context, cr, + &draw_info, rect); } cairo_restore (cr); } diff --git a/libmetacity/meta-theme.c b/libmetacity/meta-theme.c index 30f76f24..61f3c3e7 100644 --- a/libmetacity/meta-theme.c +++ b/libmetacity/meta-theme.c @@ -39,7 +39,7 @@ struct _MetaTheme PangoFontDescription *titlebar_font; - gchar *theme_name; + gchar *gtk_theme_name; GHashTable *variants; }; @@ -52,7 +52,7 @@ enum LAST_PROP }; -static GParamSpec *theme_properties[LAST_PROP] = { NULL }; +static GParamSpec *properties[LAST_PROP] = { NULL }; G_DEFINE_TYPE (MetaTheme, meta_theme, G_TYPE_OBJECT) @@ -60,19 +60,24 @@ static MetaStyleInfo * meta_theme_get_style_info (MetaTheme *theme, const gchar *variant) { + const gchar *key; MetaStyleInfo *style_info; + key = variant; if (variant == NULL) - variant = "default"; + key = "default"; - style_info = g_hash_table_lookup (theme->variants, variant); + style_info = g_hash_table_lookup (theme->variants, key); if (style_info == NULL) { - style_info = meta_style_info_new (theme->theme_name, variant, - theme->composited); + gint window_scale; - g_hash_table_insert (theme->variants, g_strdup (variant), style_info); + window_scale = get_window_scaling_factor (); + style_info = meta_style_info_new (theme->gtk_theme_name, variant, + theme->composited, window_scale); + + g_hash_table_insert (theme->variants, g_strdup (key), style_info); } return style_info; @@ -122,34 +127,12 @@ meta_theme_finalize (GObject *object) theme->titlebar_font = NULL; } - g_free (theme->theme_name); + g_free (theme->gtk_theme_name); G_OBJECT_CLASS (meta_theme_parent_class)->finalize (object); } static void -meta_theme_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - MetaTheme *theme; - - theme = META_THEME (object); - - switch (property_id) - { - case PROP_TYPE: - g_value_set_enum (value, theme->type); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void meta_theme_set_property (GObject *object, guint property_id, const GValue *value, @@ -174,14 +157,13 @@ meta_theme_set_property (GObject *object, static void meta_theme_install_properties (GObjectClass *object_class) { - theme_properties[PROP_TYPE] = + properties[PROP_TYPE] = g_param_spec_enum ("type", "type", "type", META_TYPE_THEME_TYPE, META_THEME_TYPE_GTK, G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties (object_class, LAST_PROP, - theme_properties); + g_object_class_install_properties (object_class, LAST_PROP, properties); } static void @@ -194,7 +176,6 @@ meta_theme_class_init (MetaThemeClass *theme_class) object_class->constructed = meta_theme_constructed; object_class->dispose = meta_theme_dispose; object_class->finalize = meta_theme_finalize; - object_class->get_property = meta_theme_get_property; object_class->set_property = meta_theme_set_property; meta_theme_install_properties (object_class); @@ -205,8 +186,8 @@ meta_theme_init (MetaTheme *theme) { theme->composited = TRUE; - theme->variants = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, - (GDestroyNotify) meta_style_info_unref); + theme->variants = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_object_unref); } /** @@ -233,11 +214,11 @@ meta_theme_load (MetaTheme *theme, const gchar *name, GError **error) { - g_free (theme->theme_name); + g_free (theme->gtk_theme_name); if (theme->type == META_THEME_TYPE_GTK) { - theme->theme_name = g_strdup (name); + theme->gtk_theme_name = g_strdup (name); } else if (theme->type == META_THEME_TYPE_METACITY) { @@ -245,7 +226,7 @@ meta_theme_load (MetaTheme *theme, settings = gtk_settings_get_default (); - g_object_get (settings, "gtk-theme-name", &theme->theme_name, NULL); + g_object_get (settings, "gtk-theme-name", &theme->gtk_theme_name, NULL); } else { @@ -382,7 +363,7 @@ meta_theme_create_font_desc (MetaTheme *theme, PangoFontDescription *font_desc; style_info = meta_theme_get_style_info (theme, variant); - context = style_info->styles[META_STYLE_ELEMENT_TITLE]; + context = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_TITLE); gtk_style_context_save (context); gtk_style_context_set_state (context, GTK_STATE_FLAG_NORMAL); |