[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master c9b3763: Remove NS menu synthesized events (bug#44333)
From: |
Alan Third |
Subject: |
master c9b3763: Remove NS menu synthesized events (bug#44333) |
Date: |
Sun, 27 Dec 2020 11:54:37 -0500 (EST) |
branch: master
commit c9b37634b131f3617314bd5a38090e96d0b465cf
Author: Alan Third <alan@idiocy.org>
Commit: Alan Third <alan@idiocy.org>
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 efad978..3f0cd0c 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; i<n; i++)
- {
- string = AREF (items, 4*i+1);
-
- if (EQ (string, make_fixnum (0))) // FIXME: Why??? --Stef
- continue;
- if (NILP (string))
- {
- if (previous_strings[i][0])
- break;
- else
- continue;
- }
- else if (memcmp (previous_strings[i], SDATA (string),
- min (10, SBYTES (string) + 1)))
- break;
- }
-
- if (i == n)
- {
- free_menubar_widget_value_tree (first_wv);
- unblock_input ();
- return;
- }
- }
-
- [menu clear];
for (i = 0; i < ASIZE (items); i += 4)
{
+ Lisp_Object string;
+
string = AREF (items, i + 1);
if (NILP (string))
break;
- if (n < 100)
- memcpy (previous_strings[i/4], SDATA (string),
- min (10, SBYTES (string) + 1));
-
wv = make_widget_value (SSDATA (string), NULL, true, Qnil);
wv->button_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 94472ec..b7b4d3b 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -513,25 +513,18 @@ typedef id instancetype;
==========================================================================
*/
-#ifdef NS_IMPL_COCOA
@interface EmacsMenu : NSMenu <NSMenuDelegate>
-#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 2a117a0..1616774 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 */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master c9b3763: Remove NS menu synthesized events (bug#44333),
Alan Third <=