[metacity] libmetacity: add MetaCssProvider
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [metacity] libmetacity: add MetaCssProvider
- Date: Thu, 2 Jun 2016 21:38:13 +0000 (UTC)
commit 68e0b2e84e9834a807c250a419846549cc5cee8f
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Thu Jun 2 20:23:57 2016 +0300
libmetacity: add MetaCssProvider
Add MetaCssProvider that has same theme loading code as
GtkCssProvider. This is needed to create GTK+ theme reload
functionality in metacity-theme-viewer without restarting
application.
configure.ac | 7 +
libmetacity/Makefile.am | 2 +
libmetacity/meta-css-provider-private.h | 35 ++++
libmetacity/meta-css-provider.c | 311 +++++++++++++++++++++++++++++++
4 files changed, 355 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 16a4ad7..a8140ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,6 +97,13 @@ PKG_CHECK_MODULES([METACITY_THEME_VIEWER], [
])
dnl **************************************************************************
+dnl Get GTK+ data prefix, needed by libmetacity
+dnl **************************************************************************
+
+GTK_DATA_PREFIX=`$PKG_CONFIG --variable=prefix gtk+-3.0`
+AC_DEFINE_UNQUOTED([GTK_DATA_PREFIX], ["$GTK_DATA_PREFIX"], [GTK+ data prefix])
+
+dnl **************************************************************************
# Honor aclocal flags
AC_SUBST(ACLOCAL_AMFLAGS, "\${ACLOCAL_FLAGS}")
diff --git a/libmetacity/Makefile.am b/libmetacity/Makefile.am
index 4fd809e..e378fd0 100644
--- a/libmetacity/Makefile.am
+++ b/libmetacity/Makefile.am
@@ -13,6 +13,8 @@ libmetacity_la_SOURCES = \
meta-color-private.h \
meta-color-spec.c \
meta-color-spec-private.h \
+ meta-css-provider.c \
+ meta-css-provider-private.h \
meta-draw-op.c \
meta-draw-op-private.h \
meta-draw-spec.c \
diff --git a/libmetacity/meta-css-provider-private.h b/libmetacity/meta-css-provider-private.h
new file mode 100644
index 0000000..4a20b34
--- /dev/null
+++ b/libmetacity/meta-css-provider-private.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_CSS_PROVIDER_PRIVATE_H
+#define META_CSS_PROVIDER_PRIVATE_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define META_TYPE_CSS_PROVIDER meta_css_provider_get_type ()
+G_DECLARE_FINAL_TYPE (MetaCssProvider, meta_css_provider,
+ META, CSS_PROVIDER, GtkCssProvider)
+
+G_GNUC_INTERNAL
+GtkCssProvider *meta_css_provider_new (const gchar *name,
+ const gchar *variant);
+
+G_END_DECLS
+
+#endif
diff --git a/libmetacity/meta-css-provider.c b/libmetacity/meta-css-provider.c
new file mode 100644
index 0000000..544d934
--- /dev/null
+++ b/libmetacity/meta-css-provider.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2016 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "meta-css-provider-private.h"
+
+struct _MetaCssProvider
+{
+ GtkCssProvider parent;
+
+ gchar *name;
+ gchar *variant;
+
+ GResource *resource;
+};
+
+enum
+{
+ PROP_0,
+
+ PROP_NAME,
+ PROP_VARIANT,
+
+ LAST_PROP
+};
+
+static GParamSpec *properties[LAST_PROP] = { NULL };
+
+G_DEFINE_TYPE (MetaCssProvider, meta_css_provider, GTK_TYPE_CSS_PROVIDER)
+
+static gchar *
+get_theme_dir (void)
+{
+ const gchar *prefix;
+
+ prefix = g_getenv ("GTK_DATA_PREFIX");
+
+ if (prefix == NULL)
+ prefix = GTK_DATA_PREFIX;
+
+ return g_build_filename (prefix, "share", "themes", NULL);
+}
+
+static gint
+get_minor_version (void)
+{
+ if (GTK_MINOR_VERSION % 2)
+ return GTK_MINOR_VERSION + 1;
+
+ return GTK_MINOR_VERSION;
+}
+
+static gchar *
+find_theme_dir (const gchar *dir,
+ const gchar *subdir,
+ const gchar *name,
+ const gchar *variant)
+{
+ gchar *file;
+ gchar *base;
+ gchar *subsubdir;
+ gint i;
+ gchar *path;
+
+ if (variant)
+ file = g_strconcat ("gtk-", variant, ".css", NULL);
+ else
+ file = g_strdup ("gtk.css");
+
+ if (subdir)
+ base = g_build_filename (dir, subdir, name, NULL);
+ else
+ base = g_build_filename (dir, name, NULL);
+
+ for (i = get_minor_version (); i >= 0; i = i - 2)
+ {
+ if (i < 14)
+ i = 0;
+
+ subsubdir = g_strdup_printf ("gtk-3.%d", i);
+ path = g_build_filename (base, subsubdir, file, NULL);
+ g_free (subsubdir);
+
+ if (g_file_test (path, G_FILE_TEST_EXISTS))
+ break;
+
+ g_free (path);
+ path = NULL;
+ }
+
+ g_free (file);
+ g_free (base);
+
+ return path;
+}
+
+static gchar *
+find_theme (const gchar *name,
+ const gchar *variant)
+{
+ gchar *path;
+ const gchar *const *dirs;
+ gint i;
+ gchar *dir;
+
+ /* First look in the user's data directory */
+ path = find_theme_dir (g_get_user_data_dir (), "themes", name, variant);
+ if (path)
+ return path;
+
+ /* Next look in the user's home directory */
+ path = find_theme_dir (g_get_home_dir (), ".themes", name, variant);
+ if (path)
+ return path;
+
+ /* Look in system data directories */
+ dirs = g_get_system_data_dirs ();
+ for (i = 0; dirs[i]; i++)
+ {
+ path = find_theme_dir (dirs[i], "themes", name, variant);
+ if (path)
+ return path;
+ }
+
+ /* Finally, try in the default theme directory */
+ dir = get_theme_dir ();
+ path = find_theme_dir (dir, NULL, name, variant);
+ g_free (dir);
+
+ return path;
+}
+
+static gboolean
+load_builtin_theme (GtkCssProvider *provider,
+ const gchar *name,
+ const gchar *variant)
+{
+ gchar *path;
+
+ if (variant != NULL)
+ path = g_strdup_printf ("/org/gtk/libgtk/theme/%s/gtk-%s.css", name, variant);
+ else
+ path = g_strdup_printf ("/org/gtk/libgtk/theme/%s/gtk.css", name);
+
+ if (g_resources_get_info (path, 0, NULL, NULL, NULL))
+ {
+ gtk_css_provider_load_from_resource (provider, path);
+ g_free (path);
+
+ return TRUE;
+ }
+
+ g_free (path);
+
+ return FALSE;
+}
+
+static void
+provider_load_named (MetaCssProvider *provider,
+ const gchar *name,
+ const gchar *variant)
+{
+ GtkCssProvider *css_provider;
+ gchar *path;
+
+ if (name == NULL)
+ return;
+
+ css_provider = GTK_CSS_PROVIDER (provider);
+
+ if (load_builtin_theme (css_provider, name, variant))
+ return;
+
+ path = find_theme (name, variant);
+
+ if (path != NULL)
+ {
+ gchar *dir;
+ gchar *file;
+
+ dir = g_path_get_dirname (path);
+ file = g_build_filename (dir, "gtk.gresource", NULL);
+ g_free (dir);
+
+ provider->resource = g_resource_load (file, NULL);
+ g_free (file);
+
+ if (provider->resource != NULL)
+ g_resources_register (provider->resource);
+
+ gtk_css_provider_load_from_path (css_provider, path, NULL);
+ g_free (path);
+ }
+ else if (variant != NULL)
+ {
+ provider_load_named (provider, name, NULL);
+ }
+}
+
+static void
+meta_css_provider_constructed (GObject *object)
+{
+ MetaCssProvider *provider;
+
+ G_OBJECT_CLASS (meta_css_provider_parent_class)->constructed (object);
+
+ provider = META_CSS_PROVIDER (object);
+
+ provider_load_named (provider, provider->name, provider->variant);
+}
+
+static void
+meta_css_provider_finalize (GObject *object)
+{
+ MetaCssProvider *provider;
+
+ provider = META_CSS_PROVIDER (object);
+
+ if (provider->resource)
+ {
+ g_resources_unregister (provider->resource);
+ g_resource_unref (provider->resource);
+ provider->resource = NULL;
+ }
+
+ G_OBJECT_CLASS (meta_css_provider_parent_class)->finalize (object);
+}
+
+static void
+meta_css_provider_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MetaCssProvider *provider;
+
+ provider = META_CSS_PROVIDER (object);
+
+ switch (property_id)
+ {
+ case PROP_NAME:
+ provider->name = g_value_dup_string (value);
+ break;
+
+ case PROP_VARIANT:
+ provider->variant = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+meta_css_provider_class_init (MetaCssProviderClass *provider_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (provider_class);
+
+ object_class->constructed = meta_css_provider_constructed;
+ object_class->finalize = meta_css_provider_finalize;
+ object_class->set_property = meta_css_provider_set_property;
+
+ properties[PROP_NAME] =
+ g_param_spec_string ("name",
+ "GTK+ Theme Name",
+ "GTK+ Theme Name",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_VARIANT] =
+ g_param_spec_string ("variant",
+ "GTK+ Theme Variant",
+ "GTK+ Theme Variant",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+}
+
+static void
+meta_css_provider_init (MetaCssProvider *provider)
+{
+}
+
+GtkCssProvider *
+meta_css_provider_new (const gchar *name,
+ const gchar *variant)
+{
+ return g_object_new (META_TYPE_CSS_PROVIDER,
+ "name", name, "variant", variant,
+ NULL);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]