From c9b37634b131f3617314bd5a38090e96d0b465cf Mon Sep 17 00:00:00 2001 From: Alan Third Date: Wed, 23 Dec 2020 20:12:02 +0000 Subject: [PATCH] Remove NS menu synthesized events (bug#44333) Remove the frame tracking stuff as it's not used for anything, and move the update tracking into the EmacsMenu class. * src/nsmenu.m (ns_update_menubar): Copy the parsing code from xmenu.c and rework the NS specific code around to update the existing menus instead of rebuilding them completely. (ns_activate_menubar): ([EmacsMenu trackingNotification:]): ([EmacsMenu menuWillOpen:]): ([EmacsMenu menuDidClose:]): Remove unused functions. ([EmacsMenu menuNeedsUpdate:]): Remove menu tracking code and add code to check whether an update is required. ([EmacsMenu fillWithWidgetValue:]): ([EmacsMenu addSubmenuWithTitle:]): ([EmacsMenu initWithTitle:]): Remove references to frame. ([EmacsMenu setFrame:]): Remove method. ([EmacsMenu clear]): Rename to removeAllItems. ([EmacsMenu removeAllItems]): Use built-in removeAllItems, if available. (syms_of_nsmenu): Remove tracking code. * src/nsterm.m (ns_check_menu_open): (ns_check_pending_open_menu): (ns_create_terminal): Remove unused functions. (ns_term_init): Get rid of menu tracking. * src/nsterm.h (EmacsMenu): Remove frame, add needsUpdate and update method definitions. --- src/nsmenu.m | 457 +++++++++++++++++---------------------------------- src/nsterm.h | 15 +- src/nsterm.m | 101 ------------ 3 files changed, 158 insertions(+), 415 deletions(-) diff --git a/src/nsmenu.m b/src/nsmenu.m index efad978316e..3f0cd0c6ed4 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -47,21 +47,11 @@ Carbon version by Yamamoto Mitsuharu. */ #endif -#if 0 -/* Include lisp -> C common menu parsing code. */ -#define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str) -#include "nsmenu_common.c" -#endif - extern long context_menu_value; EmacsMenu *svcsMenu; /* Nonzero means a menu is currently active. */ static int popup_activated_flag; -/* Nonzero means we are tracking and updating menus. */ -static int trackingMenu; - - /* NOTE: toolbar implementation is at end, following complete menu implementation. */ @@ -98,16 +88,18 @@ popup_activated (void) 3) deep_p, submenu = non-nil: Update contents of a single submenu. -------------------------------------------------------------------------- */ static void -ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) +ns_update_menubar (struct frame *f, bool deep_p) { NSAutoreleasePool *pool; - id menu = [NSApp mainMenu]; - static EmacsMenu *last_submenu = nil; BOOL needsSet = NO; - bool owfi; + id menu = [NSApp mainMenu]; + Lisp_Object items; widget_value *wv, *first_wv, *prev_wv = 0; int i; + int *submenu_start, *submenu_end; + bool *submenu_top_level_items; + int *submenu_n_panes; #if NSMENUPROFILE struct timeb tb; @@ -141,115 +133,94 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) t = -(1000*tb.time+tb.millitm); #endif -#ifdef NS_IMPL_GNUSTEP - deep_p = 1; /* until GNUstep NSMenu implements the Panther delegation model */ -#endif - if (deep_p) { - /* Fully parse one or more of the submenus. */ - int n = 0; - int *submenu_start, *submenu_end; - bool *submenu_top_level_items; - int *submenu_n_panes; + /* Make a widget-value tree representing the entire menu trees. */ + struct buffer *prev = current_buffer; Lisp_Object buffer; ptrdiff_t specpdl_count = SPECPDL_INDEX (); int previous_menu_items_used = f->menu_bar_items_used; Lisp_Object *previous_items = alloca (previous_menu_items_used * sizeof *previous_items); + int subitems; - /* lisp preliminaries */ buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents; specbind (Qinhibit_quit, Qt); + /* Don't let the debugger step into this code + because it is not reentrant. */ specbind (Qdebug_on_next_call, Qnil); + record_unwind_save_match_data (); if (NILP (Voverriding_local_map_menu_flag)) { specbind (Qoverriding_terminal_local_map, Qnil); specbind (Qoverriding_local_map, Qnil); } - set_buffer_internal_1 (XBUFFER (buffer)); - /* TODO: for some reason this is not needed in other terms, - but some menu updates call Info-extract-pointer which causes - abort-on-error if waiting-for-input. Needs further investigation. */ - owfi = waiting_for_input; - waiting_for_input = 0; + set_buffer_internal_1 (XBUFFER (buffer)); - /* lucid hook and possible reset */ + /* Run the Lucid hook. */ safe_run_hooks (Qactivate_menubar_hook); + + /* If it has changed current-menubar from previous value, + really recompute the menubar from the value. */ if (! NILP (Vlucid_menu_bar_dirty_flag)) call0 (Qrecompute_lucid_menubar); safe_run_hooks (Qmenu_bar_update_hook); fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f))); - /* Now ready to go */ items = FRAME_MENU_BAR_ITEMS (f); - /* Save the frame's previous menu bar contents data */ + /* Save the frame's previous menu bar contents data. */ if (previous_menu_items_used) - memcpy (previous_items, aref_addr (f->menu_bar_vector, 0), - previous_menu_items_used * sizeof (Lisp_Object)); + memcpy (previous_items, xvector_contents (f->menu_bar_vector), + previous_menu_items_used * word_size); - /* parse stage 1: extract from lisp */ + /* Fill in menu_items with the current menu bar contents. + This can evaluate Lisp code. */ save_menu_items (); menu_items = f->menu_bar_vector; menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; - submenu_start = alloca (ASIZE (items) * sizeof *submenu_start); - submenu_end = alloca (ASIZE (items) * sizeof *submenu_end); - submenu_n_panes = alloca (ASIZE (items) * sizeof *submenu_n_panes); - submenu_top_level_items = alloca (ASIZE (items) + subitems = ASIZE (items) / 4; + submenu_start = alloca ((subitems + 1) * sizeof *submenu_start); + submenu_end = alloca (subitems * sizeof *submenu_end); + submenu_n_panes = alloca (subitems * sizeof *submenu_n_panes); + submenu_top_level_items = alloca (subitems * sizeof *submenu_top_level_items); init_menu_items (); - for (i = 0; i < ASIZE (items); i += 4) + for (i = 0; i < subitems; i++) { Lisp_Object key, string, maps; - key = AREF (items, i); - string = AREF (items, i + 1); - maps = AREF (items, i + 2); + key = AREF (items, 4 * i); + string = AREF (items, 4 * i + 1); + maps = AREF (items, 4 * i + 2); if (NILP (string)) break; - /* FIXME: we'd like to only parse the needed submenu, but this - was causing crashes in the _common parsing code: need to make - sure proper initialization done. */ - /* if (submenu && strcmp ([[submenu title] UTF8String], SSDATA (string))) - continue; */ - submenu_start[i] = menu_items_used; menu_items_n_panes = 0; - submenu_top_level_items[i] = parse_single_submenu (key, string, maps); + submenu_top_level_items[i] + = parse_single_submenu (key, string, maps); submenu_n_panes[i] = menu_items_n_panes; + submenu_end[i] = menu_items_used; - n++; } + submenu_start[i] = -1; finish_menu_items (); - waiting_for_input = owfi; + /* Convert menu_items into widget_value trees + to display the menu. This cannot evaluate Lisp code. */ - if (submenu && n == 0) - { - /* should have found a menu for this one but didn't */ - fprintf (stderr, "ERROR: did not find lisp menu for submenu '%s'.\n", - [[submenu title] UTF8String]); - discard_menu_items (); - unbind_to (specpdl_count, Qnil); - unblock_input (); - return; - } - - /* parse stage 2: insert into lucid 'widget_value' structures - [comments in other terms say not to evaluate lisp code here] */ wv = make_widget_value ("menubar", NULL, true, Qnil); wv->button_type = BUTTON_TYPE_NONE; first_wv = wv; - for (i = 0; i < 4*n; i += 4) + for (i = 0; submenu_start[i] >= 0; i++) { menu_items_n_panes = submenu_n_panes[i]; wv = digest_single_submenu (submenu_start[i], submenu_end[i], @@ -259,169 +230,79 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) else first_wv->contents = wv; /* Don't set wv->name here; GC during the loop might relocate it. */ - wv->enabled = 1; + wv->enabled = true; wv->button_type = BUTTON_TYPE_NONE; prev_wv = wv; } set_buffer_internal_1 (prev); - /* Compare the new menu items with previous, and leave off if no change. */ - /* FIXME: following other terms here, but seems like this should be - done before parse stage 2 above, since its results aren't used. */ - if (previous_menu_items_used - && (!submenu || (submenu && submenu == last_submenu)) - && menu_items_used == previous_menu_items_used) - { - for (i = 0; i < previous_menu_items_used; i++) - /* FIXME: this ALWAYS fails on Buffers menu items.. something - about their strings causes them to change every time, so we - double-check failures. */ - if (!EQ (previous_items[i], AREF (menu_items, i))) - if (!(STRINGP (previous_items[i]) - && STRINGP (AREF (menu_items, i)) - && !strcmp (SSDATA (previous_items[i]), - SSDATA (AREF (menu_items, i))))) - break; - if (i == previous_menu_items_used) - { - /* No change. */ + /* If there has been no change in the Lisp-level contents + of the menu bar, skip redisplaying it. Just exit. */ -#if NSMENUPROFILE - ftime (&tb); - t += 1000*tb.time+tb.millitm; - fprintf (stderr, "NO CHANGE! CUTTING OUT after %ld msec.\n", t); -#endif + /* Compare the new menu items with the ones computed last time. */ + for (i = 0; i < previous_menu_items_used; i++) + if (menu_items_used == i + || (!EQ (previous_items[i], AREF (menu_items, i)))) + break; + if (i == menu_items_used && i == previous_menu_items_used && i != 0) + { + /* The menu items have not changed. Don't bother updating + the menus in any form, since it would be a no-op. */ + free_menubar_widget_value_tree (first_wv); + discard_menu_items (); + unbind_to (specpdl_count, Qnil); + return; + } - free_menubar_widget_value_tree (first_wv); - discard_menu_items (); - unbind_to (specpdl_count, Qnil); - unblock_input (); - return; - } - } /* The menu items are different, so store them in the frame. */ - /* FIXME: this is not correct for single-submenu case. */ fset_menu_bar_vector (f, menu_items); f->menu_bar_items_used = menu_items_used; - /* Calls restore_menu_items, etc., as they were outside. */ + /* This undoes save_menu_items. */ unbind_to (specpdl_count, Qnil); - /* Parse stage 2a: now GC cannot happen during the lifetime of the - widget_value, so it's safe to store data from a Lisp_String. */ + /* Now GC cannot happen during the lifetime of the widget_value, + so it's safe to store data from a Lisp_String. */ wv = first_wv->contents; for (i = 0; i < ASIZE (items); i += 4) { Lisp_Object string; string = AREF (items, i + 1); if (NILP (string)) - break; - - wv->name = SSDATA (string); + break; + wv->name = SSDATA (string); update_submenu_strings (wv->contents); - wv = wv->next; + wv = wv->next; } - /* Now, update the NS menu; if we have a submenu, use that, otherwise - create a new menu for each sub and fill it. */ - if (submenu) - { - const char *submenuTitle = [[submenu title] UTF8String]; - for (wv = first_wv->contents; wv; wv = wv->next) - { - if (!strcmp (submenuTitle, wv->name)) - { - [submenu fillWithWidgetValue: wv->contents]; - last_submenu = submenu; - break; - } - } - } - else - { - [menu fillWithWidgetValue: first_wv->contents frame: f]; - } - } else { - static int n_previous_strings = 0; - static char previous_strings[100][10]; - static struct frame *last_f = NULL; - int n; - Lisp_Object string; + /* Make a widget-value tree containing + just the top level menu bar strings. */ wv = make_widget_value ("menubar", NULL, true, Qnil); wv->button_type = BUTTON_TYPE_NONE; first_wv = wv; - /* Make widget-value tree with just the top level menu bar strings. */ items = FRAME_MENU_BAR_ITEMS (f); - if (NILP (items)) - { - free_menubar_widget_value_tree (first_wv); - unblock_input (); - return; - } - - - /* Check if no change: this mechanism is a bit rough, but ready. */ - n = ASIZE (items) / 4; - if (f == last_f && n_previous_strings == n) - { - for (i = 0; ibutton_type = BUTTON_TYPE_NONE; + /* This prevents lwlib from assuming this + menu item is really supposed to be empty. */ + /* The intptr_t cast avoids a warning. + This value just has to be different from small integers. */ wv->call_data = (void *) (intptr_t) (-1); -#ifdef NS_IMPL_COCOA - /* We'll update the real copy under app menu when time comes. */ - if (!strcmp ("Services", wv->name)) - { - /* But we need to make sure it will update on demand. */ - [svcsMenu setFrame: f]; - } - else -#endif - [menu addSubmenuWithTitle: wv->name forFrame: f]; - if (prev_wv) prev_wv->next = wv; else @@ -429,15 +310,68 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) prev_wv = wv; } - last_f = f; - if (n < 100) - n_previous_strings = n; - else - n_previous_strings = 0; + /* Forget what we thought we knew about what is in the + detailed contents of the menu bar menus. + Changing the top level always destroys the contents. */ + f->menu_bar_items_used = 0; + } + + /* Now, update the NS menu. */ + if (deep_p) + { + /* This path is typically used when a menu has been clicked. I + think Apple expect us to only update that one menu, however + to update one we need to do the hard work of parsing the + whole tree, so we may as well update them all. */ +#ifdef NS_IMPL_COCOA + int i = 1; +#else + int i = 0; +#endif + for (wv = first_wv->contents; wv; wv = wv->next) + { + /* The contents of wv should match the top level menu. */ + EmacsMenu *submenu = (EmacsMenu*)[[menu itemAtIndex:i++] submenu]; + [submenu fillWithWidgetValue: wv->contents]; + } } - free_menubar_widget_value_tree (first_wv); + else + { + /* Make sure we skip the "application" menu, which is always the + first entry in our top-level menu. */ +#ifdef NS_IMPL_COCOA + int i = 1; +#else + int i = 0; +#endif + for (wv = first_wv->contents; wv; wv = wv->next) + { + if (i < [menu numberOfItems]) + { + NSString *titleStr = [NSString stringWithUTF8String: wv->name]; + NSMenuItem *item = [menu itemAtIndex:i]; + EmacsMenu *submenu = (EmacsMenu*)[item submenu]; + [item setTitle:titleStr]; + [submenu setTitle:titleStr]; + [submenu removeAllItems]; + } + else + [menu addSubmenuWithTitle: wv->name]; + + i += 1; + } + + while (i < [menu numberOfItems]) + { + /* Remove any extra items. */ + [menu removeItemAtIndex:i]; + } + } + + + free_menubar_widget_value_tree (first_wv); #if NSMENUPROFILE ftime (&tb); @@ -460,21 +394,10 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) void set_frame_menubar (struct frame *f, bool first_time, bool deep_p) { - ns_update_menubar (f, deep_p, nil); -} - -void -ns_activate_menubar (struct frame *f) -{ -#ifdef NS_IMPL_COCOA - ns_update_menubar (f, true, nil); - ns_check_pending_open_menu (); -#endif + ns_update_menubar (f, deep_p); } - - /* ========================================================================== Menu: class implementation @@ -490,97 +413,31 @@ ns_activate_menubar (struct frame *f) /* override designated initializer */ - (instancetype)initWithTitle: (NSString *)title { - frame = 0; if ((self = [super initWithTitle: title])) [self setAutoenablesItems: NO]; - return self; -} - - -/* used for top-level */ -- (instancetype)initWithTitle: (NSString *)title frame: (struct frame *)f -{ - [self initWithTitle: title]; - frame = f; -#ifdef NS_IMPL_COCOA [self setDelegate: self]; -#endif - return self; -} - - -- (void)setFrame: (struct frame *)f -{ - frame = f; -} - -#ifdef NS_IMPL_COCOA --(void)trackingNotification:(NSNotification *)notification -{ - /* Update menu in menuNeedsUpdate only while tracking menus. */ - trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification - ? 1 : 0); - if (! trackingMenu) ns_check_menu_open (nil); -} - -- (void)menuWillOpen:(NSMenu *)menu -{ - ++trackingMenu; - -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 - // On 10.6 we get repeated calls, only the one for NSSystemDefined is "real". - if ( -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - NSAppKitVersionNumber < NSAppKitVersionNumber10_7 && -#endif - [[NSApp currentEvent] type] != NSEventTypeSystemDefined) - 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); -} + needsUpdate = YES; -- (void)menuDidClose:(NSMenu *)menu -{ - --trackingMenu; + return self; } -#endif /* NS_IMPL_COCOA */ /* Delegate method called when a submenu is being opened: run a 'deep' call to set_frame_menubar. */ + +/* TODO: GNUstep calls this method when the menu is still being built + which throws it into an infinite loop. One possible solution is to + use menuWillOpen instead, but the Apple docs explicitly warn + against changing the contents of the menu in it. I don't know what + the right thing to do for GNUstep is. */ - (void)menuNeedsUpdate: (NSMenu *)menu { - if (!FRAME_LIVE_P (frame)) + if (!FRAME_LIVE_P (SELECTED_FRAME ())) return; - /* Cocoa/Carbon will request update on every keystroke - via IsMenuKeyEvent -> CheckMenusForKeyEvent. These are not needed - since key equivalents are handled through emacs. - On Leopard, even keystroke events generate SystemDefined event. - Third-party applications that enhance mouse / trackpad - interaction, or also VNC/Remote Desktop will send events - of type AppDefined rather than SysDefined. - Menus will fail to show up if they haven't been initialized. - AppDefined events may lack timing data. - - Thus, we rely on the didBeginTrackingNotification notification - as above to indicate the need for updates. - From 10.6 on, we could also use -[NSMenu propertiesToUpdate]: In the - key press case, NSMenuPropertyItemImage (e.g.) won't be set. - */ - if (trackingMenu == 0) - return; -/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */ -#ifdef NS_IMPL_GNUSTEP - /* Don't know how to do this for anything other than Mac OS X 10.5 and later. - This is wrong, as it might run Lisp code in the event loop. */ - ns_update_menubar (frame, true, self); -#endif + if (needsUpdate) + ns_update_menubar (SELECTED_FRAME (), true); } @@ -674,8 +531,13 @@ ns_activate_menubar (struct frame *f) /* convenience */ --(void)clear +-(void)removeAllItems { +#ifdef NS_IMPL_COCOA + [super removeAllItems]; +#else + /* GNUstep doesn't have removeAllItems yet, so do it + manually. */ int n; for (n = [self numberOfItems]-1; n >= 0; n--) @@ -687,20 +549,18 @@ ns_activate_menubar (struct frame *f) continue; [self removeItemAtIndex: n]; } +#endif + + needsUpdate = YES; } - (void)fillWithWidgetValue: (void *)wvptr -{ - [self fillWithWidgetValue: wvptr frame: (struct frame *)nil]; -} - -- (void)fillWithWidgetValue: (void *)wvptr frame: (struct frame *)f { widget_value *wv = (widget_value *)wvptr; /* clear existing contents */ - [self clear]; + [self removeAllItems]; /* add new contents */ for (; wv != NULL; wv = wv->next) @@ -711,10 +571,7 @@ ns_activate_menubar (struct frame *f) { EmacsMenu *submenu; - if (f) - submenu = [[EmacsMenu alloc] initWithTitle: [item title] frame:f]; - else - submenu = [[EmacsMenu alloc] initWithTitle: [item title]]; + submenu = [[EmacsMenu alloc] initWithTitle: [item title]]; [self setSubmenu: submenu forItem: item]; [submenu fillWithWidgetValue: wv->contents]; @@ -723,6 +580,8 @@ ns_activate_menubar (struct frame *f) } } + needsUpdate = NO; + #ifdef NS_IMPL_GNUSTEP if ([[self window] isVisible]) [self sizeToFit]; @@ -731,13 +590,13 @@ ns_activate_menubar (struct frame *f) /* Adds an empty submenu and returns it. */ -- (EmacsMenu *)addSubmenuWithTitle: (const char *)title forFrame: (struct frame *)f +- (EmacsMenu *)addSubmenuWithTitle: (const char *)title { NSString *titleStr = [NSString stringWithUTF8String: title]; NSMenuItem *item = [self addItemWithTitle: titleStr action: (SEL)nil /*@selector (menuDown:) */ keyEquivalent: @""]; - EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr frame: f]; + EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr]; [self setSubmenu: submenu forItem: item]; [submenu release]; return submenu; @@ -1881,12 +1740,6 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_ void syms_of_nsmenu (void) { -#ifndef NS_IMPL_COCOA - /* Don't know how to keep track of this in Next/Open/GNUstep. Always - update menus there. */ - trackingMenu = 1; - PDUMPER_REMEMBER_SCALAR (trackingMenu); -#endif defsubr (&Sns_reset_menu); defsubr (&Smenu_or_popup_active_p); diff --git a/src/nsterm.h b/src/nsterm.h index 94472ec1070..b7b4d3b047c 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -513,25 +513,18 @@ typedef id instancetype; ========================================================================== */ -#ifdef NS_IMPL_COCOA @interface EmacsMenu : NSMenu -#else -@interface EmacsMenu : NSMenu -#endif { - struct frame *frame; unsigned long keyEquivModMask; + BOOL needsUpdate; } -- (instancetype)initWithTitle: (NSString *)title frame: (struct frame *)f; -- (void)setFrame: (struct frame *)f; - (void)menuNeedsUpdate: (NSMenu *)menu; /* (delegate method) */ - (NSString *)parseKeyEquiv: (const char *)key; - (NSMenuItem *)addItemWithWidgetValue: (void *)wvptr; - (void)fillWithWidgetValue: (void *)wvptr; -- (void)fillWithWidgetValue: (void *)wvptr frame: (struct frame *)f; -- (EmacsMenu *)addSubmenuWithTitle: (const char *)title forFrame: (struct frame *)f; -- (void) clear; +- (EmacsMenu *)addSubmenuWithTitle: (const char *)title; +- (void) removeAllItems; - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f keymaps: (bool)keymaps; @end @@ -1130,8 +1123,6 @@ extern int ns_lisp_to_color (Lisp_Object color, NSColor **col); extern NSColor *ns_lookup_indexed_color (unsigned long idx, struct frame *f); extern unsigned long ns_index_color (NSColor *color, struct frame *f); extern const char *ns_get_pending_menu_title (void); -extern void ns_check_menu_open (NSMenu *menu); -extern void ns_check_pending_open_menu (void); #endif /* Implemented in nsfns, published in nsterm. */ diff --git a/src/nsterm.m b/src/nsterm.m index 2a117a07801..161677484f9 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -310,24 +310,6 @@ static struct { NULL, 0, 0 }; -#ifdef NS_IMPL_COCOA -/* - * State for pending menu activation: - * MENU_NONE Normal state - * MENU_PENDING A menu has been clicked on, but has been canceled so we can - * run lisp to update the menu. - * MENU_OPENING Menu is up to date, and the click event is redone so the menu - * will open. - */ -#define MENU_NONE 0 -#define MENU_PENDING 1 -#define MENU_OPENING 2 -static int menu_will_open_state = MENU_NONE; - -/* Saved position for menu click. */ -static CGPoint menu_mouse_point; -#endif - /* Convert modifiers in a NeXTstep event to emacs style modifiers. */ #define NS_FUNCTION_KEY_MASK 0x800000 #define NSLeftControlKeyMask (0x000001 | NSEventModifierFlagControl) @@ -4607,79 +4589,6 @@ check_native_fs () } #endif -/* GNUstep does not have cancelTracking. */ -#ifdef NS_IMPL_COCOA -/* Check if menu open should be canceled or continued as normal. */ -void -ns_check_menu_open (NSMenu *menu) -{ - /* Click in menu bar? */ - 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) - { - if (menu_will_open_state == MENU_NONE && emacs_event) - { - NSEvent *theEvent = [NSApp currentEvent]; - struct frame *emacsframe = SELECTED_FRAME (); - - /* On macOS, the following can cause an event loop when the - Spotlight for Help search field is populated. Avoid this by - not postponing mouse drag and non-user-generated mouse down - events (Bug#31371). */ - if (([theEvent type] == NSEventTypeLeftMouseDown) - && [theEvent eventNumber]) - { - [menu cancelTracking]; - menu_will_open_state = MENU_PENDING; - emacs_event->kind = MENU_BAR_ACTIVATE_EVENT; - EV_TRAILER (theEvent); - - CGEventRef ourEvent = CGEventCreate (NULL); - menu_mouse_point = CGEventGetLocation (ourEvent); - CFRelease (ourEvent); - } - } - else if (menu_will_open_state == MENU_OPENING) - { - menu_will_open_state = MENU_NONE; - } - } -} - -/* Redo saved menu click if state is MENU_PENDING. */ -void -ns_check_pending_open_menu () -{ - if (menu_will_open_state == MENU_PENDING) - { - CGEventSourceRef source - = CGEventSourceCreate (kCGEventSourceStateHIDSystemState); - - CGEventRef event = CGEventCreateMouseEvent (source, - kCGEventLeftMouseDown, - menu_mouse_point, - kCGMouseButtonLeft); - CGEventSetType (event, kCGEventLeftMouseDown); - CGEventPost (kCGHIDEventTap, event); - CFRelease (event); - CFRelease (source); - - menu_will_open_state = MENU_OPENING; - } -} -#endif /* NS_IMPL_COCOA */ static int ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) @@ -5416,7 +5325,6 @@ ns_create_terminal (struct ns_display_info *dpyinfo) terminal->set_new_font_hook = ns_new_font; terminal->implicit_set_name_hook = ns_implicitly_set_name; terminal->menu_show_hook = ns_menu_show; - terminal->activate_menubar_hook = ns_activate_menubar; terminal->popup_dialog_hook = ns_popup_dialog; terminal->set_vertical_scroll_bar_hook = ns_set_vertical_scroll_bar; terminal->set_horizontal_scroll_bar_hook = ns_set_horizontal_scroll_bar; @@ -5661,15 +5569,6 @@ ns_term_init (Lisp_Object display_name) [NSApp setServicesMenu: svcsMenu]; /* Needed at least on Cocoa, to get dock menu to show windows */ [NSApp setWindowsMenu: [[NSMenu alloc] init]]; - - [[NSNotificationCenter defaultCenter] - addObserver: mainMenu - selector: @selector (trackingNotification:) - name: NSMenuDidBeginTrackingNotification object: mainMenu]; - [[NSNotificationCenter defaultCenter] - addObserver: mainMenu - selector: @selector (trackingNotification:) - name: NSMenuDidEndTrackingNotification object: mainMenu]; } #endif /* macOS menu setup */ -- 2.39.5