Merge lp:~ted/libdbusmenu/lp934574 into lp:libdbusmenu/0.6

Proposed by Ted Gould
Status: Merged
Merged at revision: 380
Proposed branch: lp:~ted/libdbusmenu/lp934574
Merge into: lp:libdbusmenu/0.6
Diff against target: 150 lines (+49/-19)
2 files modified
libdbusmenu-glib/menuitem.c (+1/-1)
libdbusmenu-gtk/parser.c (+48/-18)
To merge this branch: bzr merge lp:~ted/libdbusmenu/lp934574
Reviewer Review Type Date Requested Status
Charles Kerr (community) Needs Fixing
DBus Menu Team Pending
Review via email: mp+95673@code.launchpad.net

Description of the change

Fixes a rather nasty little bug where icons don't update. There's actually a couple of factors. One, is that we don't resetup the signals when we get a new image. The second is that we'll send a clear even if the value was never set.

To post a comment you must log in.
Revision history for this message
Charles Kerr (charlesk) wrote :

menuitem.c:

  > 9+ if ((!inhash || replaced) &&
  > 10+ !(!inhash && value == NULL)) {

  This is the only item that needs fixing... this really hurts.

  After staring at the code block above this for a bit,
  I /think/ this can be changed to:

  > 9+ if (replaced)

parser.c:

  Looks fine. I have two trivial suggestions, feel free to ignore:

  Since the patch does the same thing three times, it might be
  cleaner to have a n update_icon_from_item() wrapper function that
  extracts the ParserData from the Menuitem and calls update_icon().

  gpointer is a void*, so an explicit cast is never required.
  "ParserData * pdata = g_object_get_data()" will always work --
  "ParserData * pdata = (ParserData*)g_object_get_data()" is unnecessary.

review: Needs Fixing
Revision history for this message
Ted Gould (ted) wrote :

Okay, so I think I agree on the logic :-) Took a while to figure out, but I think I'm at the same place now. r384

lp:~ted/libdbusmenu/lp934574 updated
384. By Ted Gould

