(x_activate_menubar): Update the whole menu.
(trackingNotification:): Call ns_check_menu_open if tracking ends.
(menuWillOpen:): Increment trackingMenu. For OSX <= 10.6, exit if
current event is not NSSystemDefined.
Call ns_check_menu_open only if trackingMenu is 2.
(menuDidClose:): New method, decrease trackingMenu.
(fillWithWidgetValue:setDelegate:): New method.
(fillWithWidgetValue:): Call the above.
* nsterm.h (EmacsMenu): Add fillWithWidgetValue:setDelegate:
* nsterm.m (menu_pending_title, ns_get_pending_menu_title): Remove.
(ns_check_menu_open): Handle menu == nil. Remove assignment to
menu_pending_title.
Fixes: debbugs:15001
+2013-08-11 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsterm.m (menu_pending_title, ns_get_pending_menu_title): Remove.
+ (ns_check_menu_open): Handle menu == nil. Remove assignment to
+ menu_pending_title.
+
+ * nsmenu.m (ns_update_menubar): Call fillWithWidgetValue:setDelegate.
+ (x_activate_menubar): Update the whole menu.
+ (trackingNotification:): Call ns_check_menu_open if tracking ends.
+ (menuWillOpen:): Increment trackingMenu. For OSX <= 10.6, exit if
+ current event is not NSSystemDefined (Bug#15001).
+ Call ns_check_menu_open only if trackingMenu is 2.
+ (menuDidClose:): New method, decrease trackingMenu.
+ (fillWithWidgetValue:setDelegate:): New method.
+ (fillWithWidgetValue:): Call the above.
+
+ * nsterm.h (EmacsMenu): Add fillWithWidgetValue:setDelegate:
+
2013-08-11 Paul Eggert <eggert@cs.ucla.edu>
Omit some unnecessary casts.
}
else
{
- [menu fillWithWidgetValue: first_wv->contents];
+ [menu fillWithWidgetValue: first_wv->contents setDelegate:YES];
}
}
x_activate_menubar (struct frame *f)
{
#ifdef NS_IMPL_COCOA
- NSArray *a = [[NSApp mainMenu] itemArray];
- /* Update each submenu separately so ns_update_menubar doesn't reset
- the delegate. */
- int i = 0;
- while (i < [a count])
- {
- EmacsMenu *menu = (EmacsMenu *)[[a objectAtIndex:i] submenu];
- const char *title = [[menu title] UTF8String];
- if (strcmp (title, ns_get_pending_menu_title ()) == 0)
- {
- ns_update_menubar (f, true, menu);
- break;
- }
- ++i;
- }
+ ns_update_menubar (f, true, nil);
ns_check_pending_open_menu ();
#endif
}
/* Update menu in menuNeedsUpdate only while tracking menus. */
trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification
? 1 : 0);
+ if (! trackingMenu) ns_check_menu_open (nil);
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- (void)menuWillOpen:(NSMenu *)menu
{
- ns_check_menu_open (menu);
-}
-#endif
+ ++trackingMenu;
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_6
+ // On 10.6 we get repeated calls, only the one for NSSystemDefined is "real".
+ if ([[NSApp currentEvent] type] != NSSystemDefined) return;
#endif
+ /* When dragging from one menu to another, we get willOpen followed by didClose,
+ i.e. trackingMenu == 3 in willOpen and then 2 after didClose.
+ We have updated all menus, so avoid doing it when trackingMenu == 3. */
+ if (trackingMenu == 2)
+ ns_check_menu_open (menu);
+}
+
+- (void)menuDidClose:(NSMenu *)menu
+{
+ --trackingMenu;
+}
+#endif /* OSX >= 10.5 */
+
+#endif /* NS_IMPL_COCOA */
+
/* delegate method called when a submenu is being opened: run a 'deep' call
to set_frame_menubar */
- (void)menuNeedsUpdate: (NSMenu *)menu
- (void)fillWithWidgetValue: (void *)wvptr
+{
+ [self fillWithWidgetValue: wvptr setDelegate:NO];
+}
+
+- (void)fillWithWidgetValue: (void *)wvptr setDelegate: (BOOL)set
{
widget_value *wv = (widget_value *)wvptr;
{
EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: [item title]];
+#ifdef NS_IMPL_COCOA
+ if (set) [submenu setDelegate: submenu];
+#endif
[self setSubmenu: submenu forItem: item];
[submenu fillWithWidgetValue: wv->contents];
[submenu release];
- (NSString *)parseKeyEquiv: (const char *)key;
- (NSMenuItem *)addItemWithWidgetValue: (void *)wvptr;
- (void)fillWithWidgetValue: (void *)wvptr;
+- (void)fillWithWidgetValue: (void *)wvptr setDelegate: (BOOL)set;
- (EmacsMenu *)addSubmenuWithTitle: (const char *)title forFrame: (struct frame *)f;
- (void) clear;
- (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f
/* Saved position for menu click. */
static CGPoint menu_mouse_point;
-
-/* Title for the menu to open. */
-static char *menu_pending_title = 0;
#endif
/* Convert modifiers in a NeXTstep event to emacs style modifiers. */
/* GNUStep and OSX <= 10.4 does not have cancelTracking. */
#if defined (NS_IMPL_COCOA) && \
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-const char *
-ns_get_pending_menu_title ()
-{
- return menu_pending_title;
-}
-
/* Check if menu open should be cancelled or continued as normal. */
void
ns_check_menu_open (NSMenu *menu)
NSArray *a = [[NSApp mainMenu] itemArray];
int i;
BOOL found = NO;
+
+ if (menu == nil) // Menu tracking ended.
+ {
+ if (menu_will_open_state == MENU_OPENING)
+ menu_will_open_state = MENU_NONE;
+ return;
+ }
+
for (i = 0; ! found && i < [a count]; i++)
found = menu == [[a objectAtIndex:i] submenu];
if (found)
CGEventRef ourEvent = CGEventCreate (NULL);
menu_mouse_point = CGEventGetLocation (ourEvent);
CFRelease (ourEvent);
- xfree (menu_pending_title);
- menu_pending_title = xstrdup ([[menu title] UTF8String]);
}
else if (menu_will_open_state == MENU_OPENING)
{