theme: Build a StyleContext hierarchy that matches GTK+'s CSD

In order to pick up all theme information from GTK+, a single style
context is not enough; a style hierarchy that closely matches the widget
hierarchy by GTK+'s client-side decorations will allow this soon.

https://bugzilla.gnome.org/show_bug.cgi?id=741917
This commit is contained in:
Florian Müllner 2014-09-23 04:20:22 +02:00 committed by Jasper St. Pierre
parent 472f2a4b8e
commit 2db71e73b4
2 changed files with 83 additions and 24 deletions

View File

@ -684,6 +684,10 @@ typedef enum
typedef enum typedef enum
{ {
META_STYLE_ELEMENT_FRAME, META_STYLE_ELEMENT_FRAME,
META_STYLE_ELEMENT_TITLEBAR,
META_STYLE_ELEMENT_TITLE,
META_STYLE_ELEMENT_BUTTON,
META_STYLE_ELEMENT_IMAGE,
META_STYLE_ELEMENT_LAST META_STYLE_ELEMENT_LAST
} MetaStyleElement; } MetaStyleElement;

View File

@ -42,6 +42,7 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <math.h> #include <math.h>
#define GDK_COLOR_RGBA(color) \ #define GDK_COLOR_RGBA(color) \
@ -4999,44 +5000,98 @@ meta_theme_get_title_scale (MetaTheme *theme,
return style->layout->title_scale; return style->layout->title_scale;
} }
static GtkStyleContext *
create_style_context (GType widget_type,
GtkStyleContext *parent_style,
GtkCssProvider *provider,
const char *first_class,
...)
{
GtkStyleContext *style;
GtkWidgetPath *path;
const char *name;
va_list ap;
style = gtk_style_context_new ();
gtk_style_context_set_parent (style, parent_style);
if (parent_style)
path = gtk_widget_path_copy (gtk_style_context_get_path (parent_style));
else
path = gtk_widget_path_new ();
gtk_widget_path_append_type (path, widget_type);
va_start (ap, first_class);
for (name = first_class; name; name = va_arg (ap, const char *))
gtk_widget_path_iter_add_class (path, -1, name);
va_end (ap);
gtk_style_context_set_path (style, path);
gtk_widget_path_unref (path);
gtk_style_context_add_provider (style, GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
return style;
}
MetaStyleInfo * MetaStyleInfo *
meta_theme_create_style_info (GdkScreen *screen, meta_theme_create_style_info (GdkScreen *screen,
const gchar *variant) const gchar *variant)
{ {
GtkWidgetPath *path;
MetaStyleInfo *style_info; MetaStyleInfo *style_info;
GtkStyleContext *style; GtkCssProvider *provider;
char *theme_name; char *theme_name;
g_object_get (gtk_settings_get_for_screen (screen), g_object_get (gtk_settings_get_for_screen (screen),
"gtk-theme-name", &theme_name, "gtk-theme-name", &theme_name,
NULL); NULL);
if (theme_name && *theme_name)
provider = gtk_css_provider_get_named (theme_name, variant);
else
provider = gtk_css_provider_get_default ();
g_free (theme_name);
style_info = g_new0 (MetaStyleInfo, 1); style_info = g_new0 (MetaStyleInfo, 1);
style_info->refcount = 1; style_info->refcount = 1;
path = gtk_widget_path_new (); style_info->styles[META_STYLE_ELEMENT_FRAME] =
create_style_context (META_TYPE_FRAMES,
style_info->styles[META_STYLE_ELEMENT_FRAME] = style = gtk_style_context_new (); NULL,
gtk_widget_path_append_type (path, META_TYPE_FRAMES); provider,
gtk_widget_path_iter_add_class (path, -1, GTK_STYLE_CLASS_BACKGROUND); GTK_STYLE_CLASS_BACKGROUND,
gtk_widget_path_iter_add_class (path, -1, "window-frame"); "window-frame",
gtk_style_context_set_path (style, path); "ssd",
NULL);
gtk_widget_path_unref (path); style_info->styles[META_STYLE_ELEMENT_TITLEBAR] =
create_style_context (GTK_TYPE_HEADER_BAR,
if (theme_name && *theme_name) style_info->styles[META_STYLE_ELEMENT_FRAME],
{ provider,
GtkCssProvider *provider; GTK_STYLE_CLASS_TITLEBAR,
GTK_STYLE_CLASS_HORIZONTAL,
provider = gtk_css_provider_get_named (theme_name, variant); "default-decoration",
gtk_style_context_add_provider (style, "header-bar",
GTK_STYLE_PROVIDER (provider), NULL);
GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); style_info->styles[META_STYLE_ELEMENT_TITLE] =
} create_style_context (GTK_TYPE_LABEL,
style_info->styles[META_STYLE_ELEMENT_TITLEBAR],
g_free (theme_name); provider,
GTK_STYLE_CLASS_TITLE,
NULL);
style_info->styles[META_STYLE_ELEMENT_BUTTON] =
create_style_context (GTK_TYPE_BUTTON,
style_info->styles[META_STYLE_ELEMENT_TITLEBAR],
provider,
GTK_STYLE_CLASS_BUTTON,
"titlebutton",
NULL);
style_info->styles[META_STYLE_ELEMENT_IMAGE] =
create_style_context (GTK_TYPE_IMAGE,
style_info->styles[META_STYLE_ELEMENT_BUTTON],
provider,
NULL);
return style_info; return style_info;
} }