Mercurial > audlegacy
comparison src/audacious/sync-menu.c @ 3417:db83b4a786ed trunk
MacOS platform: Add support code for the MacOS menubar.
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Sun, 02 Sep 2007 22:32:57 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3416:820c2db12041 | 3417:db83b4a786ed |
---|---|
1 /* GTK+ Integration for the Mac OS X Menubar. | |
2 * | |
3 * Copyright (C) 2007 Pioneer Research Center USA, Inc. | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the | |
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
18 * Boston, MA 02111-1307, USA. | |
19 */ | |
20 | |
21 #include <gtk/gtk.h> | |
22 | |
23 #ifdef GDK_WINDOWING_QUARTZ | |
24 | |
25 #include <gdk/gdkkeysyms.h> | |
26 | |
27 #include <Carbon/Carbon.h> | |
28 | |
29 #include "sync-menu.h" | |
30 | |
31 | |
32 /* TODO | |
33 * | |
34 * - Setup shortcuts, possibly transforming ctrl->cmd | |
35 * - Sync menus | |
36 * - Create on demand? (can this be done with gtk+? ie fill in menu items when the menu is opened) | |
37 * - Figure out what to do per app/window... | |
38 * - Toggle/radio items | |
39 * | |
40 */ | |
41 | |
42 #define GTK_QUARTZ_MENU_CREATOR 'GTKC' | |
43 #define GTK_QUARTZ_ITEM_WIDGET 'GWID' | |
44 | |
45 | |
46 static void sync_menu_shell (GtkMenuShell *menu_shell, | |
47 MenuRef carbon_menu, | |
48 gboolean toplevel); | |
49 | |
50 | |
51 /* | |
52 * utility functions | |
53 */ | |
54 | |
55 static GtkWidget * | |
56 find_menu_label (GtkWidget *widget) | |
57 { | |
58 GtkWidget *label = NULL; | |
59 | |
60 if (GTK_IS_LABEL (widget)) | |
61 return widget; | |
62 | |
63 if (GTK_IS_CONTAINER (widget)) | |
64 { | |
65 GList *children; | |
66 GList *l; | |
67 | |
68 children = gtk_container_get_children (GTK_CONTAINER (widget)); | |
69 | |
70 for (l = children; l; l = l->next) | |
71 { | |
72 label = find_menu_label (l->data); | |
73 if (label) | |
74 break; | |
75 } | |
76 | |
77 g_list_free (children); | |
78 } | |
79 | |
80 return label; | |
81 } | |
82 | |
83 static const gchar * | |
84 get_menu_label_text (GtkWidget *menu_item, | |
85 GtkWidget **label) | |
86 { | |
87 *label = find_menu_label (menu_item); | |
88 if (!*label) | |
89 return NULL; | |
90 | |
91 return gtk_label_get_text (GTK_LABEL (*label)); | |
92 } | |
93 | |
94 static gboolean | |
95 accel_find_func (GtkAccelKey *key, | |
96 GClosure *closure, | |
97 gpointer data) | |
98 { | |
99 return (GClosure *) data == closure; | |
100 } | |
101 | |
102 | |
103 /* | |
104 * CarbonMenu functions | |
105 */ | |
106 | |
107 typedef struct | |
108 { | |
109 MenuRef menu; | |
110 } CarbonMenu; | |
111 | |
112 static GQuark carbon_menu_quark = 0; | |
113 | |
114 static CarbonMenu * | |
115 carbon_menu_new (void) | |
116 { | |
117 return g_slice_new0 (CarbonMenu); | |
118 } | |
119 | |
120 static void | |
121 carbon_menu_free (CarbonMenu *menu) | |
122 { | |
123 g_slice_free (CarbonMenu, menu); | |
124 } | |
125 | |
126 static CarbonMenu * | |
127 carbon_menu_get (GtkWidget *widget) | |
128 { | |
129 return g_object_get_qdata (G_OBJECT (widget), carbon_menu_quark); | |
130 } | |
131 | |
132 static void | |
133 carbon_menu_connect (GtkWidget *menu, | |
134 MenuRef menuRef) | |
135 { | |
136 CarbonMenu *carbon_menu = carbon_menu_get (menu); | |
137 | |
138 if (!carbon_menu) | |
139 { | |
140 carbon_menu = carbon_menu_new (); | |
141 | |
142 g_object_set_qdata_full (G_OBJECT (menu), carbon_menu_quark, | |
143 carbon_menu, | |
144 (GDestroyNotify) carbon_menu_free); | |
145 } | |
146 | |
147 carbon_menu->menu = menuRef; | |
148 } | |
149 | |
150 | |
151 /* | |
152 * CarbonMenuItem functions | |
153 */ | |
154 | |
155 typedef struct | |
156 { | |
157 MenuRef menu; | |
158 MenuItemIndex index; | |
159 MenuRef submenu; | |
160 GClosure *accel_closure; | |
161 } CarbonMenuItem; | |
162 | |
163 static GQuark carbon_menu_item_quark = 0; | |
164 | |
165 static CarbonMenuItem * | |
166 carbon_menu_item_new (void) | |
167 { | |
168 return g_slice_new0 (CarbonMenuItem); | |
169 } | |
170 | |
171 static void | |
172 carbon_menu_item_free (CarbonMenuItem *menu_item) | |
173 { | |
174 if (menu_item->accel_closure) | |
175 g_closure_unref (menu_item->accel_closure); | |
176 | |
177 g_slice_free (CarbonMenuItem, menu_item); | |
178 } | |
179 | |
180 static CarbonMenuItem * | |
181 carbon_menu_item_get (GtkWidget *widget) | |
182 { | |
183 return g_object_get_qdata (G_OBJECT (widget), carbon_menu_item_quark); | |
184 } | |
185 | |
186 static void | |
187 carbon_menu_item_update_state (CarbonMenuItem *carbon_item, | |
188 GtkWidget *widget) | |
189 { | |
190 gboolean sensitive; | |
191 gboolean visible; | |
192 UInt32 set_attrs = 0; | |
193 UInt32 clear_attrs = 0; | |
194 | |
195 g_object_get (widget, | |
196 "sensitive", &sensitive, | |
197 "visible", &visible, | |
198 NULL); | |
199 | |
200 if (!sensitive) | |
201 set_attrs |= kMenuItemAttrDisabled; | |
202 else | |
203 clear_attrs |= kMenuItemAttrDisabled; | |
204 | |
205 if (!visible) | |
206 set_attrs |= kMenuItemAttrHidden; | |
207 else | |
208 clear_attrs |= kMenuItemAttrHidden; | |
209 | |
210 ChangeMenuItemAttributes (carbon_item->menu, carbon_item->index, | |
211 set_attrs, clear_attrs); | |
212 } | |
213 | |
214 static void | |
215 carbon_menu_item_update_active (CarbonMenuItem *carbon_item, | |
216 GtkWidget *widget) | |
217 { | |
218 gboolean active; | |
219 | |
220 g_object_get (widget, | |
221 "active", &active, | |
222 NULL); | |
223 | |
224 CheckMenuItem (carbon_item->menu, carbon_item->index, | |
225 active); | |
226 } | |
227 | |
228 static void | |
229 carbon_menu_item_update_submenu (CarbonMenuItem *carbon_item, | |
230 GtkWidget *widget) | |
231 { | |
232 GtkWidget *submenu; | |
233 | |
234 submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); | |
235 | |
236 if (submenu) | |
237 { | |
238 GtkWidget *label = NULL; | |
239 const gchar *label_text; | |
240 CFStringRef cfstr = NULL; | |
241 | |
242 label_text = get_menu_label_text (widget, &label); | |
243 if (label_text) | |
244 cfstr = CFStringCreateWithCString (NULL, label_text, | |
245 kCFStringEncodingUTF8); | |
246 | |
247 CreateNewMenu (0, 0, &carbon_item->submenu); | |
248 SetMenuTitleWithCFString (carbon_item->submenu, cfstr); | |
249 SetMenuItemHierarchicalMenu (carbon_item->menu, carbon_item->index, | |
250 carbon_item->submenu); | |
251 | |
252 sync_menu_shell (GTK_MENU_SHELL (submenu), carbon_item->submenu, FALSE); | |
253 | |
254 if (cfstr) | |
255 CFRelease (cfstr); | |
256 } | |
257 else | |
258 { | |
259 SetMenuItemHierarchicalMenu (carbon_item->menu, carbon_item->index, | |
260 NULL); | |
261 carbon_item->submenu = NULL; | |
262 } | |
263 } | |
264 | |
265 static void | |
266 carbon_menu_item_update_label (CarbonMenuItem *carbon_item, | |
267 GtkWidget *widget) | |
268 { | |
269 GtkWidget *label; | |
270 const gchar *label_text; | |
271 CFStringRef cfstr = NULL; | |
272 | |
273 label_text = get_menu_label_text (widget, &label); | |
274 if (label_text) | |
275 cfstr = CFStringCreateWithCString (NULL, label_text, | |
276 kCFStringEncodingUTF8); | |
277 | |
278 SetMenuItemTextWithCFString (carbon_item->menu, carbon_item->index, | |
279 cfstr); | |
280 | |
281 if (cfstr) | |
282 CFRelease (cfstr); | |
283 } | |
284 | |
285 static void | |
286 carbon_menu_item_update_accelerator (CarbonMenuItem *carbon_item, | |
287 GtkWidget *widget) | |
288 { | |
289 GtkWidget *label; | |
290 | |
291 get_menu_label_text (widget, &label); | |
292 | |
293 if (GTK_IS_ACCEL_LABEL (label) && | |
294 GTK_ACCEL_LABEL (label)->accel_closure) | |
295 { | |
296 GtkAccelKey *key; | |
297 | |
298 key = gtk_accel_group_find (GTK_ACCEL_LABEL (label)->accel_group, | |
299 accel_find_func, | |
300 GTK_ACCEL_LABEL (label)->accel_closure); | |
301 | |
302 if (key && | |
303 key->accel_key && | |
304 key->accel_flags & GTK_ACCEL_VISIBLE) | |
305 { | |
306 GdkDisplay *display = gtk_widget_get_display (widget); | |
307 GdkKeymap *keymap = gdk_keymap_get_for_display (display); | |
308 GdkKeymapKey *keys; | |
309 gint n_keys; | |
310 | |
311 if (gdk_keymap_get_entries_for_keyval (keymap, key->accel_key, | |
312 &keys, &n_keys)) | |
313 { | |
314 UInt8 modifiers = 0; | |
315 | |
316 SetMenuItemCommandKey (carbon_item->menu, carbon_item->index, | |
317 true, keys[0].keycode); | |
318 | |
319 g_free (keys); | |
320 | |
321 if (key->accel_mods) | |
322 { | |
323 if (key->accel_mods & GDK_SHIFT_MASK) | |
324 modifiers |= kMenuShiftModifier; | |
325 | |
326 if (key->accel_mods & GDK_MOD1_MASK) | |
327 modifiers |= kMenuOptionModifier; | |
328 } | |
329 | |
330 if (!(key->accel_mods & GDK_CONTROL_MASK)) | |
331 { | |
332 modifiers |= kMenuNoCommandModifier; | |
333 } | |
334 | |
335 SetMenuItemModifiers (carbon_item->menu, carbon_item->index, | |
336 modifiers); | |
337 | |
338 return; | |
339 } | |
340 } | |
341 } | |
342 | |
343 /* otherwise, clear the menu shortcut */ | |
344 SetMenuItemModifiers (carbon_item->menu, carbon_item->index, | |
345 kMenuNoModifiers | kMenuNoCommandModifier); | |
346 ChangeMenuItemAttributes (carbon_item->menu, carbon_item->index, | |
347 0, kMenuItemAttrUseVirtualKey); | |
348 SetMenuItemCommandKey (carbon_item->menu, carbon_item->index, | |
349 false, 0); | |
350 } | |
351 | |
352 static void | |
353 carbon_menu_item_accel_changed (GtkAccelGroup *accel_group, | |
354 guint keyval, | |
355 GdkModifierType modifier, | |
356 GClosure *accel_closure, | |
357 GtkWidget *widget) | |
358 { | |
359 CarbonMenuItem *carbon_item = carbon_menu_item_get (widget); | |
360 GtkWidget *label; | |
361 | |
362 get_menu_label_text (widget, &label); | |
363 | |
364 if (GTK_IS_ACCEL_LABEL (label) && | |
365 GTK_ACCEL_LABEL (label)->accel_closure == accel_closure) | |
366 carbon_menu_item_update_accelerator (carbon_item, widget); | |
367 } | |
368 | |
369 static void | |
370 carbon_menu_item_update_accel_closure (CarbonMenuItem *carbon_item, | |
371 GtkWidget *widget) | |
372 { | |
373 GtkAccelGroup *group; | |
374 GtkWidget *label; | |
375 | |
376 get_menu_label_text (widget, &label); | |
377 | |
378 if (carbon_item->accel_closure) | |
379 { | |
380 group = gtk_accel_group_from_accel_closure (carbon_item->accel_closure); | |
381 | |
382 g_signal_handlers_disconnect_by_func (group, | |
383 carbon_menu_item_accel_changed, | |
384 widget); | |
385 | |
386 g_closure_unref (carbon_item->accel_closure); | |
387 carbon_item->accel_closure = NULL; | |
388 } | |
389 | |
390 if (GTK_IS_ACCEL_LABEL (label)) | |
391 carbon_item->accel_closure = GTK_ACCEL_LABEL (label)->accel_closure; | |
392 | |
393 if (carbon_item->accel_closure) | |
394 { | |
395 g_closure_ref (carbon_item->accel_closure); | |
396 | |
397 group = gtk_accel_group_from_accel_closure (carbon_item->accel_closure); | |
398 | |
399 g_signal_connect_object (group, "accel-changed", | |
400 G_CALLBACK (carbon_menu_item_accel_changed), | |
401 widget, 0); | |
402 } | |
403 | |
404 carbon_menu_item_update_accelerator (carbon_item, widget); | |
405 } | |
406 | |
407 static void | |
408 carbon_menu_item_notify (GObject *object, | |
409 GParamSpec *pspec, | |
410 CarbonMenuItem *carbon_item) | |
411 { | |
412 if (!strcmp (pspec->name, "sensitive") || | |
413 !strcmp (pspec->name, "visible")) | |
414 { | |
415 carbon_menu_item_update_state (carbon_item, GTK_WIDGET (object)); | |
416 } | |
417 else if (!strcmp (pspec->name, "active")) | |
418 { | |
419 carbon_menu_item_update_active (carbon_item, GTK_WIDGET (object)); | |
420 } | |
421 else if (!strcmp (pspec->name, "submenu")) | |
422 { | |
423 carbon_menu_item_update_submenu (carbon_item, GTK_WIDGET (object)); | |
424 } | |
425 } | |
426 | |
427 static void | |
428 carbon_menu_item_notify_label (GObject *object, | |
429 GParamSpec *pspec, | |
430 gpointer data) | |
431 { | |
432 CarbonMenuItem *carbon_item = carbon_menu_item_get (GTK_WIDGET (object)); | |
433 | |
434 if (!strcmp (pspec->name, "label")) | |
435 { | |
436 carbon_menu_item_update_label (carbon_item, | |
437 GTK_WIDGET (object)); | |
438 } | |
439 else if (!strcmp (pspec->name, "accel-closure")) | |
440 { | |
441 carbon_menu_item_update_accel_closure (carbon_item, | |
442 GTK_WIDGET (object)); | |
443 } | |
444 } | |
445 | |
446 static CarbonMenuItem * | |
447 carbon_menu_item_connect (GtkWidget *menu_item, | |
448 GtkWidget *label, | |
449 MenuRef menu, | |
450 MenuItemIndex index) | |
451 { | |
452 CarbonMenuItem *carbon_item = carbon_menu_item_get (menu_item); | |
453 | |
454 if (!carbon_item) | |
455 { | |
456 carbon_item = carbon_menu_item_new (); | |
457 | |
458 g_object_set_qdata_full (G_OBJECT (menu_item), carbon_menu_item_quark, | |
459 carbon_item, | |
460 (GDestroyNotify) carbon_menu_item_free); | |
461 | |
462 g_signal_connect (menu_item, "notify", | |
463 G_CALLBACK (carbon_menu_item_notify), | |
464 carbon_item); | |
465 | |
466 if (label) | |
467 g_signal_connect_swapped (label, "notify::label", | |
468 G_CALLBACK (carbon_menu_item_notify_label), | |
469 menu_item); | |
470 } | |
471 | |
472 carbon_item->menu = menu; | |
473 carbon_item->index = index; | |
474 | |
475 return carbon_item; | |
476 } | |
477 | |
478 | |
479 /* | |
480 * carbon event handler | |
481 */ | |
482 | |
483 static OSStatus | |
484 menu_event_handler_func (EventHandlerCallRef event_handler_call_ref, | |
485 EventRef event_ref, | |
486 void *data) | |
487 { | |
488 UInt32 event_class = GetEventClass (event_ref); | |
489 UInt32 event_kind = GetEventKind (event_ref); | |
490 MenuRef menu_ref; | |
491 | |
492 switch (event_class) | |
493 { | |
494 case kEventClassCommand: | |
495 /* This is called when activating (is that the right GTK+ term?) | |
496 * a menu item. | |
497 */ | |
498 if (event_kind == kEventCommandProcess) | |
499 { | |
500 HICommand command; | |
501 OSStatus err; | |
502 | |
503 //g_print ("Menu: kEventClassCommand/kEventCommandProcess\n"); | |
504 | |
505 err = GetEventParameter (event_ref, kEventParamDirectObject, | |
506 typeHICommand, 0, | |
507 sizeof (command), 0, &command); | |
508 | |
509 if (err == noErr) | |
510 { | |
511 GtkWidget *widget = NULL; | |
512 | |
513 if (command.commandID == kHICommandQuit) | |
514 { | |
515 gtk_main_quit (); /* Just testing... */ | |
516 return noErr; | |
517 } | |
518 | |
519 /* Get any GtkWidget associated with the item. */ | |
520 err = GetMenuItemProperty (command.menu.menuRef, | |
521 command.menu.menuItemIndex, | |
522 GTK_QUARTZ_MENU_CREATOR, | |
523 GTK_QUARTZ_ITEM_WIDGET, | |
524 sizeof (widget), 0, &widget); | |
525 if (err == noErr && widget) | |
526 { | |
527 gtk_menu_item_activate (GTK_MENU_ITEM (widget)); | |
528 return noErr; | |
529 } | |
530 } | |
531 } | |
532 break; | |
533 | |
534 case kEventClassMenu: | |
535 GetEventParameter (event_ref, | |
536 kEventParamDirectObject, | |
537 typeMenuRef, | |
538 NULL, | |
539 sizeof (menu_ref), | |
540 NULL, | |
541 &menu_ref); | |
542 | |
543 switch (event_kind) | |
544 { | |
545 case kEventMenuTargetItem: | |
546 /* This is called when an item is selected (what is the | |
547 * GTK+ term? prelight?) | |
548 */ | |
549 //g_print ("kEventClassMenu/kEventMenuTargetItem\n"); | |
550 break; | |
551 | |
552 case kEventMenuOpening: | |
553 /* Is it possible to dynamically build the menu here? We | |
554 * can at least set visibility/sensitivity. | |
555 */ | |
556 //g_print ("kEventClassMenu/kEventMenuOpening\n"); | |
557 break; | |
558 | |
559 case kEventMenuClosed: | |
560 //g_print ("kEventClassMenu/kEventMenuClosed\n"); | |
561 break; | |
562 | |
563 default: | |
564 break; | |
565 } | |
566 | |
567 break; | |
568 | |
569 default: | |
570 break; | |
571 } | |
572 | |
573 return CallNextEventHandler (event_handler_call_ref, event_ref); | |
574 } | |
575 | |
576 static void | |
577 setup_menu_event_handler (void) | |
578 { | |
579 EventHandlerUPP menu_event_handler_upp; | |
580 EventHandlerRef menu_event_handler_ref; | |
581 const EventTypeSpec menu_events[] = { | |
582 { kEventClassCommand, kEventCommandProcess }, | |
583 { kEventClassMenu, kEventMenuTargetItem }, | |
584 { kEventClassMenu, kEventMenuOpening }, | |
585 { kEventClassMenu, kEventMenuClosed } | |
586 }; | |
587 | |
588 /* FIXME: We might have to install one per window? */ | |
589 | |
590 menu_event_handler_upp = NewEventHandlerUPP (menu_event_handler_func); | |
591 InstallEventHandler (GetApplicationEventTarget (), menu_event_handler_upp, | |
592 GetEventTypeCount (menu_events), menu_events, 0, | |
593 &menu_event_handler_ref); | |
594 | |
595 #if 0 | |
596 /* FIXME: Remove the handler with: */ | |
597 RemoveEventHandler(menu_event_handler_ref); | |
598 DisposeEventHandlerUPP(menu_event_handler_upp); | |
599 #endif | |
600 } | |
601 | |
602 static void | |
603 sync_menu_shell (GtkMenuShell *menu_shell, | |
604 MenuRef carbon_menu, | |
605 gboolean toplevel) | |
606 { | |
607 GList *children; | |
608 GList *l; | |
609 MenuItemIndex carbon_index = 1; | |
610 | |
611 carbon_menu_connect (GTK_WIDGET (menu_shell), carbon_menu); | |
612 | |
613 children = gtk_container_get_children (GTK_CONTAINER (menu_shell)); | |
614 | |
615 for (l = children; l; l = l->next) | |
616 { | |
617 GtkWidget *menu_item = l->data; | |
618 CarbonMenuItem *carbon_item; | |
619 | |
620 if (GTK_IS_TEAROFF_MENU_ITEM (menu_item)) | |
621 continue; | |
622 | |
623 if (toplevel && g_object_get_data (G_OBJECT (menu_item), "gtk-empty-menu-item")) | |
624 continue; | |
625 | |
626 carbon_item = carbon_menu_item_get (menu_item); | |
627 | |
628 if (carbon_item && carbon_item->index != carbon_index) | |
629 { | |
630 DeleteMenuItem (carbon_item->menu, | |
631 carbon_item->index); | |
632 carbon_item = NULL; | |
633 } | |
634 | |
635 if (!carbon_item) | |
636 { | |
637 GtkWidget *label = NULL; | |
638 const gchar *label_text; | |
639 CFStringRef cfstr = NULL; | |
640 MenuItemAttributes attributes = 0; | |
641 | |
642 label_text = get_menu_label_text (menu_item, &label); | |
643 if (label_text) | |
644 cfstr = CFStringCreateWithCString (NULL, label_text, | |
645 kCFStringEncodingUTF8); | |
646 | |
647 if (GTK_IS_SEPARATOR_MENU_ITEM (menu_item)) | |
648 attributes |= kMenuItemAttrSeparator; | |
649 | |
650 if (!GTK_WIDGET_IS_SENSITIVE (menu_item)) | |
651 attributes |= kMenuItemAttrDisabled; | |
652 | |
653 if (!GTK_WIDGET_VISIBLE (menu_item)) | |
654 attributes |= kMenuItemAttrHidden; | |
655 | |
656 InsertMenuItemTextWithCFString (carbon_menu, cfstr, | |
657 carbon_index, | |
658 attributes, 0); | |
659 SetMenuItemProperty (carbon_menu, carbon_index, | |
660 GTK_QUARTZ_MENU_CREATOR, | |
661 GTK_QUARTZ_ITEM_WIDGET, | |
662 sizeof (menu_item), &menu_item); | |
663 | |
664 if (cfstr) | |
665 CFRelease (cfstr); | |
666 | |
667 carbon_item = carbon_menu_item_connect (menu_item, label, | |
668 carbon_menu, | |
669 carbon_index); | |
670 | |
671 if (GTK_IS_CHECK_MENU_ITEM (menu_item)) | |
672 carbon_menu_item_update_active (carbon_item, menu_item); | |
673 | |
674 carbon_menu_item_update_accel_closure (carbon_item, menu_item); | |
675 | |
676 if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item))) | |
677 carbon_menu_item_update_submenu (carbon_item, menu_item); | |
678 } | |
679 | |
680 carbon_index++; | |
681 } | |
682 | |
683 g_list_free (children); | |
684 } | |
685 | |
686 void | |
687 sync_menu_takeover_menu (GtkMenuShell *menu_shell) | |
688 { | |
689 MenuRef carbon_menubar; | |
690 | |
691 g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); | |
692 | |
693 if (carbon_menu_quark == 0) | |
694 carbon_menu_quark = g_quark_from_static_string ("CarbonMenu"); | |
695 | |
696 if (carbon_menu_item_quark == 0) | |
697 carbon_menu_item_quark = g_quark_from_static_string ("CarbonMenuItem"); | |
698 | |
699 CreateNewMenu (0 /*id*/, 0 /*options*/, &carbon_menubar); | |
700 SetRootMenu (carbon_menubar); | |
701 | |
702 setup_menu_event_handler (); | |
703 | |
704 sync_menu_shell (menu_shell, carbon_menubar, TRUE); | |
705 } | |
706 | |
707 #else | |
708 | |
709 void | |
710 sync_menu_takeover_menu (GtkMenuShell *menu_shell) | |
711 { | |
712 | |
713 } | |
714 | |
715 #endif |