[libdazzle] shortcuts: add support for including external CSS resources
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libdazzle] shortcuts: add support for including external CSS resources
- Date: Fri, 16 Jun 2017 01:02:57 +0000 (UTC)
commit a8feaf6a659ca63c6800e3c9009b542d95319093
Author: Christian Hergert <chergert redhat com>
Date: Thu Jun 15 18:02:48 2017 -0700
shortcuts: add support for including external CSS resources
This can be handy for situations where we still rely on CSS for
@bindingset type stuff. This will be necessary to incremntally port
the VIM engine in Builder.
src/shortcuts/dzl-shortcut-manager.c | 22 ++++++-
src/shortcuts/dzl-shortcut-private.h | 2 +
src/shortcuts/dzl-shortcut-theme-load.c | 26 +++++++
src/shortcuts/dzl-shortcut-theme.c | 114 +++++++++++++++++++++++++++++++
src/shortcuts/dzl-shortcut-theme.h | 4 +
5 files changed, 166 insertions(+), 2 deletions(-)
---
diff --git a/src/shortcuts/dzl-shortcut-manager.c b/src/shortcuts/dzl-shortcut-manager.c
index 91e8b06..d8db57a 100644
--- a/src/shortcuts/dzl-shortcut-manager.c
+++ b/src/shortcuts/dzl-shortcut-manager.c
@@ -177,6 +177,7 @@ dzl_shortcut_manager_reload (DzlShortcutManager *self,
*/
theme_name = g_strdup (dzl_shortcut_theme_get_name (priv->theme));
parent_theme_name = g_strdup (dzl_shortcut_theme_get_parent_name (priv->theme));
+ _dzl_shortcut_theme_detach (priv->theme);
g_clear_object (&priv->theme);
}
@@ -282,10 +283,15 @@ dzl_shortcut_manager_finalize (GObject *object)
priv->root = NULL;
}
+ if (priv->theme != NULL)
+ {
+ _dzl_shortcut_theme_detach (priv->theme);
+ g_clear_object (&priv->theme);
+ }
+
g_clear_pointer (&priv->seen_entries, g_hash_table_unref);
g_clear_pointer (&priv->themes, g_ptr_array_unref);
g_clear_pointer (&priv->user_dir, g_free);
- g_clear_object (&priv->theme);
g_clear_object (&priv->internal_theme);
G_OBJECT_CLASS (dzl_shortcut_manager_parent_class)->finalize (object);
@@ -578,8 +584,20 @@ dzl_shortcut_manager_set_theme (DzlShortcutManager *self,
* could be transitioning between incorrect contexts.
*/
- if (g_set_object (&priv->theme, theme))
+ if (priv->theme != theme)
{
+ if (priv->theme != NULL)
+ {
+ _dzl_shortcut_theme_detach (priv->theme);
+ g_clear_object (&priv->theme);
+ }
+
+ if (theme != NULL)
+ {
+ priv->theme = g_object_ref (theme);
+ _dzl_shortcut_theme_attach (priv->theme);
+ }
+
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_THEME]);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_THEME_NAME]);
}
diff --git a/src/shortcuts/dzl-shortcut-private.h b/src/shortcuts/dzl-shortcut-private.h
index 837a91d..8f11f6c 100644
--- a/src/shortcuts/dzl-shortcut-private.h
+++ b/src/shortcuts/dzl-shortcut-private.h
@@ -103,6 +103,8 @@ gboolean _dzl_gtk_widget_activate_action (GtkWidget
GVariant *parameter);
GNode *_dzl_shortcut_manager_get_root (DzlShortcutManager *self);
DzlShortcutTheme *_dzl_shortcut_manager_get_internal_theme (DzlShortcutManager *self);
+void _dzl_shortcut_theme_attach (DzlShortcutTheme *self);
+void _dzl_shortcut_theme_detach (DzlShortcutTheme *self);
GtkTreeModel *_dzl_shortcut_theme_create_model (DzlShortcutTheme *self);
GHashTable *_dzl_shortcut_theme_get_contexts (DzlShortcutTheme *self);
void _dzl_shortcut_theme_set_manager (DzlShortcutTheme *self,
diff --git a/src/shortcuts/dzl-shortcut-theme-load.c b/src/shortcuts/dzl-shortcut-theme-load.c
index dc54f54..8b6e32e 100644
--- a/src/shortcuts/dzl-shortcut-theme-load.c
+++ b/src/shortcuts/dzl-shortcut-theme-load.c
@@ -544,6 +544,26 @@ theme_start_element (GMarkupParseContext *context,
load_state_add_action (state, name);
}
+ else if (g_strcmp0 (element_name, "resource") == 0)
+ {
+ const gchar *path = NULL;
+ g_autofree gchar *full_path = NULL;
+
+ if (!load_state_check_type (state, LOAD_STATE_THEME, error))
+ return;
+
+ if (!g_markup_collect_attributes (element_name, attr_names, attr_values, error,
+ G_MARKUP_COLLECT_STRING, "path", &path,
+ G_MARKUP_COLLECT_INVALID))
+ return;
+
+ g_assert (state->self != NULL);
+
+ if (!g_str_has_prefix (path, "resource://"))
+ path = full_path = g_strdup_printf ("resource://%s", path);
+
+ dzl_shortcut_theme_add_css_resource (state->self, path);
+ }
}
static void
@@ -562,6 +582,12 @@ theme_end_element (GMarkupParseContext *context,
if (!load_state_check_type (state, LOAD_STATE_THEME, error))
return;
}
+ else if (g_strcmp0 (element_name, "resource") == 0)
+ {
+ /* nothing to pop, but we want to propagate any errors */
+ load_state_check_type (state, LOAD_STATE_THEME, error);
+ return;
+ }
else if (g_strcmp0 (element_name, "property") == 0)
{
if (!load_state_check_type (state, LOAD_STATE_PROPERTY, error))
diff --git a/src/shortcuts/dzl-shortcut-theme.c b/src/shortcuts/dzl-shortcut-theme.c
index 80a30ee..fece545 100644
--- a/src/shortcuts/dzl-shortcut-theme.c
+++ b/src/shortcuts/dzl-shortcut-theme.c
@@ -18,6 +18,8 @@
#define G_LOG_DOMAIN "dzl-shortcut-theme"
+#include <string.h>
+
#include "shortcuts/dzl-shortcut-private.h"
#include "shortcuts/dzl-shortcut-chord.h"
#include "shortcuts/dzl-shortcut-theme.h"
@@ -43,6 +45,13 @@ typedef struct
GHashTable *contexts;
/*
+ * A list of additional CSS resources that should be ingreated with this
+ * theme so that everything is applied together. You might use this if
+ * some of your keytheme needs to use CSS keybinding resources.
+ */
+ GHashTable *resource_providers;
+
+ /*
* Commands and actions can be mapped from a context or directly from the
* theme for convenience (to avoid having to define them from every context).
*/
@@ -751,6 +760,22 @@ _dzl_shortcut_theme_merge (DzlShortcutTheme *self,
_dzl_shortcut_context_merge (base_context, context);
}
+ /* Merge any associated resources. */
+ if (layer_priv->resource_providers != NULL)
+ {
+ GHashTableIter iter;
+
+ if (priv->resource_providers == NULL)
+ priv->resource_providers = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
+
+ g_hash_table_iter_init (&iter, layer_priv->resource_providers);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ g_hash_table_iter_steal (&iter);
+ g_hash_table_insert (priv->resource_providers, key, value);
+ }
+ }
+
/*
* Copy our action and commands chords over. These are all const data, so no
* need to be tricky about stealing data or what data we are safe to
@@ -759,3 +784,92 @@ _dzl_shortcut_theme_merge (DzlShortcutTheme *self,
dzl_shortcut_chord_table_foreach (layer_priv->actions_table, copy_chord_to_table, priv->actions_table);
dzl_shortcut_chord_table_foreach (layer_priv->commands_table, copy_chord_to_table, priv->commands_table);
}
+
+void
+dzl_shortcut_theme_add_css_resource (DzlShortcutTheme *self,
+ const gchar *path)
+{
+ DzlShortcutThemePrivate *priv = dzl_shortcut_theme_get_instance_private (self);
+ g_autoptr(GtkCssProvider) provider = NULL;
+
+ g_return_if_fail (DZL_IS_SHORTCUT_THEME (self));
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (*path == '/' || g_str_has_prefix (path, "resource://"));
+
+ if (priv->resource_providers == NULL)
+ priv->resource_providers = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
+
+ path = g_intern_string (path);
+
+ provider = gtk_css_provider_new ();
+
+ if (g_str_has_prefix (path, "resource://"))
+ {
+ const gchar *adjpath = path + strlen ("resource://");
+
+ gtk_css_provider_load_from_resource (provider, adjpath);
+ g_hash_table_insert (priv->resource_providers, (gpointer)path, g_steal_pointer (&provider));
+ }
+ else
+ {
+ g_autoptr(GError) error = NULL;
+
+ if (!gtk_css_provider_load_from_path (provider, path, &error))
+ g_warning ("%s", error->message);
+ else
+ g_hash_table_insert (priv->resource_providers, (gpointer)path, g_steal_pointer (&provider));
+ }
+}
+
+void
+dzl_shortcut_theme_remove_css_resource (DzlShortcutTheme *self,
+ const gchar *path)
+{
+ DzlShortcutThemePrivate *priv = dzl_shortcut_theme_get_instance_private (self);
+
+ g_return_if_fail (DZL_IS_SHORTCUT_THEME (self));
+ g_return_if_fail (path != NULL);
+
+ if (priv->resource_providers != NULL)
+ g_hash_table_remove (priv->resource_providers, g_intern_string (path));
+}
+
+void
+_dzl_shortcut_theme_attach (DzlShortcutTheme *self)
+{
+ DzlShortcutThemePrivate *priv = dzl_shortcut_theme_get_instance_private (self);
+
+ g_return_if_fail (DZL_IS_SHORTCUT_THEME (self));
+
+ if (priv->resource_providers != NULL)
+ {
+ GdkScreen *screen = gdk_screen_get_default ();
+ GtkStyleProvider *provider;
+ GHashTableIter iter;
+
+ g_hash_table_iter_init (&iter, priv->resource_providers);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&provider))
+ gtk_style_context_add_provider_for_screen (screen,
+ provider,
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ }
+}
+
+void
+_dzl_shortcut_theme_detach (DzlShortcutTheme *self)
+{
+ DzlShortcutThemePrivate *priv = dzl_shortcut_theme_get_instance_private (self);
+
+ g_return_if_fail (DZL_IS_SHORTCUT_THEME (self));
+
+ if (priv->resource_providers != NULL)
+ {
+ GdkScreen *screen = gdk_screen_get_default ();
+ GtkStyleProvider *provider;
+ GHashTableIter iter;
+
+ g_hash_table_iter_init (&iter, priv->resource_providers);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&provider))
+ gtk_style_context_remove_provider_for_screen (screen, provider);
+ }
+}
diff --git a/src/shortcuts/dzl-shortcut-theme.h b/src/shortcuts/dzl-shortcut-theme.h
index f869fee..25206eb 100644
--- a/src/shortcuts/dzl-shortcut-theme.h
+++ b/src/shortcuts/dzl-shortcut-theme.h
@@ -101,6 +101,10 @@ gboolean dzl_shortcut_theme_save_to_path (DzlShortcutThe
const gchar *path,
GCancellable *cancellable,
GError **error);
+void dzl_shortcut_theme_add_css_resource (DzlShortcutTheme *self,
+ const gchar *path);
+void dzl_shortcut_theme_remove_css_resource (DzlShortcutTheme *self,
+ const gchar *path);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]