Merge lp:~mterry/libdbusmenu/proxy-gtk-menu-images into lp:libdbusmenu/12.10

Proposed by Michael Terry on 2012-09-10
Status: Merged
Approved by: Charles Kerr on 2012-09-13
Approved revision: 422
Merged at revision: 422
Proposed branch: lp:~mterry/libdbusmenu/proxy-gtk-menu-images
Merge into: lp:libdbusmenu/12.10
Diff against target: 115 lines (+63/-0)
1 file modified
libdbusmenu-gtk/parser.c (+63/-0)
To merge this branch: bzr merge lp:~mterry/libdbusmenu/proxy-gtk-menu-images
Reviewer Review Type Date Requested Status
Charles Kerr (community) 2012-09-10 Approve on 2012-09-13
Review via email: mp+123576@code.launchpad.net

Description of the change

There is a gsettings key org.gnome.desktop.interface.menus-have-icons which, when changed, gets translated into an XSettings value by gnome-settings-daemon. When that happens, all GTK+ apps notice and their GtkSettings objects emit property changes.

However, libdbusmenu does not notice. You can watch this happen by opening dconf-editor, toggling that key, and watching the behavior of the Power menu (which is native to the top bar) and the Network menu (which is proxied over dbusmenu by nm-applet). The Power menu changes appropriately. The Network menu does not.

This branch fixes that by updating parser.c to first, pay attention to which screen a widget is on. When that changes (or on init), we then watch that screen's GtkSettings object. And when it tells us the menu-icon value is different, we see if we need to change the icon we send over the wire.

Works for me in testing.

To post a comment you must log in.
Charles Kerr (charlesk) wrote :

Looks good. Thanks for this!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libdbusmenu-gtk/parser.c'
2--- libdbusmenu-gtk/parser.c 2012-04-10 16:05:52 +0000
3+++ libdbusmenu-gtk/parser.c 2012-09-10 15:36:24 +0000
4@@ -60,6 +60,9 @@
5 gulong widget_accel_handler_id;
6 gulong widget_toggle_handler_id;
7 gulong widget_visible_handler_id;
8+ gulong widget_screen_changed_handler_id;
9+
10+ gulong settings_notify_handler_id;
11
12 } ParserData;
13
14@@ -116,6 +119,12 @@
15 static void widget_add_cb (GtkWidget * widget,
16 GtkWidget * child,
17 gpointer data);
18+static void widget_screen_changed_cb (GtkWidget * widget,
19+ GdkScreen * old_screen,
20+ gpointer data);
21+static void settings_notify_cb (GtkSettings * settings,
22+ GParamSpec * pspec,
23+ gpointer data);
24 static gboolean should_show_image (GtkImage * image);
25 static void menuitem_notify_cb (GtkWidget * widget,
26 GParamSpec * pspec,
27@@ -130,6 +139,7 @@
28 static const char * interned_str_always_show_image = NULL;
29 static const char * interned_str_file = NULL;
30 static const char * interned_str_gicon = NULL;
31+static const char * interned_str_gtk_menu_images = NULL;
32 static const char * interned_str_icon_name = NULL;
33 static const char * interned_str_icon_set = NULL;
34 static const char * interned_str_image = NULL;
35@@ -155,6 +165,7 @@
36 interned_str_always_show_image = g_intern_static_string ("always-show-image");
37 interned_str_file = g_intern_static_string ("file");
38 interned_str_gicon = g_intern_static_string ("gicon");
39+ interned_str_gtk_menu_images = g_intern_static_string ("gtk-menu-images");
40 interned_str_icon_name = g_intern_static_string ("icon-name");
41 interned_str_icon_set = g_intern_static_string ("icon-set");
42 interned_str_image = g_intern_static_string ("image");
43@@ -291,6 +302,9 @@
44 dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_accel_handler_id);
45 dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_toggle_handler_id);
46 dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_visible_handler_id);
47+ dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_screen_changed_handler_id);
48+ dbusmenu_gtk_clear_signal_handler (gtk_widget_get_settings (GTK_WIDGET (o)),
49+ &pdata->settings_notify_handler_id);
50 g_object_remove_weak_pointer(o, (gpointer*)&pdata->widget);
51
52 /* since the DbusmenuMenuitem is being destroyed, uncache it from the GtkWidget */
53@@ -746,6 +760,10 @@
54 pdata->widget_add_handler_id = g_signal_connect (widget, "add",
55 G_CALLBACK (widget_add_cb), mi);
56
57+ pdata->widget_screen_changed_handler_id = g_signal_connect (widget, "screen-changed",
58+ G_CALLBACK (widget_screen_changed_cb), mi);
59+ widget_screen_changed_cb (widget, NULL, mi);
60+
61 return mi;
62 }
63
64@@ -1282,6 +1300,51 @@
65 handle_first_label (data);
66 }
67
68+/* Pass NULL for pspec to update all settings at once */
69+static void
70+widget_screen_changed_cb (GtkWidget * widget, GdkScreen * old_screen, gpointer data)
71+{
72+ DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data);
73+ g_return_if_fail (mi != NULL);
74+
75+ ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(mi), PARSER_DATA);
76+
77+ if (old_screen != NULL)
78+ dbusmenu_gtk_clear_signal_handler (gtk_settings_get_for_screen (old_screen),
79+ &pdata->settings_notify_handler_id);
80+ pdata->settings_notify_handler_id = g_signal_connect (gtk_widget_get_settings (widget), "notify",
81+ G_CALLBACK (settings_notify_cb), mi);
82+
83+ /* And update widget now that we have a new GtkSettings */
84+ settings_notify_cb (gtk_widget_get_settings (widget), NULL, mi);
85+}
86+
87+/* Pass NULL for pspec to update all settings at once */
88+static void
89+settings_notify_cb (GtkSettings * settings, GParamSpec * pspec, gpointer data)
90+{
91+ GValue prop_value = {0};
92+ DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data);
93+ g_return_if_fail (mi != NULL);
94+
95+ ensure_interned_strings_loaded ();
96+
97+ if (pspec != NULL)
98+ {
99+ g_value_init (&prop_value, pspec->value_type);
100+ g_object_get_property (G_OBJECT (settings), pspec->name, &prop_value);
101+ }
102+
103+ if (pspec == NULL || pspec->name == interned_str_gtk_menu_images)
104+ {
105+ ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(mi), PARSER_DATA);
106+ update_icon (mi, pdata, GTK_IMAGE(pdata->image));
107+ }
108+
109+ if (pspec != NULL)
110+ g_value_unset (&prop_value);
111+}
112+
113 /* A child item was added to a menu we're watching. Let's try to integrate it. */
114 static void
115 item_inserted_cb (GtkContainer *menu,

Subscribers

People subscribed via source and target branches

to all changes: