Merge lp:~attente/unity-gtk-module/1208019-2 into lp:unity-gtk-module/14.10
- 1208019-2
- Merge into trunk.14.10
Proposed by
William Hua
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Ted Gould | ||||
Approved revision: | 335 | ||||
Merged at revision: | 330 | ||||
Proposed branch: | lp:~attente/unity-gtk-module/1208019-2 | ||||
Merge into: | lp:unity-gtk-module/14.10 | ||||
Diff against target: |
895 lines (+442/-230) 7 files modified
lib/unity-gtk-action-group.c (+269/-161) lib/unity-gtk-action-private.h (+19/-15) lib/unity-gtk-action.c (+14/-0) lib/unity-gtk-menu-item-private.h (+3/-1) lib/unity-gtk-menu-item.c (+88/-26) lib/unity-gtk-menu-section.c (+40/-25) lib/unity-gtk-menu-shell.c (+9/-2) |
||||
To merge this branch: | bzr merge lp:~attente/unity-gtk-module/1208019-2 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+224646@code.launchpad.net |
Commit message
Forward show and hide signals to GTK+ menus.
Description of the change
Forward show and hide signals to GTK+ menus.
To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : | # |
review:
Approve
(continuous-integration)
Revision history for this message
Ted Gould (ted) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/unity-gtk-action-group.c' |
2 | --- lib/unity-gtk-action-group.c 2014-03-25 21:48:16 +0000 |
3 | +++ lib/unity-gtk-action-group.c 2014-06-26 14:42:27 +0000 |
4 | @@ -42,6 +42,14 @@ |
5 | |
6 | static gboolean unity_gtk_action_group_debug; |
7 | |
8 | +static gboolean |
9 | +g_signal_emit_hide (gpointer user_data) |
10 | +{ |
11 | + g_signal_emit_by_name (user_data, "hide"); |
12 | + |
13 | + return G_SOURCE_REMOVE; |
14 | +} |
15 | + |
16 | static void |
17 | unity_gtk_action_group_handle_group_action_added (GActionGroup *action_group, |
18 | gchar *action_name, |
19 | @@ -272,54 +280,79 @@ |
20 | |
21 | if (action != NULL) |
22 | { |
23 | - if (action->items_by_name != NULL) |
24 | + if (g_strcmp0 (name, action->name) == 0) |
25 | { |
26 | - if (value != NULL) |
27 | - { |
28 | - const gchar *name; |
29 | - UnityGtkMenuItem *item; |
30 | - |
31 | - g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)); |
32 | - |
33 | - name = g_variant_get_string (value, NULL); |
34 | - item = g_hash_table_lookup (action->items_by_name, name); |
35 | - |
36 | - if (item == NULL || !unity_gtk_menu_item_is_check (item)) |
37 | - { |
38 | - g_warn_if_reached (); |
39 | - |
40 | - value = NULL; |
41 | - } |
42 | - else |
43 | - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item->menu_item), TRUE); |
44 | - } |
45 | - |
46 | - if (value == NULL) |
47 | - { |
48 | - GHashTableIter iter; |
49 | - gpointer value; |
50 | - |
51 | - g_hash_table_iter_init (&iter, action->items_by_name); |
52 | - while (g_hash_table_iter_next (&iter, NULL, &value)) |
53 | - { |
54 | - UnityGtkMenuItem *item = value; |
55 | - |
56 | - if (unity_gtk_menu_item_is_check (item)) |
57 | - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item->menu_item), FALSE); |
58 | - } |
59 | - } |
60 | + if (action->items_by_name != NULL) |
61 | + { |
62 | + if (value != NULL) |
63 | + { |
64 | + const gchar *name; |
65 | + UnityGtkMenuItem *item; |
66 | + |
67 | + g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)); |
68 | + |
69 | + name = g_variant_get_string (value, NULL); |
70 | + item = g_hash_table_lookup (action->items_by_name, name); |
71 | + |
72 | + if (item == NULL || !unity_gtk_menu_item_is_check (item)) |
73 | + { |
74 | + g_warn_if_reached (); |
75 | + |
76 | + value = NULL; |
77 | + } |
78 | + else |
79 | + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item->menu_item), TRUE); |
80 | + } |
81 | + |
82 | + if (value == NULL) |
83 | + { |
84 | + GHashTableIter iter; |
85 | + gpointer value; |
86 | + |
87 | + g_hash_table_iter_init (&iter, action->items_by_name); |
88 | + while (g_hash_table_iter_next (&iter, NULL, &value)) |
89 | + { |
90 | + UnityGtkMenuItem *item = value; |
91 | + |
92 | + if (unity_gtk_menu_item_is_check (item)) |
93 | + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item->menu_item), FALSE); |
94 | + } |
95 | + } |
96 | + } |
97 | + else if (action->item != NULL && unity_gtk_menu_item_is_check (action->item)) |
98 | + { |
99 | + g_return_if_fail (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)); |
100 | + |
101 | + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (action->item->menu_item), g_variant_get_boolean (value)); |
102 | + } |
103 | + else |
104 | + g_warn_if_fail (value == NULL); |
105 | + |
106 | + return; |
107 | } |
108 | - else if (action->item != NULL && unity_gtk_menu_item_is_check (action->item)) |
109 | + else if (g_strcmp0 (name, action->subname) == 0) |
110 | { |
111 | + GtkWidget *submenu; |
112 | + |
113 | g_return_if_fail (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)); |
114 | - |
115 | - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (action->item->menu_item), g_variant_get_boolean (value)); |
116 | + g_return_if_fail (action->item != NULL && action->item->menu_item != NULL); |
117 | + |
118 | + submenu = gtk_menu_item_get_submenu (action->item->menu_item); |
119 | + |
120 | + g_return_if_fail (submenu != NULL); |
121 | + |
122 | + if (g_variant_get_boolean (value)) |
123 | + g_signal_emit_by_name (submenu, "show"); |
124 | + else |
125 | + g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, g_signal_emit_hide, g_object_ref (submenu), g_object_unref); |
126 | + |
127 | + return; |
128 | } |
129 | else |
130 | - g_warn_if_fail (value == NULL); |
131 | - |
132 | - return; |
133 | + g_warn_if_reached (); |
134 | } |
135 | + else |
136 | + g_warn_if_reached (); |
137 | } |
138 | else |
139 | g_warn_if_reached (); |
140 | @@ -359,33 +392,40 @@ |
141 | |
142 | if (action != NULL) |
143 | { |
144 | - if (action->items_by_name != NULL) |
145 | - { |
146 | - const gchar *name; |
147 | - UnityGtkMenuItem *item; |
148 | - |
149 | - g_return_if_fail (parameter != NULL && g_variant_is_of_type (parameter, G_VARIANT_TYPE_STRING)); |
150 | - |
151 | - name = g_variant_get_string (parameter, NULL); |
152 | - item = g_hash_table_lookup (action->items_by_name, name); |
153 | - |
154 | - if (item != NULL) |
155 | - unity_gtk_menu_item_activate (item); |
156 | - |
157 | - g_action_group_action_state_changed (G_ACTION_GROUP (group), action->name, parameter); |
158 | - } |
159 | - else if (action->item != NULL) |
160 | - { |
161 | - if (unity_gtk_menu_item_get_draw_as_radio (action->item)) |
162 | - g_warn_if_fail (g_variant_is_of_type (parameter, G_VARIANT_TYPE_STRING)); |
163 | - else |
164 | - g_warn_if_fail (parameter == NULL); |
165 | - |
166 | - unity_gtk_menu_item_activate (action->item); |
167 | - } |
168 | - |
169 | - return; |
170 | + if (g_strcmp0 (name, action->name) == 0) |
171 | + { |
172 | + if (action->items_by_name != NULL) |
173 | + { |
174 | + const gchar *name; |
175 | + UnityGtkMenuItem *item; |
176 | + |
177 | + g_return_if_fail (parameter != NULL && g_variant_is_of_type (parameter, G_VARIANT_TYPE_STRING)); |
178 | + |
179 | + name = g_variant_get_string (parameter, NULL); |
180 | + item = g_hash_table_lookup (action->items_by_name, name); |
181 | + |
182 | + if (item != NULL) |
183 | + unity_gtk_menu_item_activate (item); |
184 | + |
185 | + g_action_group_action_state_changed (G_ACTION_GROUP (group), action->name, parameter); |
186 | + } |
187 | + else if (action->item != NULL) |
188 | + { |
189 | + if (unity_gtk_menu_item_get_draw_as_radio (action->item)) |
190 | + g_warn_if_fail (g_variant_is_of_type (parameter, G_VARIANT_TYPE_STRING)); |
191 | + else |
192 | + g_warn_if_fail (parameter == NULL); |
193 | + |
194 | + unity_gtk_menu_item_activate (action->item); |
195 | + } |
196 | + |
197 | + return; |
198 | + } |
199 | + else |
200 | + g_warn_if_reached (); |
201 | } |
202 | + else |
203 | + g_warn_if_reached (); |
204 | } |
205 | else |
206 | g_warn_if_reached (); |
207 | @@ -419,111 +459,142 @@ |
208 | |
209 | if (action != NULL) |
210 | { |
211 | - if (enabled != NULL) |
212 | + if (g_strcmp0 (name, action->name) == 0) |
213 | { |
214 | - if (action->items_by_name != NULL) |
215 | - { |
216 | - GHashTableIter iter; |
217 | - gpointer value; |
218 | - |
219 | - *enabled = FALSE; |
220 | - |
221 | - g_hash_table_iter_init (&iter, action->items_by_name); |
222 | - while (!*enabled && g_hash_table_iter_next (&iter, NULL, &value)) |
223 | - *enabled = unity_gtk_menu_item_is_sensitive (value); |
224 | - } |
225 | - else |
226 | - *enabled = action->item != NULL && unity_gtk_menu_item_is_sensitive (action->item); |
227 | + if (enabled != NULL) |
228 | + { |
229 | + if (action->items_by_name != NULL) |
230 | + { |
231 | + GHashTableIter iter; |
232 | + gpointer value; |
233 | + |
234 | + *enabled = FALSE; |
235 | + |
236 | + g_hash_table_iter_init (&iter, action->items_by_name); |
237 | + while (!*enabled && g_hash_table_iter_next (&iter, NULL, &value)) |
238 | + *enabled = unity_gtk_menu_item_is_sensitive (value); |
239 | + } |
240 | + else |
241 | + *enabled = action->item != NULL && unity_gtk_menu_item_is_sensitive (action->item); |
242 | + } |
243 | + |
244 | + if (parameter_type != NULL) |
245 | + { |
246 | + if (action->items_by_name != NULL || (action->item != NULL && unity_gtk_menu_item_get_draw_as_radio (action->item))) |
247 | + *parameter_type = G_VARIANT_TYPE_STRING; |
248 | + else |
249 | + *parameter_type = NULL; |
250 | + } |
251 | + |
252 | + if (state_type != NULL) |
253 | + { |
254 | + if (action->items_by_name != NULL || (action->item != NULL && unity_gtk_menu_item_get_draw_as_radio (action->item))) |
255 | + *state_type = G_VARIANT_TYPE_STRING; |
256 | + else if (action->item != NULL && unity_gtk_menu_item_is_check (action->item)) |
257 | + *state_type = G_VARIANT_TYPE_BOOLEAN; |
258 | + else |
259 | + *state_type = NULL; |
260 | + } |
261 | + |
262 | + if (state_hint != NULL) |
263 | + { |
264 | + if (action->items_by_name != NULL) |
265 | + { |
266 | + GVariantBuilder builder; |
267 | + GHashTableIter iter; |
268 | + gpointer key; |
269 | + |
270 | + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); |
271 | + |
272 | + g_hash_table_iter_init (&iter, action->items_by_name); |
273 | + while (g_hash_table_iter_next (&iter, &key, NULL)) |
274 | + g_variant_builder_add (&builder, "s", key); |
275 | + |
276 | + *state_hint = g_variant_ref_sink (g_variant_builder_end (&builder)); |
277 | + } |
278 | + else if (action->item != NULL && unity_gtk_menu_item_is_check (action->item)) |
279 | + { |
280 | + GVariantBuilder builder; |
281 | + |
282 | + if (unity_gtk_menu_item_get_draw_as_radio (action->item)) |
283 | + { |
284 | + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); |
285 | + g_variant_builder_add (&builder, "s", action->name); |
286 | + *state_hint = g_variant_ref_sink (g_variant_builder_end (&builder)); |
287 | + } |
288 | + else |
289 | + { |
290 | + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); |
291 | + g_variant_builder_add (&builder, "b", FALSE); |
292 | + g_variant_builder_add (&builder, "b", TRUE); |
293 | + *state_hint = g_variant_ref_sink (g_variant_builder_end (&builder)); |
294 | + } |
295 | + } |
296 | + else |
297 | + *state_hint = NULL; |
298 | + } |
299 | + |
300 | + if (state != NULL) |
301 | + { |
302 | + if (action->items_by_name != NULL) |
303 | + { |
304 | + GHashTableIter iter; |
305 | + gpointer key; |
306 | + gpointer value; |
307 | + |
308 | + *state = NULL; |
309 | + |
310 | + g_hash_table_iter_init (&iter, action->items_by_name); |
311 | + while (*state == NULL && g_hash_table_iter_next (&iter, &key, &value)) |
312 | + if (unity_gtk_menu_item_is_active (value)) |
313 | + *state = g_variant_ref_sink (g_variant_new_string (key)); |
314 | + } |
315 | + else if (action->item != NULL && unity_gtk_menu_item_is_check (action->item)) |
316 | + { |
317 | + if (unity_gtk_menu_item_get_draw_as_radio (action->item)) |
318 | + { |
319 | + if (unity_gtk_menu_item_is_active (action->item)) |
320 | + *state = g_variant_ref_sink (g_variant_new_string (action->name)); |
321 | + else |
322 | + *state = g_variant_ref_sink (g_variant_new_string ("")); |
323 | + } |
324 | + else |
325 | + *state = g_variant_ref_sink (g_variant_new_boolean (unity_gtk_menu_item_is_active (action->item))); |
326 | + } |
327 | + else |
328 | + *state = NULL; |
329 | + } |
330 | + |
331 | + return TRUE; |
332 | } |
333 | + else if (g_strcmp0 (name, action->subname) == 0) |
334 | + { |
335 | + if (enabled != NULL) |
336 | + *enabled = TRUE; |
337 | |
338 | - if (parameter_type != NULL) |
339 | - { |
340 | - if (action->items_by_name != NULL || (action->item != NULL && unity_gtk_menu_item_get_draw_as_radio (action->item))) |
341 | - *parameter_type = G_VARIANT_TYPE_STRING; |
342 | - else |
343 | + if (parameter_type != NULL) |
344 | *parameter_type = NULL; |
345 | - } |
346 | |
347 | - if (state_type != NULL) |
348 | - { |
349 | - if (action->items_by_name != NULL || (action->item != NULL && unity_gtk_menu_item_get_draw_as_radio (action->item))) |
350 | - *state_type = G_VARIANT_TYPE_STRING; |
351 | - else if (action->item != NULL && unity_gtk_menu_item_is_check (action->item)) |
352 | + if (state_type != NULL) |
353 | *state_type = G_VARIANT_TYPE_BOOLEAN; |
354 | - else |
355 | - *state_type = NULL; |
356 | - } |
357 | |
358 | - if (state_hint != NULL) |
359 | - { |
360 | - if (action->items_by_name != NULL) |
361 | + if (state_hint != NULL) |
362 | { |
363 | GVariantBuilder builder; |
364 | - GHashTableIter iter; |
365 | - gpointer key; |
366 | - |
367 | - g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); |
368 | - |
369 | - g_hash_table_iter_init (&iter, action->items_by_name); |
370 | - while (g_hash_table_iter_next (&iter, &key, NULL)) |
371 | - g_variant_builder_add (&builder, "s", key); |
372 | - |
373 | + |
374 | + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); |
375 | + g_variant_builder_add (&builder, "b", FALSE); |
376 | + g_variant_builder_add (&builder, "b", TRUE); |
377 | *state_hint = g_variant_ref_sink (g_variant_builder_end (&builder)); |
378 | } |
379 | - else if (action->item != NULL && unity_gtk_menu_item_is_check (action->item)) |
380 | - { |
381 | - GVariantBuilder builder; |
382 | - |
383 | - if (unity_gtk_menu_item_get_draw_as_radio (action->item)) |
384 | - { |
385 | - g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); |
386 | - g_variant_builder_add (&builder, "s", action->name); |
387 | - *state_hint = g_variant_ref_sink (g_variant_builder_end (&builder)); |
388 | - } |
389 | - else |
390 | - { |
391 | - g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); |
392 | - g_variant_builder_add (&builder, "b", FALSE); |
393 | - g_variant_builder_add (&builder, "b", TRUE); |
394 | - *state_hint = g_variant_ref_sink (g_variant_builder_end (&builder)); |
395 | - } |
396 | - } |
397 | - else |
398 | - *state_hint = NULL; |
399 | - } |
400 | - |
401 | - if (state != NULL) |
402 | - { |
403 | - if (action->items_by_name != NULL) |
404 | - { |
405 | - GHashTableIter iter; |
406 | - gpointer key; |
407 | - gpointer value; |
408 | - |
409 | - *state = NULL; |
410 | - |
411 | - g_hash_table_iter_init (&iter, action->items_by_name); |
412 | - while (*state == NULL && g_hash_table_iter_next (&iter, &key, &value)) |
413 | - if (unity_gtk_menu_item_is_active (value)) |
414 | - *state = g_variant_ref_sink (g_variant_new_string (key)); |
415 | - } |
416 | - else if (action->item != NULL && unity_gtk_menu_item_is_check (action->item)) |
417 | - { |
418 | - if (unity_gtk_menu_item_get_draw_as_radio (action->item)) |
419 | - { |
420 | - if (unity_gtk_menu_item_is_active (action->item)) |
421 | - *state = g_variant_ref_sink (g_variant_new_string (action->name)); |
422 | - else |
423 | - *state = g_variant_ref_sink (g_variant_new_string ("")); |
424 | - } |
425 | - else |
426 | - *state = g_variant_ref_sink (g_variant_new_boolean (unity_gtk_menu_item_is_active (action->item))); |
427 | - } |
428 | - else |
429 | - *state = NULL; |
430 | - } |
431 | - |
432 | - return TRUE; |
433 | + |
434 | + if (state != NULL) |
435 | + *state = g_variant_ref_sink (g_variant_new_boolean (TRUE)); |
436 | + |
437 | + return TRUE; |
438 | + } |
439 | + else |
440 | + g_warn_if_reached (); |
441 | } |
442 | } |
443 | else |
444 | @@ -865,6 +936,21 @@ |
445 | g_warn_if_reached (); |
446 | |
447 | g_action_group_action_added (G_ACTION_GROUP (group), new_action->name); |
448 | + |
449 | + /* Add a new submenu action so we can detect opening and closing. */ |
450 | + if (item->menu_item != NULL && gtk_menu_item_get_submenu (item->menu_item) != NULL) |
451 | + { |
452 | + gchar *subname = unity_gtk_action_group_get_action_name (group, item); |
453 | + unity_gtk_action_set_subname (new_action, subname); |
454 | + g_free (subname); |
455 | + |
456 | + if (group->actions_by_name != NULL) |
457 | + g_hash_table_insert (group->actions_by_name, new_action->subname, g_object_ref (new_action)); |
458 | + else |
459 | + g_warn_if_reached (); |
460 | + |
461 | + g_action_group_action_added (G_ACTION_GROUP (group), new_action->subname); |
462 | + } |
463 | } |
464 | } |
465 | } |
466 | @@ -908,6 +994,17 @@ |
467 | |
468 | if (g_hash_table_size (action->items_by_name) == 0) |
469 | { |
470 | + /* Remove the submenu action used to detect opening and closing. */ |
471 | + if (action->subname != NULL) |
472 | + { |
473 | + if (group->actions_by_name != NULL) |
474 | + g_hash_table_remove (group->actions_by_name, action->subname); |
475 | + else |
476 | + g_warn_if_reached (); |
477 | + |
478 | + g_action_group_action_removed (G_ACTION_GROUP (group), action->subname); |
479 | + } |
480 | + |
481 | if (group->actions_by_name != NULL) |
482 | g_hash_table_remove (group->actions_by_name, action->name); |
483 | else |
484 | @@ -924,6 +1021,17 @@ |
485 | } |
486 | else |
487 | { |
488 | + /* Remove the submenu action used to detect opening and closing. */ |
489 | + if (action->subname != NULL) |
490 | + { |
491 | + if (group->actions_by_name != NULL) |
492 | + g_hash_table_remove (group->actions_by_name, action->subname); |
493 | + else |
494 | + g_warn_if_reached (); |
495 | + |
496 | + g_action_group_action_removed (G_ACTION_GROUP (group), action->subname); |
497 | + } |
498 | + |
499 | if (group->actions_by_name != NULL) |
500 | g_hash_table_remove (group->actions_by_name, action->name); |
501 | else |
502 | |
503 | === modified file 'lib/unity-gtk-action-private.h' |
504 | --- lib/unity-gtk-action-private.h 2013-02-19 11:55:57 +0000 |
505 | +++ lib/unity-gtk-action-private.h 2014-06-26 14:42:27 +0000 |
506 | @@ -46,25 +46,29 @@ |
507 | |
508 | /*< private >*/ |
509 | gchar *name; |
510 | + gchar *subname; |
511 | UnityGtkMenuItem *item; |
512 | GHashTable *items_by_name; |
513 | }; |
514 | |
515 | -GType unity_gtk_action_get_type (void) G_GNUC_INTERNAL; |
516 | - |
517 | -UnityGtkAction * unity_gtk_action_new (const gchar *name, |
518 | - UnityGtkMenuItem *item) G_GNUC_INTERNAL; |
519 | - |
520 | -UnityGtkAction * unity_gtk_action_new_radio (const gchar *name) G_GNUC_INTERNAL; |
521 | - |
522 | -void unity_gtk_action_set_name (UnityGtkAction *action, |
523 | - const gchar *name) G_GNUC_INTERNAL; |
524 | - |
525 | -void unity_gtk_action_set_item (UnityGtkAction *action, |
526 | - UnityGtkMenuItem *item) G_GNUC_INTERNAL; |
527 | - |
528 | -void unity_gtk_action_print (UnityGtkAction *action, |
529 | - guint indent) G_GNUC_INTERNAL; |
530 | +GType unity_gtk_action_get_type (void) G_GNUC_INTERNAL; |
531 | + |
532 | +UnityGtkAction * unity_gtk_action_new (const gchar *name, |
533 | + UnityGtkMenuItem *item) G_GNUC_INTERNAL; |
534 | + |
535 | +UnityGtkAction * unity_gtk_action_new_radio (const gchar *name) G_GNUC_INTERNAL; |
536 | + |
537 | +void unity_gtk_action_set_name (UnityGtkAction *action, |
538 | + const gchar *name) G_GNUC_INTERNAL; |
539 | + |
540 | +void unity_gtk_action_set_subname (UnityGtkAction *action, |
541 | + const gchar *subname) G_GNUC_INTERNAL; |
542 | + |
543 | +void unity_gtk_action_set_item (UnityGtkAction *action, |
544 | + UnityGtkMenuItem *item) G_GNUC_INTERNAL; |
545 | + |
546 | +void unity_gtk_action_print (UnityGtkAction *action, |
547 | + guint indent) G_GNUC_INTERNAL; |
548 | |
549 | G_END_DECLS |
550 | |
551 | |
552 | === modified file 'lib/unity-gtk-action.c' |
553 | --- lib/unity-gtk-action.c 2013-02-19 11:55:57 +0000 |
554 | +++ lib/unity-gtk-action.c 2014-06-26 14:42:27 +0000 |
555 | @@ -41,6 +41,7 @@ |
556 | } |
557 | |
558 | unity_gtk_action_set_item (action, NULL); |
559 | + unity_gtk_action_set_subname (action, NULL); |
560 | unity_gtk_action_set_name (action, NULL); |
561 | |
562 | G_OBJECT_CLASS (unity_gtk_action_parent_class)->dispose (object); |
563 | @@ -93,6 +94,16 @@ |
564 | } |
565 | |
566 | void |
567 | +unity_gtk_action_set_subname (UnityGtkAction *action, |
568 | + const gchar *subname) |
569 | +{ |
570 | + g_return_if_fail (UNITY_GTK_IS_ACTION (action)); |
571 | + |
572 | + g_free (action->subname); |
573 | + action->subname = g_strdup (subname); |
574 | +} |
575 | + |
576 | +void |
577 | unity_gtk_action_set_item (UnityGtkAction *action, |
578 | UnityGtkMenuItem *item) |
579 | { |
580 | @@ -132,6 +143,9 @@ |
581 | if (action->name != NULL) |
582 | g_print ("%s \"%s\"\n", space, action->name); |
583 | |
584 | + if (action->subname != NULL) |
585 | + g_print ("%s \"%s\"\n", space, action->subname); |
586 | + |
587 | if (action->item != NULL) |
588 | g_print ("%s (%s *) %p\n", space, G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (action->item)), action->item); |
589 | |
590 | |
591 | === modified file 'lib/unity-gtk-menu-item-private.h' |
592 | --- lib/unity-gtk-menu-item-private.h 2014-03-31 00:40:48 +0000 |
593 | +++ lib/unity-gtk-menu-item-private.h 2014-06-26 14:42:27 +0000 |
594 | @@ -52,7 +52,9 @@ |
595 | guchar child_shell_valid : 1; |
596 | guint item_index; |
597 | UnityGtkAction *action; |
598 | - gchar *label; |
599 | + GtkLabel *first_label; |
600 | + GtkLabel *second_label; |
601 | + gchar *label_label; |
602 | }; |
603 | |
604 | GType unity_gtk_menu_item_get_type (void) G_GNUC_INTERNAL; |
605 | |
606 | === modified file 'lib/unity-gtk-menu-item.c' |
607 | --- lib/unity-gtk-menu-item.c 2014-03-31 00:40:48 +0000 |
608 | +++ lib/unity-gtk-menu-item.c 2014-06-26 14:42:27 +0000 |
609 | @@ -368,6 +368,75 @@ |
610 | } |
611 | |
612 | static void |
613 | +unity_gtk_menu_item_disconnect_labels (UnityGtkMenuItem *item) |
614 | +{ |
615 | + g_return_if_fail (UNITY_GTK_IS_MENU_ITEM (item)); |
616 | + |
617 | + if (item->second_label != NULL) |
618 | + { |
619 | + g_signal_handlers_disconnect_by_data (item->second_label, item); |
620 | + item->second_label = NULL; |
621 | + } |
622 | + |
623 | + if (item->first_label != NULL) |
624 | + { |
625 | + g_signal_handlers_disconnect_by_data (item->first_label, item); |
626 | + item->first_label = NULL; |
627 | + } |
628 | +} |
629 | + |
630 | +static gboolean |
631 | +unity_gtk_menu_item_connect_labels (UnityGtkMenuItem *item) |
632 | +{ |
633 | + GtkLabel *first_label = NULL; |
634 | + GtkLabel *second_label = NULL; |
635 | + |
636 | + g_return_val_if_fail (UNITY_GTK_IS_MENU_ITEM (item), FALSE); |
637 | + |
638 | + if (item->menu_item != NULL) |
639 | + { |
640 | + /* ensure label is available */ |
641 | + gtk_menu_item_get_label (item->menu_item); |
642 | + |
643 | + first_label = gtk_menu_item_get_nth_label (item->menu_item, 0); |
644 | + second_label = gtk_menu_item_get_nth_label (item->menu_item, 1); |
645 | + } |
646 | + |
647 | + if (first_label != item->first_label || second_label != item->second_label) |
648 | + { |
649 | + unity_gtk_menu_item_disconnect_labels (item); |
650 | + |
651 | + item->first_label = first_label; |
652 | + item->second_label = second_label; |
653 | + |
654 | + if (item->first_label != NULL) |
655 | + g_signal_connect (item->first_label, "notify", G_CALLBACK (unity_gtk_menu_item_handle_label_notify), item); |
656 | + if (item->second_label != NULL) |
657 | + g_signal_connect (item->second_label, "notify", G_CALLBACK (unity_gtk_menu_item_handle_label_notify), item); |
658 | + |
659 | + return TRUE; |
660 | + } |
661 | + |
662 | + return FALSE; |
663 | +} |
664 | + |
665 | +static void |
666 | +unity_gtk_menu_item_handle_add_or_remove (GtkContainer *container, |
667 | + GtkWidget *widget, |
668 | + gpointer user_data) |
669 | +{ |
670 | + UnityGtkMenuItem *item; |
671 | + |
672 | + g_return_if_fail (UNITY_GTK_IS_MENU_ITEM (user_data)); |
673 | + |
674 | + item = UNITY_GTK_MENU_ITEM (user_data); |
675 | + |
676 | + /* just ignore the case when parent_shell is NULL */ |
677 | + if (item->parent_shell != NULL && unity_gtk_menu_item_connect_labels (item)) |
678 | + unity_gtk_menu_shell_handle_item_notify (item->parent_shell, item, "label"); |
679 | +} |
680 | + |
681 | +static void |
682 | unity_gtk_menu_item_handle_accel_closures_changed (GtkWidget *widget, |
683 | gpointer user_data) |
684 | { |
685 | @@ -388,23 +457,16 @@ |
686 | unity_gtk_menu_item_set_menu_item (UnityGtkMenuItem *item, |
687 | GtkMenuItem *menu_item) |
688 | { |
689 | - GtkLabel *label; |
690 | - |
691 | g_return_if_fail (UNITY_GTK_IS_MENU_ITEM (item)); |
692 | |
693 | if (menu_item != item->menu_item) |
694 | { |
695 | UnityGtkMenuShell *child_shell = item->child_shell; |
696 | |
697 | + unity_gtk_menu_item_disconnect_labels (item); |
698 | + |
699 | if (item->menu_item != NULL) |
700 | - { |
701 | - label = gtk_menu_item_get_nth_label (item->menu_item, 0); |
702 | - |
703 | - if (label != NULL) |
704 | - g_signal_handlers_disconnect_by_data (label, item); |
705 | - |
706 | - g_signal_handlers_disconnect_by_data (item->menu_item, item); |
707 | - } |
708 | + g_signal_handlers_disconnect_by_data (item->menu_item, item); |
709 | |
710 | if (child_shell != NULL) |
711 | { |
712 | @@ -419,20 +481,20 @@ |
713 | if (menu_item != NULL) |
714 | { |
715 | g_signal_connect (menu_item, "notify", G_CALLBACK (unity_gtk_menu_item_handle_item_notify), item); |
716 | - |
717 | - /* ensure label is available */ |
718 | - gtk_menu_item_get_label (menu_item); |
719 | - label = gtk_menu_item_get_nth_label (menu_item, 0); |
720 | - |
721 | - if (label != NULL) |
722 | - g_signal_connect (label, "notify", G_CALLBACK (unity_gtk_menu_item_handle_label_notify), item); |
723 | - |
724 | + g_signal_connect (menu_item, "add", G_CALLBACK (unity_gtk_menu_item_handle_add_or_remove), item); |
725 | + g_signal_connect (menu_item, "remove", G_CALLBACK (unity_gtk_menu_item_handle_add_or_remove), item); |
726 | g_signal_connect (menu_item, "accel-closures-changed", G_CALLBACK (unity_gtk_menu_item_handle_accel_closures_changed), item); |
727 | |
728 | - /* LP: #1208019 */ |
729 | + /* |
730 | + * LP: #1208019: We do this because Eclipse sets menu item |
731 | + * accelerators using private API, and there's no way for us to |
732 | + * detect when they change. |
733 | + */ |
734 | if (gtk_menu_item_get_submenu (menu_item) != NULL) |
735 | g_signal_emit_by_name (gtk_menu_item_get_submenu (menu_item), "show"); |
736 | } |
737 | + |
738 | + unity_gtk_menu_item_connect_labels (item); |
739 | } |
740 | } |
741 | |
742 | @@ -470,8 +532,8 @@ |
743 | |
744 | item = UNITY_GTK_MENU_ITEM (object); |
745 | |
746 | - g_free (item->label); |
747 | - item->label = NULL; |
748 | + g_free (item->label_label); |
749 | + item->label_label = NULL; |
750 | |
751 | G_OBJECT_CLASS (unity_gtk_menu_item_parent_class)->finalize (object); |
752 | } |
753 | @@ -661,7 +723,7 @@ |
754 | g_return_val_if_fail (UNITY_GTK_IS_MENU_ITEM (item), NULL); |
755 | g_return_val_if_fail (item->menu_item != NULL, NULL); |
756 | |
757 | - if (item->label == NULL) |
758 | + if (item->label_label == NULL) |
759 | { |
760 | const gchar *label_label = gtk_menu_item_get_label (item->menu_item); |
761 | |
762 | @@ -691,16 +753,16 @@ |
763 | if (gtk_label_get_use_underline (label)) |
764 | { |
765 | if (item->parent_shell == NULL || item->parent_shell->has_mnemonics) |
766 | - item->label = g_strdup (label_label); |
767 | + item->label_label = g_strdup (label_label); |
768 | else |
769 | - item->label = g_strdup_no_mnemonics (label_label); |
770 | + item->label_label = g_strdup_no_mnemonics (label_label); |
771 | } |
772 | else |
773 | - item->label = g_strdup_escape_underscores (label_label); |
774 | + item->label_label = g_strdup_escape_underscores (label_label); |
775 | } |
776 | } |
777 | |
778 | - return item->label; |
779 | + return item->label_label; |
780 | } |
781 | |
782 | GIcon * |
783 | |
784 | === modified file 'lib/unity-gtk-menu-section.c' |
785 | --- lib/unity-gtk-menu-section.c 2014-03-31 00:40:48 +0000 |
786 | +++ lib/unity-gtk-menu-section.c 2014-06-26 14:42:27 +0000 |
787 | @@ -27,6 +27,10 @@ |
788 | #define G_MENU_ATTRIBUTE_ACCEL_TEXT "x-canonical-accel" |
789 | #endif |
790 | |
791 | +#ifndef G_MENU_ATTRIBUTE_SUBMENU_ACTION |
792 | +#define G_MENU_ATTRIBUTE_SUBMENU_ACTION "submenu-action" |
793 | +#endif |
794 | + |
795 | G_DEFINE_TYPE (UnityGtkMenuSection, |
796 | unity_gtk_menu_section, |
797 | G_TYPE_MENU_MODEL); |
798 | @@ -136,32 +140,43 @@ |
799 | g_object_unref (icon); |
800 | } |
801 | |
802 | - if (action != NULL && action->name != NULL) |
803 | + if (action != NULL) |
804 | { |
805 | - gchar *name = g_strdup_printf ("unity.%s", action->name); |
806 | - GVariant *variant = g_variant_ref_sink (g_variant_new_string (name)); |
807 | - |
808 | - g_hash_table_insert (*attributes, G_MENU_ATTRIBUTE_ACTION, variant); |
809 | - |
810 | - if (action->items_by_name != NULL) |
811 | - { |
812 | - GHashTableIter iter; |
813 | - gpointer key; |
814 | - gpointer value; |
815 | - const gchar *target = NULL; |
816 | - |
817 | - g_hash_table_iter_init (&iter, action->items_by_name); |
818 | - while (target == NULL && g_hash_table_iter_next (&iter, &key, &value)) |
819 | - if (value == item) |
820 | - target = key; |
821 | - |
822 | - if (target != NULL) |
823 | - g_hash_table_insert (*attributes, G_MENU_ATTRIBUTE_TARGET, g_variant_ref_sink (g_variant_new_string (target))); |
824 | - } |
825 | - else if (unity_gtk_menu_item_get_draw_as_radio (item)) |
826 | - g_hash_table_insert (*attributes, G_MENU_ATTRIBUTE_TARGET, g_variant_ref_sink (g_variant_new_string (action->name))); |
827 | - |
828 | - g_free (name); |
829 | + if (action->name != NULL) |
830 | + { |
831 | + gchar *name = g_strdup_printf ("unity.%s", action->name); |
832 | + GVariant *variant = g_variant_ref_sink (g_variant_new_string (name)); |
833 | + |
834 | + g_hash_table_insert (*attributes, G_MENU_ATTRIBUTE_ACTION, variant); |
835 | + |
836 | + if (action->items_by_name != NULL) |
837 | + { |
838 | + GHashTableIter iter; |
839 | + gpointer key; |
840 | + gpointer value; |
841 | + const gchar *target = NULL; |
842 | + |
843 | + g_hash_table_iter_init (&iter, action->items_by_name); |
844 | + while (target == NULL && g_hash_table_iter_next (&iter, &key, &value)) |
845 | + if (value == item) |
846 | + target = key; |
847 | + |
848 | + if (target != NULL) |
849 | + g_hash_table_insert (*attributes, G_MENU_ATTRIBUTE_TARGET, g_variant_ref_sink (g_variant_new_string (target))); |
850 | + } |
851 | + else if (unity_gtk_menu_item_get_draw_as_radio (item)) |
852 | + g_hash_table_insert (*attributes, G_MENU_ATTRIBUTE_TARGET, g_variant_ref_sink (g_variant_new_string (action->name))); |
853 | + |
854 | + g_free (name); |
855 | + } |
856 | + |
857 | + if (action->subname != NULL) |
858 | + { |
859 | + gchar *subname = g_strdup_printf ("unity.%s", action->subname); |
860 | + GVariant *variant = g_variant_ref_sink (g_variant_new_string (subname)); |
861 | + g_hash_table_insert (*attributes, G_MENU_ATTRIBUTE_SUBMENU_ACTION, variant); |
862 | + g_free (subname); |
863 | + } |
864 | } |
865 | |
866 | if (item->menu_item != NULL) |
867 | |
868 | === modified file 'lib/unity-gtk-menu-shell.c' |
869 | --- lib/unity-gtk-menu-shell.c 2014-03-27 19:52:20 +0000 |
870 | +++ lib/unity-gtk-menu-shell.c 2014-06-26 14:42:27 +0000 |
871 | @@ -449,8 +449,8 @@ |
872 | g_return_if_fail (UNITY_GTK_IS_MENU_ITEM (item)); |
873 | g_warn_if_fail (item->parent_shell == shell); |
874 | |
875 | - g_free (item->label); |
876 | - item->label = NULL; |
877 | + g_free (item->label_label); |
878 | + item->label_label = NULL; |
879 | |
880 | unity_gtk_menu_shell_update_item (shell, item); |
881 | } |
882 | @@ -582,6 +582,13 @@ |
883 | g_return_if_fail (UNITY_GTK_IS_MENU_ITEM (item)); |
884 | g_warn_if_fail (item->parent_shell == shell); |
885 | |
886 | + if (shell->action_group != NULL) |
887 | + { |
888 | + /* If a submenu was added or removed, we need to update the submenu action. */ |
889 | + unity_gtk_action_group_disconnect_item (shell->action_group, item); |
890 | + unity_gtk_action_group_connect_item (shell->action_group, item); |
891 | + } |
892 | + |
893 | if (item->child_shell_valid) |
894 | { |
895 | GtkMenuShell *old_submenu = item->child_shell != NULL ? item->child_shell->menu_shell : NULL; |
PASSED: Continuous integration, rev:335 jenkins. qa.ubuntu. com/job/ unity-gtk- module- ci/56/ jenkins. qa.ubuntu. com/job/ unity-gtk- module- utopic- amd64-ci/ 10 jenkins. qa.ubuntu. com/job/ unity-gtk- module- utopic- armhf-ci/ 10 jenkins. qa.ubuntu. com/job/ unity-gtk- module- utopic- armhf-ci/ 10/artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- gtk-module- ci/56/rebuild
http://