Switching out logic, we're using replaced now because it gets set everytime that the hashtable is modified, and if we weren't modifying the hash table in some way, we don't want to signal. And, conversely, no one cares if we didn't modify the hash table.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libdbusmenu-glib/menuitem.c'
2--- libdbusmenu-glib/menuitem.c 2012-02-09 18:44:09 +0000
3+++ libdbusmenu-glib/menuitem.c 2012-03-08 15:03:20 +0000
4@@ -1253,7 +1253,7 @@
5 becuse it has been unref'd when replaced in the hash
6 table. But the fact that there was a value is
7 the imporant part. */
8- if (!inhash || replaced) {
9+ if (replaced) {
10 GVariant * signalval = value;
11
12 if (signalval == NULL) {
13
14=== modified file 'libdbusmenu-gtk/parser.c'
15--- libdbusmenu-gtk/parser.c 2012-02-15 17:18:15 +0000
16+++ libdbusmenu-gtk/parser.c 2012-03-08 15:03:20 +0000
17@@ -44,6 +44,8 @@
18 GtkWidget *shell;
19 GtkWidget *image;
20 AtkObject *accessible;
21+
22+ guint theme_changed_sig;
23 } ParserData;
24
25 typedef struct _RecurseContext
26@@ -59,6 +61,8 @@
27 static void checkbox_toggled (GtkWidget * widget,
28 DbusmenuMenuitem * mi);
29 static void update_icon (DbusmenuMenuitem * menuitem,
30+ ParserData * pdata,
31+ GtkImageMenuItem * gmenuitem,
32 GtkImage * image);
33 static GtkWidget * find_menu_label (GtkWidget * widget);
34 static void label_notify_cb (GtkWidget * widget,
35@@ -212,6 +216,11 @@
36 g_object_remove_weak_pointer(G_OBJECT(pdata->accessible), (gpointer*)&pdata->accessible);
37 }
38
39+ if (pdata != NULL && pdata->theme_changed_sig != 0) {
40+ g_signal_handler_disconnect(gtk_icon_theme_get_default(), pdata->theme_changed_sig);
41+ pdata->theme_changed_sig = 0;
42+ }
43+
44 g_free(pdata);
45
46 return;
47@@ -568,19 +577,7 @@
48
49 if (GTK_IS_IMAGE (image))
50 {
51- update_icon (mi, GTK_IMAGE (image));
52-
53- /* Watch for theme changes because if gicon changes, we want to send a
54- different pixbuf. */
55- g_signal_connect(G_OBJECT(gtk_icon_theme_get_default()),
56- "changed", G_CALLBACK(theme_changed_cb), widget);
57-
58- pdata->image = image;
59- g_signal_connect (G_OBJECT (image),
60- "notify",
61- G_CALLBACK (image_notify_cb),
62- mi);
63- g_object_add_weak_pointer(G_OBJECT (image), (gpointer*)&pdata->image);
64+ update_icon (mi, pdata, GTK_IMAGE_MENU_ITEM(widget), GTK_IMAGE (image));
65 }
66 }
67
68@@ -737,7 +734,7 @@
69 }
70
71 static void
72-update_icon (DbusmenuMenuitem *menuitem, GtkImage *image)
73+update_icon (DbusmenuMenuitem *menuitem, ParserData * pdata, GtkImageMenuItem * gmenuitem, GtkImage *image)
74 {
75 GdkPixbuf * pixbuf = NULL;
76 const gchar * icon_name = NULL;
77@@ -746,6 +743,35 @@
78 GtkIconInfo * info;
79 gint width;
80
81+ /* Check to see if we're changing the image. If so, we need to track
82+ that little bugger */
83+ /* Why check for gmenuitem being NULL? Because there are some cases where
84+ we can't get it easily, and those mean it's not changed just the icon
85+ underneith, so we can ignore these larger impacts */
86+ if (image != GTK_IMAGE(pdata->image) && gmenuitem != NULL) {
87+ if (pdata->theme_changed_sig != 0) {
88+ g_signal_handler_disconnect(gtk_icon_theme_get_default(), pdata->theme_changed_sig);
89+ pdata->theme_changed_sig = 0;
90+ }
91+
92+ if (pdata->image != NULL) {
93+ g_signal_handlers_disconnect_by_func(pdata->image, G_CALLBACK(image_notify_cb), menuitem);
94+ g_object_remove_weak_pointer(G_OBJECT(pdata->image), (gpointer*)&pdata->image);
95+ }
96+
97+ pdata->image = GTK_WIDGET(image);
98+
99+ if (pdata->image != NULL) {
100+ pdata->theme_changed_sig = g_signal_connect(G_OBJECT(gtk_icon_theme_get_default()),
101+ "changed", G_CALLBACK(theme_changed_cb), gmenuitem);
102+ g_signal_connect (G_OBJECT (pdata->image),
103+ "notify",
104+ G_CALLBACK (image_notify_cb),
105+ menuitem);
106+ g_object_add_weak_pointer(G_OBJECT (pdata->image), (gpointer*)&pdata->image);
107+ }
108+ }
109+
110 if (image != NULL && should_show_image (image)) {
111 switch (gtk_image_get_storage_type (image)) {
112 case GTK_IMAGE_EMPTY:
113@@ -946,7 +972,8 @@
114 pspec->name == g_intern_static_string ("stock") ||
115 pspec->name == g_intern_static_string ("storage-type"))
116 {
117- update_icon (mi, GTK_IMAGE (widget));
118+ ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(mi), PARSER_DATA);
119+ update_icon (mi, pdata, NULL, GTK_IMAGE (widget));
120 }
121 }
122
123@@ -1134,13 +1161,15 @@
124 {
125 GtkWidget *image = NULL;
126 g_object_get(widget, "image", &image, NULL);
127- update_icon (child, GTK_IMAGE(image));
128+ ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(child), PARSER_DATA);
129+ update_icon (child, pdata, GTK_IMAGE_MENU_ITEM(widget), GTK_IMAGE(image));
130 }
131 else if (pspec->name == g_intern_static_string ("image"))
132 {
133 GtkWidget *image;
134 image = GTK_WIDGET (g_value_get_object (&prop_value));
135- update_icon (child, GTK_IMAGE (image));
136+ ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(child), PARSER_DATA);
137+ update_icon (child, pdata, GTK_IMAGE_MENU_ITEM(widget), GTK_IMAGE (image));
138 }
139 else if (pspec->name == g_intern_static_string ("parent"))
140 {
141@@ -1259,7 +1288,8 @@
142
143 gpointer pmi = g_object_get_data(G_OBJECT(data), CACHED_MENUITEM);
144 if (pmi != NULL) {
145- update_icon(DBUSMENU_MENUITEM(pmi), GTK_IMAGE(image));
146+ ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(pmi), PARSER_DATA);
147+ update_icon(DBUSMENU_MENUITEM(pmi), pdata, NULL, GTK_IMAGE(image));
148 }
149
150 /* Switch signal to new theme */

Subscribers

People subscribed via source and target branches

to all changes: