From 761849e55ee1a6b6597e81f00dc20f7a8397e67f Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 4 Mar 2011 11:41:48 -0600 Subject: Signal handler for theme directories changing. --- libdbusmenu-gtk/client.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 50978ff..d3d0533 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -54,6 +54,7 @@ static void new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint po static void delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, DbusmenuGtkClient * gtkclient); static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, DbusmenuGtkClient * gtkclient); static void item_activate (DbusmenuClient * client, DbusmenuMenuitem * mi, guint timestamp, gpointer userdata); +static void theme_dir_changed (DbusmenuClient * client, GStrv theme_dirs, gpointer userdata); static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data); static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data); @@ -96,6 +97,7 @@ dbusmenu_gtkclient_init (DbusmenuGtkClient *self) /* TODO: I think these can be handled in the class... */ g_signal_connect(G_OBJECT(self), DBUSMENU_CLIENT_SIGNAL_NEW_MENUITEM, G_CALLBACK(new_menuitem), NULL); g_signal_connect(G_OBJECT(self), DBUSMENU_CLIENT_SIGNAL_ITEM_ACTIVATE, G_CALLBACK(item_activate), NULL); + g_signal_connect(G_OBJECT(self), DBUSMENU_CLIENT_SIGNAL_ICON_THEME_DIRS_CHANGED, G_CALLBACK(theme_dir_changed), NULL); return; } @@ -124,6 +126,16 @@ dbusmenu_gtkclient_finalize (GObject *object) return; } +/* Called when the theme directories are changed by the + server part of things. */ +static void +theme_dir_changed (DbusmenuClient * client, GStrv theme_dirs, gpointer userdata) +{ + + + return; +} + /* Structure for passing data to swap_agroup */ typedef struct _swap_agroup_t swap_agroup_t; struct _swap_agroup_t { -- cgit v1.2.3 From 3d56637921acae3410b1889ddc2f7dba16b46e80 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 4 Mar 2011 11:47:23 -0600 Subject: Making a private variable and making a lifecycle for it. --- libdbusmenu-gtk/client.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index d3d0533..b0355c9 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -38,6 +38,7 @@ License version 3 and version 2.1 along with this program. If not, see /* Private */ struct _DbusmenuGtkClientPrivate { + GStrv old_themedirs; GtkAccelGroup * agroup; }; @@ -55,6 +56,7 @@ static void delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, Dbusm static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, DbusmenuGtkClient * gtkclient); static void item_activate (DbusmenuClient * client, DbusmenuMenuitem * mi, guint timestamp, gpointer userdata); static void theme_dir_changed (DbusmenuClient * client, GStrv theme_dirs, gpointer userdata); +static void remove_theme_dirs (GtkIconTheme * theme, GStrv dirs); static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data); static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data); @@ -90,6 +92,7 @@ dbusmenu_gtkclient_init (DbusmenuGtkClient *self) DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(self); priv->agroup = NULL; + priv->old_themedirs = NULL; dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(self), DBUSMENU_CLIENT_TYPES_DEFAULT, new_item_normal); dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(self), DBUSMENU_CLIENT_TYPES_SEPARATOR, new_item_seperator); @@ -113,6 +116,12 @@ dbusmenu_gtkclient_dispose (GObject *object) priv->agroup = NULL; } + if (priv->old_themedirs) { + remove_theme_dirs(gtk_icon_theme_get_default(), priv->old_themedirs); + g_strfreev(priv->old_themedirs); + priv->old_themedirs = NULL; + } + G_OBJECT_CLASS (dbusmenu_gtkclient_parent_class)->dispose (object); return; } @@ -126,6 +135,14 @@ dbusmenu_gtkclient_finalize (GObject *object) return; } +/* Unregister this list of theme directories */ +static void +remove_theme_dirs (GtkIconTheme * theme, GStrv dirs) +{ + + return; +} + /* Called when the theme directories are changed by the server part of things. */ static void -- cgit v1.2.3 From 59336ca7d7d4706bbe122446f6a1179a12f9ba55 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 4 Mar 2011 12:04:43 -0600 Subject: Fleshing out the change functions, but it infact creates more functions. Whoa! --- libdbusmenu-gtk/client.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index b0355c9..c998517 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -42,6 +42,8 @@ struct _DbusmenuGtkClientPrivate { GtkAccelGroup * agroup; }; +GHashTable * theme_dir_db = NULL; + #define DBUSMENU_GTKCLIENT_GET_PRIVATE(o) (DBUSMENU_GTKCLIENT(o)->priv) #define USE_FALLBACK_PROP "use-fallback" @@ -135,10 +137,32 @@ dbusmenu_gtkclient_finalize (GObject *object) return; } +static void +theme_dir_ref (GtkIconTheme * theme, GHashTable * db, const gchar * dir) +{ + + return; +} + +static void +theme_dir_unref (GtkIconTheme * theme, GHashTable * db, const gchar * dir) +{ + + return; +} + /* Unregister this list of theme directories */ static void remove_theme_dirs (GtkIconTheme * theme, GStrv dirs) { + g_return_if_fail(GTK_ICON_THEME(theme)); + g_return_if_fail(dirs != NULL); + + int dir; + + for (dir = 0; dirs[dir] != NULL; dir++) { + theme_dir_unref(theme, theme_dir_db, dirs[dir]); + } return; } @@ -148,7 +172,28 @@ remove_theme_dirs (GtkIconTheme * theme, GStrv dirs) static void theme_dir_changed (DbusmenuClient * client, GStrv theme_dirs, gpointer userdata) { + DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(client); + GtkIconTheme * theme = gtk_icon_theme_get_default(); + + /* Ref the new directories */ + if (theme_dirs != NULL) { + int dir; + for (dir = 0; theme_dirs[dir] != NULL; dir++) { + theme_dir_ref(theme, theme_dir_db, theme_dirs[dir]); + } + } + /* Unref the old ones */ + if (priv->old_themedirs) { + remove_theme_dirs(theme, priv->old_themedirs); + g_strfreev(priv->old_themedirs); + priv->old_themedirs = NULL; + } + + /* Copy the new to the old */ + if (theme_dirs != NULL) { + priv->old_themedirs = g_strdupv(theme_dirs); + } return; } -- cgit v1.2.3 From 911ce51574b4771318d5af94a239a4d41e6001a3 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 4 Mar 2011 12:37:14 -0600 Subject: Build the theme directory database when we build objects --- libdbusmenu-gtk/client.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index c998517..88671f7 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -96,6 +96,22 @@ dbusmenu_gtkclient_init (DbusmenuGtkClient *self) priv->agroup = NULL; priv->old_themedirs = NULL; + /* We either build the theme db or we get a reference + to it. This way when all clients die the hashtable + will be free'd as well. */ + if (theme_dir_db == NULL) { + theme_dir_db = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + + /* NOTE: We're adding an extra ref here because there + is no way to clear the pointer when the hash table + dies, so it's safer to keep the hash table around + forever than not know if it's free'd or not. Patch + submitted to GLib. */ + g_hash_table_ref(theme_dir_db); + } else { + g_hash_table_ref(theme_dir_db); + } + dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(self), DBUSMENU_CLIENT_TYPES_DEFAULT, new_item_normal); dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(self), DBUSMENU_CLIENT_TYPES_SEPARATOR, new_item_seperator); @@ -124,6 +140,12 @@ dbusmenu_gtkclient_dispose (GObject *object) priv->old_themedirs = NULL; } + if (theme_dir_db != NULL) { + g_hash_table_unref(theme_dir_db); + } else { + g_assert_not_reached(); + } + G_OBJECT_CLASS (dbusmenu_gtkclient_parent_class)->dispose (object); return; } -- cgit v1.2.3 From 0108ac16f1db0c6e7cbc46e0f61c1267bdf607a3 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 4 Mar 2011 17:22:56 -0600 Subject: Stealing the code from indicator-application to ref and unref theme directories. --- libdbusmenu-gtk/client.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 88671f7..fd266df 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -159,16 +159,90 @@ dbusmenu_gtkclient_finalize (GObject *object) return; } +/* Add a theme directory to the table and the theme's list of available + themes to use. */ static void theme_dir_ref (GtkIconTheme * theme, GHashTable * db, const gchar * dir) { + g_return_if_fail(db != NULL); + g_return_if_fail(theme != NULL); + g_return_if_fail(dir != NULL); + + int count = 0; + if ((count = GPOINTER_TO_INT(g_hash_table_lookup(db, dir))) != 0) { + /* It exists so what we need to do is increase the ref + count of this dir. */ + count++; + } else { + /* It doesn't exist, so we need to add it to the table + and to the search path. */ + gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), dir); + g_debug("\tAppending search path: %s", dir); + count = 1; + } + + g_hash_table_insert(db, g_strdup(dir), GINT_TO_POINTER(count)); return; } +/* Unreference the theme directory, and if it's count goes to zero then + we need to remove it from the search path. */ static void theme_dir_unref (GtkIconTheme * theme, GHashTable * db, const gchar * dir) { + g_return_if_fail(db != NULL); + g_return_if_fail(theme != NULL); + g_return_if_fail(dir != NULL); + + /* Grab the count for this dir */ + int count = GPOINTER_TO_INT(g_hash_table_lookup(db, dir)); + + /* Is this a simple deprecation, if so, we can just lower the + number and move on. */ + if (count > 1) { + count--; + g_hash_table_insert(db, g_strdup(dir), GINT_TO_POINTER(count)); + return; + } + + /* Try to remove it from the hash table, this makes sure + that it existed */ + if (!g_hash_table_remove(db, dir)) { + g_warning("Unref'd a directory that wasn't in the theme dir hash table."); + return; + } + + gchar ** paths; + gint path_count; + + gtk_icon_theme_get_search_path(theme, &paths, &path_count); + + gint i; + gboolean found = FALSE; + for (i = 0; i < path_count; i++) { + if (found) { + /* If we've already found the right entry */ + paths[i - 1] = paths[i]; + } else { + /* We're still looking, is this the one? */ + if (!g_strcmp0(paths[i], dir)) { + found = TRUE; + /* We're freeing this here as it won't be captured by the + g_strfreev() below as it's out of the array. */ + g_free(paths[i]); + } + } + } + + /* If we found one we need to reset the path to + accomidate the changes */ + if (found) { + paths[path_count - 1] = NULL; /* Clear the last one */ + gtk_icon_theme_set_search_path(theme, (const gchar **)paths, path_count - 1); + } + + g_strfreev(paths); return; } -- cgit v1.2.3 From bbadbf77efa2c3f322c4812677438129bbfef2f8 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 10 Mar 2011 10:15:08 -0600 Subject: Check the theme directories on build so we can insure we're up-to-date --- libdbusmenu-gtk/client.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index fd266df..de7a752 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -120,6 +120,8 @@ dbusmenu_gtkclient_init (DbusmenuGtkClient *self) g_signal_connect(G_OBJECT(self), DBUSMENU_CLIENT_SIGNAL_ITEM_ACTIVATE, G_CALLBACK(item_activate), NULL); g_signal_connect(G_OBJECT(self), DBUSMENU_CLIENT_SIGNAL_ICON_THEME_DIRS_CHANGED, G_CALLBACK(theme_dir_changed), NULL); + theme_dir_changed(DBUSMENU_CLIENT(self), dbusmenu_client_get_icon_paths(DBUSMENU_CLIENT(self)), NULL); + return; } -- cgit v1.2.3