[gnome-shell] Add functions to dynamically load/unload stylesheets
- From: Colin Walters <walters src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-shell] Add functions to dynamically load/unload stylesheets
- Date: Tue, 1 Dec 2009 20:01:18 +0000 (UTC)
commit b6cc9c7ff625dccf79d58e86a8cb77c82d2ebddd
Author: Colin Walters <walters verbum org>
Date: Sat Oct 24 13:10:15 2009 -0400
Add functions to dynamically load/unload stylesheets
For implementing extensions, we want the ability to add a stylesheet
dynamically, and unload it as well.
https://bugzilla.gnome.org/show_bug.cgi?id=599661
src/st/st-theme.c | 100 +++++++++++++++++++++++++++++++++++++++++++---------
src/st/st-theme.h | 4 ++
2 files changed, 86 insertions(+), 18 deletions(-)
---
diff --git a/src/st/st-theme.c b/src/st/st-theme.c
index 9447832..4134b75 100644
--- a/src/st/st-theme.c
+++ b/src/st/st-theme.c
@@ -44,6 +44,8 @@
#include <stdlib.h>
#include <string.h>
+#include <gio/gio.h>
+
#include "st-theme-node.h"
#include "st-theme-private.h"
@@ -68,6 +70,7 @@ struct _StTheme
char *application_stylesheet;
char *default_stylesheet;
char *theme_stylesheet;
+ GSList *custom_stylesheets;
GHashTable *stylesheets_by_filename;
GHashTable *filenames_by_stylesheet;
@@ -193,24 +196,19 @@ convert_rgba_RGBA (char *buf)
}
static CRStyleSheet *
-parse_stylesheet (const char *filename)
+parse_stylesheet (const char *filename,
+ GError **error)
{
enum CRStatus status;
char *contents;
gsize length;
- GError *error = NULL;
CRStyleSheet *stylesheet = NULL;
if (filename == NULL)
return NULL;
- if (!g_file_get_contents (filename, &contents ,&length, &error))
- {
- g_warning("Couldn't read stylesheet: %s", error->message);
- g_error_free (error);
-
- return NULL;
- }
+ if (!g_file_get_contents (filename, &contents, &length, error))
+ return NULL;
convert_rgba_RGBA (contents);
@@ -218,11 +216,14 @@ parse_stylesheet (const char *filename)
length,
CR_UTF_8,
&stylesheet);
+ g_free (contents);
if (status != CR_OK)
- g_warning ("Error parsing stylesheet '%s'", filename);
-
- g_free (contents);
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Error parsing stylesheet '%s'; errcode:%d", filename, status);
+ return NULL;
+ }
return stylesheet;
}
@@ -243,7 +244,8 @@ _st_theme_parse_declaration_list (const char *str)
}
#else /* LIBCROCO_VERSION_NUMBER >= 602 */
static CRStyleSheet *
-parse_stylesheet (const char *filename)
+parse_stylesheet (const char *filename,
+ GError **error)
{
enum CRStatus status;
CRStyleSheet *stylesheet;
@@ -257,7 +259,8 @@ parse_stylesheet (const char *filename)
if (status != CR_OK)
{
- g_warning ("Error parsing stylesheet '%s'", filename);
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Error parsing stylesheet '%s'; errcode:%d", filename, status);
return NULL;
}
@@ -272,6 +275,22 @@ _st_theme_parse_declaration_list (const char *str)
}
#endif /* LIBCROCO_VERSION_NUMBER < 602 */
+/* Just g_warning for now until we have something nicer to do */
+static CRStyleSheet *
+parse_stylesheet_nofail (const char *filename)
+{
+ GError *error = NULL;
+ CRStyleSheet *result;
+
+ result = parse_stylesheet (filename, &error);
+ if (error)
+ {
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
+ }
+ return result;
+}
+
static void
insert_stylesheet (StTheme *theme,
const char *filename,
@@ -289,6 +308,42 @@ insert_stylesheet (StTheme *theme,
g_hash_table_insert (theme->filenames_by_stylesheet, stylesheet, filename_copy);
}
+gboolean
+st_theme_load_stylesheet (StTheme *theme,
+ const char *path,
+ GError **error)
+{
+ CRStyleSheet *stylesheet;
+
+ stylesheet = parse_stylesheet (path, error);
+ if (!stylesheet)
+ return FALSE;
+
+ insert_stylesheet (theme, path, stylesheet);
+ theme->custom_stylesheets = g_slist_prepend (theme->custom_stylesheets, stylesheet);
+
+ return TRUE;
+}
+
+void
+st_theme_unload_stylesheet (StTheme *theme,
+ const char *path)
+{
+ CRStyleSheet *stylesheet;
+
+ stylesheet = g_hash_table_lookup (theme->stylesheets_by_filename, path);
+ if (!stylesheet)
+ return;
+
+ if (!g_slist_find (theme->custom_stylesheets, stylesheet))
+ return;
+
+ theme->custom_stylesheets = g_slist_remove (theme->custom_stylesheets, stylesheet);
+ g_hash_table_remove (theme->stylesheets_by_filename, path);
+ g_hash_table_remove (theme->filenames_by_stylesheet, stylesheet);
+ cr_stylesheet_unref (stylesheet);
+}
+
static GObject *
st_theme_constructor (GType type,
guint n_construct_properties,
@@ -305,9 +360,9 @@ st_theme_constructor (GType type,
construct_properties);
theme = ST_THEME (object);
- application_stylesheet = parse_stylesheet (theme->application_stylesheet);
- theme_stylesheet = parse_stylesheet (theme->theme_stylesheet);
- default_stylesheet = parse_stylesheet (theme->default_stylesheet);
+ application_stylesheet = parse_stylesheet_nofail (theme->application_stylesheet);
+ theme_stylesheet = parse_stylesheet_nofail (theme->theme_stylesheet);
+ default_stylesheet = parse_stylesheet_nofail (theme->default_stylesheet);
theme->cascade = cr_cascade_new (application_stylesheet,
theme_stylesheet,
@@ -328,6 +383,10 @@ st_theme_finalize (GObject * object)
{
StTheme *theme = ST_THEME (object);
+ g_slist_foreach (theme->custom_stylesheets, (GFunc) cr_stylesheet_unref, NULL);
+ g_slist_free (theme->custom_stylesheets);
+ theme->custom_stylesheets = NULL;
+
g_hash_table_destroy (theme->stylesheets_by_filename);
g_hash_table_destroy (theme->filenames_by_stylesheet);
@@ -559,6 +618,7 @@ id_add_sel_matches_style (CRAdditionalSel *a_add_sel,
}
/**
+ *additional_selector_matches_style:
*Evaluates if a given additional selector matches an style node.
* param a_add_sel the additional selector to consider.
* param a_node the style node to consider.
@@ -862,7 +922,7 @@ add_matched_properties (StTheme *a_this,
import_rule->url->stryng->str);
if (filename)
- import_rule->sheet = parse_stylesheet (filename);
+ import_rule->sheet = parse_stylesheet (filename, NULL);
if (import_rule->sheet)
{
@@ -980,6 +1040,7 @@ _st_theme_get_matched_properties (StTheme *theme,
enum CRStyleOrigin origin = 0;
CRStyleSheet *sheet = NULL;
GPtrArray *props = g_ptr_array_new ();
+ GSList *iter;
g_return_val_if_fail (ST_IS_THEME (theme), NULL);
g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL);
@@ -993,6 +1054,9 @@ _st_theme_get_matched_properties (StTheme *theme,
add_matched_properties (theme, sheet, node, props);
}
+ for (iter = theme->custom_stylesheets; iter; iter = iter->next)
+ add_matched_properties (theme, iter->data, node, props);
+
/* We count on a stable sort here so that later declarations come
* after earlier declarations */
g_ptr_array_sort (props, compare_declarations);
diff --git a/src/st/st-theme.h b/src/st/st-theme.h
index dcf567a..1a55b29 100644
--- a/src/st/st-theme.h
+++ b/src/st/st-theme.h
@@ -33,6 +33,10 @@ StTheme *st_theme_new (const char *application_stylesheet,
const char *theme_stylesheet,
const char *default_stylesheet);
+gboolean st_theme_load_stylesheet (StTheme *theme, const char *path, GError **error);
+
+void st_theme_unload_stylesheet (StTheme *theme, const char *path);
+
G_END_DECLS
#endif /* __ST_THEME_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]