27 #include <sigc++/signal.h>
28 #include <sigc++/slot.h>
32 #include <gdk/gdkkeysyms.h>
36 #import <AppKit/NSMenu.h>
37 #import <AppKit/NSMenuItem.h>
38 #import <AppKit/NSCell.h>
39 #import <AppKit/NSEvent.h>
40 #import <AppKit/NSApplication.h>
41 #import <Foundation/NSString.h>
42 #import <Foundation/NSNotification.h>
44 #define UNUSED_PARAMETER(a) (void) (a)
47 #define DEBUG(format, ...)
65 return NSBackspaceCharacter;
67 return NSDeleteFunctionKey;
69 return NSPauseFunctionKey;
71 return NSScrollLockFunctionKey;
73 return NSSysReqFunctionKey;
75 return NSHomeFunctionKey;
78 return NSLeftArrowFunctionKey;
81 return NSUpArrowFunctionKey;
84 return NSRightArrowFunctionKey;
87 return NSDownArrowFunctionKey;
89 return NSPageUpFunctionKey;
91 return NSPageDownFunctionKey;
93 return NSEndFunctionKey;
95 return NSBeginFunctionKey;
97 return NSSelectFunctionKey;
99 return NSPrintFunctionKey;
101 return NSExecuteFunctionKey;
103 return NSInsertFunctionKey;
105 return NSUndoFunctionKey;
107 return NSRedoFunctionKey;
109 return NSMenuFunctionKey;
111 return NSFindFunctionKey;
113 return NSHelpFunctionKey;
115 return NSBreakFunctionKey;
116 case GDK_Mode_switch:
117 return NSModeSwitchFunctionKey;
119 return NSF1FunctionKey;
121 return NSF2FunctionKey;
123 return NSF3FunctionKey;
125 return NSF4FunctionKey;
127 return NSF5FunctionKey;
129 return NSF6FunctionKey;
131 return NSF7FunctionKey;
133 return NSF8FunctionKey;
135 return NSF9FunctionKey;
137 return NSF10FunctionKey;
139 return NSF11FunctionKey;
141 return NSF12FunctionKey;
143 return NSF13FunctionKey;
145 return NSF14FunctionKey;
147 return NSF15FunctionKey;
149 return NSF16FunctionKey;
151 return NSF17FunctionKey;
153 return NSF18FunctionKey;
155 return NSF19FunctionKey;
157 return NSF20FunctionKey;
159 return NSF21FunctionKey;
161 return NSF22FunctionKey;
163 return NSF23FunctionKey;
165 return NSF24FunctionKey;
167 return NSF25FunctionKey;
169 return NSF26FunctionKey;
171 return NSF27FunctionKey;
173 return NSF28FunctionKey;
175 return NSF29FunctionKey;
177 return NSF30FunctionKey;
179 return NSF31FunctionKey;
181 return NSF32FunctionKey;
183 return NSF33FunctionKey;
185 return NSF34FunctionKey;
187 return NSF35FunctionKey;
209 case GDK_KP_Page_Down:
215 case GDK_KP_Multiply:
217 case GDK_KP_Separator:
218 case GDK_KP_Subtract:
263 case GDK_KP_Page_Down:
264 return GDK_Page_Down;
275 case GDK_KP_Multiply:
279 case GDK_KP_Subtract:
309 return GDK_VoidSymbol;
460 case GDK_bracketleft:
464 case GDK_bracketright:
466 case GDK_asciicircum:
543 gtk_menu_item_activate ((GtkMenuItem*) data);
553 - (id) initWithTitle:(NSString*) title andGtkWidget:(GtkMenuItem*) w;
554 - (void) activate:(
id) sender;
558 - (id) initWithTitle:(NSString*) title andGtkWidget:(GtkMenuItem*) w
563 self = [
super initWithTitle:title action:@selector(activate:) keyEquivalent:@"" ];
567 [
self setTarget:self ];
573 - (void) activate:(
id) sender
592 GtkWidget *label = NULL;
594 if (GTK_IS_LABEL (widget))
597 if (GTK_IS_CONTAINER (widget))
602 children = gtk_container_get_children (GTK_CONTAINER (widget));
604 for (l = children; l; l = l->next)
611 g_list_free (children);
628 return gtk_label_get_text (GTK_LABEL (my_label));
638 return (GClosure *) data == closure;
657 NSMenu* menu = (NSMenu*) ptr;
704 g_object_get (widget,
705 "sensitive", &sensitive,
710 [cocoa_item setEnabled:NO];
712 [cocoa_item setEnabled:YES];
717 [cocoa_item setHidden:YES];
719 [cocoa_item setHidden:NO];
729 g_object_get (widget,
"active", &active, NULL);
732 [cocoa_item setState:NSOnState];
734 [cocoa_item setState:NSOffState];
743 g_return_if_fail (cocoa_item != NULL);
744 g_return_if_fail (widget != NULL);
746 submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
750 GtkWidget* label = NULL;
751 const gchar *label_text;
752 NSMenu* cocoa_submenu;
759 cocoa_submenu = [ [ NSMenu alloc ] initWithTitle:[ [ NSString alloc] initWithCString:label_text encoding:NSUTF8StringEncoding]];
761 cocoa_submenu = [ [ NSMenu alloc ] initWithTitle:@""];
763 [cocoa_submenu setAutoenablesItems:NO];
770 [ cocoa_item setSubmenu:cocoa_submenu];
775 [ cocoa_submenu release ];
783 const gchar *label_text;
785 g_return_if_fail (cocoa_item != NULL);
786 g_return_if_fail (widget != NULL);
790 [cocoa_item setTitle:[ [ NSString alloc] initWithCString:label_text encoding:NSUTF8StringEncoding]];
792 [cocoa_item setTitle:@""];
801 g_return_if_fail (cocoa_item != NULL);
802 g_return_if_fail (widget != NULL);
813 if (GTK_IS_ACCEL_LABEL (label) &&
818 key = gtk_accel_group_find (GTK_ACCEL_LABEL (label)->accel_group,
824 key->accel_flags & GTK_ACCEL_VISIBLE)
827 const gchar* str = NULL;
828 guint actual_key = key->accel_key;
833 [cocoa_item setKeyEquivalent:@""];
836 modifiers |= NSNumericPadKeyMask;
844 modifiers |= NSShiftKeyMask;
850 unichar ukey = str[0];
851 [cocoa_item setKeyEquivalent:[NSString stringWithCharacters:&ukey length:1]];
855 [cocoa_item setKeyEquivalent:[NSString stringWithCharacters:&ukey length:1]];
858 [cocoa_item setKeyEquivalent:@""];
863 if (key->accel_mods || modifiers)
865 if (key->accel_mods & GDK_SHIFT_MASK) {
866 modifiers |= NSShiftKeyMask;
871 if (key->accel_mods & (GDK_MOD1_MASK)) {
872 modifiers |= NSAlternateKeyMask;
875 if (key->accel_mods & GDK_CONTROL_MASK) {
876 modifiers |= NSControlKeyMask;
881 if (key->accel_mods & GDK_META_MASK) {
882 modifiers |= NSCommandKeyMask;
886 [cocoa_item setKeyEquivalentModifierMask:modifiers];
892 [cocoa_item setKeyEquivalent:@""];
911 if (GTK_IS_ACCEL_LABEL (label) &&
912 GTK_ACCEL_LABEL (label)->accel_closure == accel_closure)
920 GtkAccelGroup *group;
927 group = gtk_accel_group_from_accel_closure (cocoa_item->
accel_closure);
929 g_signal_handlers_disconnect_by_func (group,
937 if (GTK_IS_ACCEL_LABEL (label)) {
938 cocoa_item->
accel_closure = GTK_ACCEL_LABEL (label)->accel_closure;
945 group = gtk_accel_group_from_accel_closure (cocoa_item->
accel_closure);
947 g_signal_connect_object (group,
"accel-changed",
949 widget, (GConnectFlags) 0);
967 if (!strcmp (pspec->name,
"label"))
970 GTK_WIDGET (
object));
972 else if (!strcmp (pspec->name,
"accel-closure"))
975 GTK_WIDGET (
object));
982 NSMenuItem *cocoa_item)
987 if (!strcmp (pspec->name,
"sensitive") ||
988 !strcmp (pspec->name,
"visible"))
992 else if (!strcmp (pspec->name,
"active"))
996 else if (!strcmp (pspec->name,
"submenu"))
1009 [cocoa_item retain];
1020 g_signal_connect (menu_item,
"notify",
1025 g_signal_connect_swapped (label,
"notify::label",
1034 GtkWidget* label = NULL;
1038 [[cocoa_menu title] cStringUsingEncoding:NSUTF8StringEncoding],
1039 GTK_IS_SEPARATOR_MENU_ITEM(menu_item));
1046 if (GTK_IS_SEPARATOR_MENU_ITEM (menu_item)) {
1047 cocoa_item = [NSMenuItem separatorItem];
1048 DEBUG (
"\ta separator\n");
1051 if (!GTK_WIDGET_VISIBLE (menu_item)) {
1052 DEBUG (
"\tnot visible\n");
1059 cocoa_item = [ [
GNSMenuItem alloc] initWithTitle:[ [ NSString alloc] initWithCString:label_text encoding:NSUTF8StringEncoding]
1060 andGtkWidget:(GtkMenuItem*)menu_item];
1062 cocoa_item = [ [
GNSMenuItem alloc] initWithTitle:@"" andGtkWidget:(GtkMenuItem*)menu_item];
1063 DEBUG (
"\tan item\n");
1069 [ cocoa_item setEnabled:YES];
1071 [ cocoa_menu insertItem:cocoa_item atIndex:index];
1073 [ cocoa_menu addItem:cocoa_item];
1075 if (!GTK_WIDGET_IS_SENSITIVE (menu_item))
1076 [cocoa_item setState:NSOffState];
1078 #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4
1079 if (!GTK_WIDGET_VISIBLE (menu_item))
1080 [cocoa_item setHidden:YES];
1083 if (GTK_IS_CHECK_MENU_ITEM (menu_item))
1086 if (!GTK_IS_SEPARATOR_MENU_ITEM (menu_item))
1089 if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item)))
1092 [ cocoa_item release];
1104 children = gtk_container_get_children (GTK_CONTAINER (menu_shell));
1106 for (l = children; l; l = l->next)
1108 GtkWidget *menu_item = (GtkWidget*) l->data;
1110 if (GTK_IS_TEAROFF_MENU_ITEM (menu_item))
1113 if (g_object_get_data (G_OBJECT (menu_item),
"gtk-empty-menu-item"))
1119 g_list_free (children);
1128 const GValue* param_values,
1131 GtkWidget *instance = (GtkWidget*) g_value_get_object (param_values);
1133 if (GTK_IS_MENU_ITEM (instance))
1135 GtkWidget *previous_parent = (GtkWidget*) g_value_get_object (param_values + 1);
1136 GtkWidget *menu_shell = NULL;
1138 if (GTK_IS_MENU_SHELL (previous_parent))
1140 menu_shell = previous_parent;
1142 else if (GTK_IS_MENU_SHELL (instance->parent))
1144 menu_shell = instance->parent;
1155 cocoa_menu == (NSMenu*) data,
1167 g_signal_remove_emission_hook (g_signal_lookup (
"parent-set", GTK_TYPE_WIDGET),
1173 #warning You can safely ignore the next warning about a duplicate interface definition
1175 - (void)setAppleMenu:(NSMenu *)aMenu;
1185 NSMenuItem *dummyItem = [[NSMenuItem alloc] initWithTitle:@""
1186 action:nil keyEquivalent:@""];
1187 [dummyItem setSubmenu:menu];
1188 [_main_menubar addItem:dummyItem];
1189 [dummyItem release];
1195 add_to_app_menu (NSMenu *menu)
1197 NSMenuItem *dummyItem = [[NSMenuItem alloc] initWithTitle:@""
1198 action:nil keyEquivalent:@""];
1199 [dummyItem setSubmenu:menu];
1200 [_app_menu addItem:dummyItem];
1201 [dummyItem release];
1209 NSMenuItem *menuitem;
1211 _app_menu = [[NSMenu alloc] initWithTitle: @"Apple Menu"];
1213 NSMenu *menuServices = [[NSMenu alloc] initWithTitle: @"Services"];
1214 [NSApp setServicesMenu:menuServices];
1216 [_app_menu addItem: [NSMenuItem separatorItem]];
1217 menuitem = [[NSMenuItem alloc] initWithTitle: @"Services"
1218 action:nil keyEquivalent:@""];
1219 [menuitem setSubmenu:menuServices];
1220 [_app_menu addItem: menuitem];
1222 [_app_menu addItem: [NSMenuItem separatorItem]];
1223 menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide"
1224 action:@selector(hide:) keyEquivalent:@""];
1225 [menuitem setTarget: NSApp];
1226 [_app_menu addItem: menuitem];
1228 menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide Others"
1229 action:@selector(hideOtherApplications:) keyEquivalent:@""];
1230 [menuitem setTarget: NSApp];
1231 [_app_menu addItem: menuitem];
1233 menuitem = [[NSMenuItem alloc] initWithTitle:@"Show All"
1234 action:@selector(unhideAllApplications:) keyEquivalent:@""];
1235 [menuitem setTarget: NSApp];
1236 [_app_menu addItem: menuitem];
1238 [_app_menu addItem: [NSMenuItem separatorItem]];
1239 menuitem = [[NSMenuItem alloc] initWithTitle:@"Quit"
1240 action:@selector(terminate:) keyEquivalent:@"q"];
1241 [menuitem setTarget: NSApp];
1242 [_app_menu addItem: menuitem];
1245 [NSApp setAppleMenu:_app_menu];
1253 add_to_window_menu (NSMenu *menu)
1255 NSMenuItem *dummyItem = [[NSMenuItem alloc] initWithTitle:@""
1256 action:nil keyEquivalent:@""];
1257 [dummyItem setSubmenu:menu];
1258 [_window_menu addItem:dummyItem];
1259 [dummyItem release];
1264 create_window_menu ()
1266 _window_menu = [[NSMenu alloc] initWithTitle: @"Window"];
1268 [_window_menu addItemWithTitle:@"Minimize"
1269 action:@selector(performMiniaturize:) keyEquivalent:@""];
1270 [_window_menu addItem: [NSMenuItem separatorItem]];
1271 [_window_menu addItemWithTitle:@"Bring All to Front"
1272 action:@selector(arrangeInFront:) keyEquivalent:@""];
1274 [NSApp setWindowsMenu:_window_menu];
1288 NSMenu* cocoa_menubar;
1290 g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
1298 cocoa_menubar = [ [ NSApplication sharedApplication] mainMenu];
1304 [cocoa_menubar setAutoenablesItems:NO];
1307 g_signal_add_emission_hook (g_signal_lookup (
"parent-set",
1311 cocoa_menubar, NULL);
1314 g_signal_connect (menu_shell,
"destroy",
1323 GtkMenuItem *menu_item)
1328 NSMenuItem *firstItem;
1332 mainMenu = [NSApp mainMenu];
1333 firstItem = [ mainMenu itemAtIndex:0];
1334 appMenu = [ firstItem submenu ];
1336 g_return_if_fail (group != NULL);
1337 g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
1343 index += g_list_length (list_group->items);
1348 if (list_group->items && list->prev)
1351 if (group == list_group)
1357 if (!group->items && list->prev)
1359 [appMenu insertItem:[NSMenuItem separatorItem] atIndex:index+1];
1365 group->items = g_list_append (group->items, menu_item);
1366 gtk_widget_hide (GTK_WIDGET (menu_item));
1372 g_warning (
"%s: app menu group %p does not exist",
1379 #include <glibmm/ustring.h>
1382 namespace Application {
1396 self = [
super init ];
1399 [[NSNotificationCenter defaultCenter] addObserver:self
1400 selector:@selector(appDidBecomeActive:)
1401 name:NSApplicationDidBecomeActiveNotification
1402 object:[NSApplication sharedApplication]];
1404 [[NSNotificationCenter defaultCenter] addObserver:self
1405 selector:@selector(appDidBecomeInactive:)
1406 name:NSApplicationWillResignActiveNotification
1407 object:[NSApplication sharedApplication]];
1413 - (void)appDidBecomeActive:(NSNotification *) notification
1419 - (void)appDidBecomeInactive:(NSNotification *) notification
1428 -(BOOL) application:(NSApplication*) app openFile:(NSString*) file;
1429 - (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *) app;
1433 -(BOOL) application:(NSApplication*) app openFile:(NSString*) file
1436 Glib::ustring utf8_path ([file UTF8String]);
1440 - (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *) app
1444 return NSTerminateCancel;
1459 [NSApp setMainMenu: _main_menubar];
1474 [ NSApp finishLaunching ];
1475 [[NSApplication sharedApplication] activateIgnoringOtherApps : YES];
1484 [ _window_menu release ];
1488 [ _app_menu release ];
1492 [ _main_menubar release ];
static void push_menu_shell_to_nsmenu(GtkMenuShell *menu_shell, NSMenu *menu, gboolean toplevel, gboolean debug)
static void cocoa_menu_free(gpointer *ptr)
static void cocoa_menu_item_update_submenu(NSMenuItem *cocoa_item, GtkWidget *widget)
void gtk_application_ready()
static Application * instance()
#define DEBUG(format,...)
static GtkWidget * find_menu_label(GtkWidget *widget)
void gtk_application_cleanup()
static void add_menu_item(NSMenu *cocoa_menu, GtkWidget *menu_item, int index)
static gboolean accel_find_func(GtkAccelKey *, GClosure *closure, gpointer data)
static void cocoa_menu_item_update_accel_closure(GNSMenuItem *cocoa_item, GtkWidget *widget)
static void cocoa_menu_item_free(gpointer *ptr)
static void cocoa_menu_item_connect(GtkWidget *menu_item, GNSMenuItem *cocoa_menu_item, GtkWidget *label)
static gulong emission_hook_id
GList * _gtk_application_menu_groups
static GQuark cocoa_menu_item_quark
void gtk_application_set_menu_bar(GtkMenuShell *menu_shell)
int gtk_application_init()
typedefG_BEGIN_DECLS struct _GtkApplicationMenuGroup GtkApplicationMenuGroup
static NSMenu * _main_menubar
static void cocoa_menu_connect(GtkWidget *menu, NSMenu *cocoa_menu)
sigc::signal< void > ShouldQuit
static gboolean keyval_is_keypad(guint keyval)
static gboolean idle_call_activate(gpointer data)
static const gchar * get_menu_label_text(GtkWidget *menu_item, GtkWidget **label)
sigc::signal< void, bool > ActivationChanged
static void cocoa_menu_item_update_state(NSMenuItem *cocoa_item, GtkWidget *widget)
static NSMenu * cocoa_menu_get(GtkWidget *widget)
static void cocoa_menu_item_notify(GObject *object, GParamSpec *pspec, NSMenuItem *cocoa_item)
sigc::signal< void, const Glib::ustring & > ShouldLoad
static const struct @24 modifiers[]
static const gchar * gdk_quartz_keyval_to_string(guint keyval)
static int add_to_menubar(NSMenu *menu)
static GQuark cocoa_menu_quark
static gboolean keyval_is_uppercase(guint keyval)
static GNSMenuItem * cocoa_menu_item_get(GtkWidget *widget)
LIBARDOUR_API PBD::PropertyDescriptor< bool > active
static NSMenu * _app_menu
sigc::signal< void, const Glib::ustring & > ShouldLoad
static gboolean parent_set_emission_hook(GSignalInvocationHint *, guint, const GValue *param_values, gpointer data)
static int _in_menu_event_handler
static void cocoa_menu_item_update_accelerator(NSMenuItem *cocoa_item, GtkWidget *widget)
void gtk_application_add_app_menu_item(GtkApplicationMenuGroup *group, GtkMenuItem *menu_item)
static void cocoa_menu_item_notify_label(GObject *object, GParamSpec *pspec, gpointer)
static NSMenu * _window_menu
#define UNUSED_PARAMETER(a)
sigc::signal< void > ShouldQuit
static void parent_set_emission_hook_remove(GtkWidget *, gpointer)
static void cocoa_menu_item_accel_changed(GtkAccelGroup *, guint, GdkModifierType, GClosure *accel_closure, GtkWidget *widget)
static void cocoa_menu_item_update_label(NSMenuItem *cocoa_item, GtkWidget *widget)
static guint gdk_quartz_keyval_to_ns_keyval(guint keyval)
static void cocoa_menu_item_update_active(NSMenuItem *cocoa_item, GtkWidget *widget)
sigc::signal< void, bool > ActivationChanged
LIBARDOUR_API bool init(bool with_vst, bool try_optimization, const char *localedir)
static int create_apple_menu()
static guint keyval_keypad_nonkeypad_equivalent(guint keyval)
int gdk_quartz_in_menu_event_handler()