aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Claessens <xclaesse@gmail.com>2011-05-03 22:20:29 +0800
committerXavier Claessens <xclaesse@gmail.com>2011-05-03 22:34:22 +0800
commit752ff0ce87069fad6eaea4d9e6dff84d8a2cf55d (patch)
tree477977d29854c074de8d512f01f8bbc3d741087b
parentaf9137e60f178bcc5fe039c64ea5e7a762ffcc62 (diff)
downloadgsoc2013-empathy-752ff0ce87069fad6eaea4d9e6dff84d8a2cf55d.tar
gsoc2013-empathy-752ff0ce87069fad6eaea4d9e6dff84d8a2cf55d.tar.gz
gsoc2013-empathy-752ff0ce87069fad6eaea4d9e6dff84d8a2cf55d.tar.bz2
gsoc2013-empathy-752ff0ce87069fad6eaea4d9e6dff84d8a2cf55d.tar.lz
gsoc2013-empathy-752ff0ce87069fad6eaea4d9e6dff84d8a2cf55d.tar.xz
gsoc2013-empathy-752ff0ce87069fad6eaea4d9e6dff84d8a2cf55d.tar.zst
gsoc2013-empathy-752ff0ce87069fad6eaea4d9e6dff84d8a2cf55d.zip
ThemeManager: Make sure to emit theme-changed only once when the theme changed
Also avoid emiting the signal if it is just a variant change that can be applied on view.
-rw-r--r--libempathy-gtk/empathy-theme-manager.c89
1 files changed, 79 insertions, 10 deletions
diff --git a/libempathy-gtk/empathy-theme-manager.c b/libempathy-gtk/empathy-theme-manager.c
index 1a4f5ae47..0dcb40a70 100644
--- a/libempathy-gtk/empathy-theme-manager.c
+++ b/libempathy-gtk/empathy-theme-manager.c
@@ -54,6 +54,7 @@ typedef struct {
gchar *adium_path;
GtkSettings *settings;
GList *boxes_views;
+ guint emit_changed_idle;
} EmpathyThemeManagerPriv;
enum {
@@ -392,6 +393,51 @@ theme_manager_ensure_theme_exists (const gchar *name)
return FALSE;
}
+typedef enum {
+ THEME_TYPE_UNSET,
+ THEME_TYPE_IRC,
+ THEME_TYPE_BOXED,
+ THEME_TYPE_ADIUM,
+} ThemeType;
+
+static ThemeType
+theme_type (const gchar *name)
+{
+ if (name == NULL) {
+ return THEME_TYPE_UNSET;
+ } else if (!tp_strdiff (name, "classic")) {
+ return THEME_TYPE_IRC;
+ } else if (!tp_strdiff (name, "adium")) {
+ return THEME_TYPE_ADIUM;
+ } else {
+ return THEME_TYPE_BOXED;
+ }
+}
+
+static gboolean
+theme_manager_emit_changed_idle_cb (gpointer manager)
+{
+ EmpathyThemeManagerPriv *priv = GET_PRIV (manager);
+
+ g_signal_emit (manager, signals[THEME_CHANGED], 0, NULL);
+ priv->emit_changed_idle = 0;
+
+ return FALSE;
+}
+
+static void
+theme_manager_emit_changed (EmpathyThemeManager *manager)
+{
+ EmpathyThemeManagerPriv *priv = GET_PRIV (manager);
+
+ /* We emit the signal in idle callback to be sure we emit it only once
+ * in the case both the name and adium_path changed */
+ if (priv->emit_changed_idle == 0) {
+ priv->emit_changed_idle = g_idle_add (
+ theme_manager_emit_changed_idle_cb, manager);
+ }
+}
+
static void
theme_manager_notify_name_cb (GSettings *gsettings_chat,
const gchar *key,
@@ -400,25 +446,29 @@ theme_manager_notify_name_cb (GSettings *gsettings_chat,
EmpathyThemeManager *manager = EMPATHY_THEME_MANAGER (user_data);
EmpathyThemeManagerPriv *priv = GET_PRIV (manager);
gchar *name;
+ ThemeType old_type;
+ ThemeType new_type;
name = g_settings_get_string (gsettings_chat, key);
- if (!theme_manager_ensure_theme_exists (name) ||
- !tp_strdiff (priv->name, name)) {
- if (!priv->name) {
- priv->name = g_strdup ("classic");
- }
+ /* Fallback to classic theme if current setting does not exist */
+ if (!theme_manager_ensure_theme_exists (name)) {
+ g_free (name);
+ name = g_strdup ("classic");
+ }
+ /* If theme did not change, nothing to do */
+ if (!tp_strdiff (priv->name, name)) {
g_free (name);
return;
}
+ old_type = theme_type (priv->name);
g_free (priv->name);
priv->name = name;
+ new_type = theme_type (priv->name);
- if (!tp_strdiff (priv->name, "simple") ||
- !tp_strdiff (priv->name, "clean") ||
- !tp_strdiff (priv->name, "blue")) {
+ if (new_type == THEME_TYPE_BOXED) {
GList *l;
/* The theme changes to a boxed one, we can update boxed views */
@@ -428,7 +478,15 @@ theme_manager_notify_name_cb (GSettings *gsettings_chat,
}
}
- g_signal_emit (manager, signals[THEME_CHANGED], 0, NULL);
+ /* Do not emit theme-changed if theme type didn't change, or if it was
+ * unset (the manager is under construction). If theme changed from a
+ * boxed to another boxed, all view are updated in place. If theme
+ * changed from an adium to another adium, the signal will be emited
+ * from theme_manager_notify_adium_path_cb ()
+ */
+ if (old_type != new_type && old_type != THEME_TYPE_UNSET) {
+ theme_manager_emit_changed (manager);
+ }
}
static void
@@ -439,6 +497,7 @@ theme_manager_notify_adium_path_cb (GSettings *gsettings_chat,
EmpathyThemeManager *manager = EMPATHY_THEME_MANAGER (user_data);
EmpathyThemeManagerPriv *priv = GET_PRIV (manager);
gchar *adium_path = NULL;
+ gboolean was_set;
adium_path = g_settings_get_string (gsettings_chat, key);
@@ -447,10 +506,16 @@ theme_manager_notify_adium_path_cb (GSettings *gsettings_chat,
return;
}
+ was_set = (priv->adium_path != NULL);
+
g_free (priv->adium_path);
priv->adium_path = adium_path;
- g_signal_emit (manager, signals[THEME_CHANGED], 0, NULL);
+ /* Do not emit the signal if path was not set yet (the manager is under
+ * construction) */
+ if (was_set) {
+ theme_manager_emit_changed (manager);
+ }
}
static void
@@ -470,6 +535,10 @@ theme_manager_finalize (GObject *object)
}
g_list_free (priv->boxes_views);
+ if (priv->emit_changed_idle != 0) {
+ g_source_remove (priv->emit_changed_idle);
+ }
+
G_OBJECT_CLASS (empathy_theme_manager_parent_class)->finalize (object);
}