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
This commit is contained in:
parent
368d484dee
commit
b6cc9c7ff6
@ -44,6 +44,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
#include "st-theme-node.h"
|
#include "st-theme-node.h"
|
||||||
#include "st-theme-private.h"
|
#include "st-theme-private.h"
|
||||||
|
|
||||||
@ -68,6 +70,7 @@ struct _StTheme
|
|||||||
char *application_stylesheet;
|
char *application_stylesheet;
|
||||||
char *default_stylesheet;
|
char *default_stylesheet;
|
||||||
char *theme_stylesheet;
|
char *theme_stylesheet;
|
||||||
|
GSList *custom_stylesheets;
|
||||||
|
|
||||||
GHashTable *stylesheets_by_filename;
|
GHashTable *stylesheets_by_filename;
|
||||||
GHashTable *filenames_by_stylesheet;
|
GHashTable *filenames_by_stylesheet;
|
||||||
@ -193,24 +196,19 @@ convert_rgba_RGBA (char *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static CRStyleSheet *
|
static CRStyleSheet *
|
||||||
parse_stylesheet (const char *filename)
|
parse_stylesheet (const char *filename,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
enum CRStatus status;
|
enum CRStatus status;
|
||||||
char *contents;
|
char *contents;
|
||||||
gsize length;
|
gsize length;
|
||||||
GError *error = NULL;
|
|
||||||
CRStyleSheet *stylesheet = NULL;
|
CRStyleSheet *stylesheet = NULL;
|
||||||
|
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!g_file_get_contents (filename, &contents ,&length, &error))
|
if (!g_file_get_contents (filename, &contents, &length, error))
|
||||||
{
|
|
||||||
g_warning("Couldn't read stylesheet: %s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
convert_rgba_RGBA (contents);
|
convert_rgba_RGBA (contents);
|
||||||
|
|
||||||
@ -218,11 +216,14 @@ parse_stylesheet (const char *filename)
|
|||||||
length,
|
length,
|
||||||
CR_UTF_8,
|
CR_UTF_8,
|
||||||
&stylesheet);
|
&stylesheet);
|
||||||
|
g_free (contents);
|
||||||
|
|
||||||
if (status != CR_OK)
|
if (status != CR_OK)
|
||||||
g_warning ("Error parsing stylesheet '%s'", filename);
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
g_free (contents);
|
"Error parsing stylesheet '%s'; errcode:%d", filename, status);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return stylesheet;
|
return stylesheet;
|
||||||
}
|
}
|
||||||
@ -243,7 +244,8 @@ _st_theme_parse_declaration_list (const char *str)
|
|||||||
}
|
}
|
||||||
#else /* LIBCROCO_VERSION_NUMBER >= 602 */
|
#else /* LIBCROCO_VERSION_NUMBER >= 602 */
|
||||||
static CRStyleSheet *
|
static CRStyleSheet *
|
||||||
parse_stylesheet (const char *filename)
|
parse_stylesheet (const char *filename,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
enum CRStatus status;
|
enum CRStatus status;
|
||||||
CRStyleSheet *stylesheet;
|
CRStyleSheet *stylesheet;
|
||||||
@ -257,7 +259,8 @@ parse_stylesheet (const char *filename)
|
|||||||
|
|
||||||
if (status != CR_OK)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +275,22 @@ _st_theme_parse_declaration_list (const char *str)
|
|||||||
}
|
}
|
||||||
#endif /* LIBCROCO_VERSION_NUMBER < 602 */
|
#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
|
static void
|
||||||
insert_stylesheet (StTheme *theme,
|
insert_stylesheet (StTheme *theme,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
@ -289,6 +308,42 @@ insert_stylesheet (StTheme *theme,
|
|||||||
g_hash_table_insert (theme->filenames_by_stylesheet, stylesheet, filename_copy);
|
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 *
|
static GObject *
|
||||||
st_theme_constructor (GType type,
|
st_theme_constructor (GType type,
|
||||||
guint n_construct_properties,
|
guint n_construct_properties,
|
||||||
@ -305,9 +360,9 @@ st_theme_constructor (GType type,
|
|||||||
construct_properties);
|
construct_properties);
|
||||||
theme = ST_THEME (object);
|
theme = ST_THEME (object);
|
||||||
|
|
||||||
application_stylesheet = parse_stylesheet (theme->application_stylesheet);
|
application_stylesheet = parse_stylesheet_nofail (theme->application_stylesheet);
|
||||||
theme_stylesheet = parse_stylesheet (theme->theme_stylesheet);
|
theme_stylesheet = parse_stylesheet_nofail (theme->theme_stylesheet);
|
||||||
default_stylesheet = parse_stylesheet (theme->default_stylesheet);
|
default_stylesheet = parse_stylesheet_nofail (theme->default_stylesheet);
|
||||||
|
|
||||||
theme->cascade = cr_cascade_new (application_stylesheet,
|
theme->cascade = cr_cascade_new (application_stylesheet,
|
||||||
theme_stylesheet,
|
theme_stylesheet,
|
||||||
@ -328,6 +383,10 @@ st_theme_finalize (GObject * object)
|
|||||||
{
|
{
|
||||||
StTheme *theme = ST_THEME (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->stylesheets_by_filename);
|
||||||
g_hash_table_destroy (theme->filenames_by_stylesheet);
|
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.
|
*Evaluates if a given additional selector matches an style node.
|
||||||
*@param a_add_sel the additional selector to consider.
|
*@param a_add_sel the additional selector to consider.
|
||||||
*@param a_node the style node 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);
|
import_rule->url->stryng->str);
|
||||||
|
|
||||||
if (filename)
|
if (filename)
|
||||||
import_rule->sheet = parse_stylesheet (filename);
|
import_rule->sheet = parse_stylesheet (filename, NULL);
|
||||||
|
|
||||||
if (import_rule->sheet)
|
if (import_rule->sheet)
|
||||||
{
|
{
|
||||||
@ -980,6 +1040,7 @@ _st_theme_get_matched_properties (StTheme *theme,
|
|||||||
enum CRStyleOrigin origin = 0;
|
enum CRStyleOrigin origin = 0;
|
||||||
CRStyleSheet *sheet = NULL;
|
CRStyleSheet *sheet = NULL;
|
||||||
GPtrArray *props = g_ptr_array_new ();
|
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 (theme), NULL);
|
||||||
g_return_val_if_fail (ST_IS_THEME_NODE (node), 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);
|
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
|
/* We count on a stable sort here so that later declarations come
|
||||||
* after earlier declarations */
|
* after earlier declarations */
|
||||||
g_ptr_array_sort (props, compare_declarations);
|
g_ptr_array_sort (props, compare_declarations);
|
||||||
|
@ -33,6 +33,10 @@ StTheme *st_theme_new (const char *application_stylesheet,
|
|||||||
const char *theme_stylesheet,
|
const char *theme_stylesheet,
|
||||||
const char *default_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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __ST_THEME_H__ */
|
#endif /* __ST_THEME_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user