From: Alan Third <alan@idiocy.org>
To: "Mattias Engdegård" <mattiase@acm.org>
Cc: 44333@debbugs.gnu.org,
Viktor Kharitonovich <viktor.kharitonovich@gmail.com>
Subject: bug#44333: 27.1; macOS menu bar 2-clicks
Date: Sat, 26 Dec 2020 17:07:58 +0000 [thread overview]
Message-ID: <X+dt7qND/U5z5Zt0@breton.holly.idiocy.org> (raw)
In-Reply-To: <A100BF7C-C688-4C4B-873B-6F6B9B5DC633@acm.org>
[-- Attachment #1: Type: text/plain, Size: 1342 bytes --]
On Fri, Dec 25, 2020 at 11:28:56PM +0100, Mattias Engdegård wrote:
> 25 dec. 2020 kl. 20.20 skrev Alan Third <alan@idiocy.org>:
> >
> > On Fri, Dec 25, 2020 at 05:26:49PM +0000, Alan Third wrote:
> >> ns_update_menubar is a big, complicated function that I've not been
> >> over in depth to work out what it's doing, so I don't know if it
> >> would be practical to break it up like I suspect using those two
> >> methods would require.
> >
> > I've had a look through it, and I've noticed that most of the work
> > appears to be building a tree of widget_value structs. A quick look at
> > xmenu.c and w32menu.c leaves me with the impression that they have
> > almost identical code for that part, but for some reason the NS port
> > is different (and is full of "FIXME: this is broken" comments).
> >
> > So I suppose the first thing to do should be to align the NS code with
> > the other terminals, and see if that improves things.
>
> Probably. When the code suffers from one of its slow spells, the
> time is apparently spent in the calls to parse_single_submenu, and
> from there... single_keymap_panes, I think. Didn't dig deeper after
> that.
Does the attached seem any better? It appears to me like the first
click on a menu is slightly faster (but that may be my imagination),
and subsequent menus are instant.
--
Alan Third
[-- Attachment #2: v2-0001-Remove-NS-menu-synthesized-events-bug-44333.patch --]
[-- Type: text/plain, Size: 24607 bytes --]
From 887a5ac84ca5c86fef5762cbc48abbfee291b751 Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
Date: Wed, 23 Dec 2020 20:12:02 +0000
Subject: [PATCH v2] Remove NS menu synthesized events (bug#44333)
* src/nsmenu.m (ns_update_menubar): Copy the parsing code from xmenu.c
and rework the NS specific code around it.
(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.
(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.
---
| 377 ++++++++++++++++-----------------------------------
src/nsterm.h | 2 -
src/nsterm.m | 101 --------------
3 files changed, 115 insertions(+), 365 deletions(-)
--git a/src/nsmenu.m b/src/nsmenu.m
index efad978316..b5d0821323 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -58,9 +58,7 @@
/* Nonzero means a menu is currently active. */
static int popup_activated_flag;
-/* Nonzero means we are tracking and updating menus. */
-static int trackingMenu;
-
+static BOOL needs_deep_update = YES;
/* NOTE: toolbar implementation is at end,
following complete menu implementation. */
@@ -98,16 +96,18 @@
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 +141,94 @@
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;
-
- 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;
- }
+ /* Convert menu_items into widget_value trees
+ to display the menu. This cannot evaluate Lisp code. */
- /* 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,158 +238,115 @@
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);
+ if (prev_wv)
+ prev_wv->next = wv;
+ else
+ first_wv->contents = wv;
+ prev_wv = wv;
+ }
+
+ /* 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. */
+ int i = 1;
+
+ 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 frame: f];
+ }
+ needs_deep_update = NO;
+ }
+ else
+ {
+ [menu clear];
+ for (wv = first_wv->contents; wv; wv = wv->next)
+ {
#ifdef NS_IMPL_COCOA
/* We'll update the real copy under app menu when time comes. */
if (!strcmp ("Services", wv->name))
@@ -420,25 +356,17 @@
}
else
#endif
- [menu addSubmenuWithTitle: wv->name forFrame: f];
+ [menu addSubmenuWithTitle: wv->name forFrame: f];
+ }
- if (prev_wv)
- prev_wv->next = wv;
- else
- first_wv->contents = wv;
- prev_wv = wv;
- }
+ /* We've cleared out the contents of the menus, so the next time
+ one is clicked on we'll need to run a deep update. */
+ needs_deep_update = YES;
+ }
- last_f = f;
- if (n < 100)
- n_previous_strings = n;
- else
- n_previous_strings = 0;
- }
free_menubar_widget_value_tree (first_wv);
-
#if NSMENUPROFILE
ftime (&tb);
t += 1000*tb.time+tb.millitm;
@@ -460,21 +388,10 @@
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
@@ -514,43 +431,6 @@ - (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);
-}
-
-- (void)menuDidClose:(NSMenu *)menu
-{
- --trackingMenu;
-}
-
-#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
@@ -558,29 +438,8 @@ - (void)menuNeedsUpdate: (NSMenu *)menu
if (!FRAME_LIVE_P (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 (needs_deep_update)
+ ns_update_menubar (frame, true);
}
@@ -1881,12 +1740,6 @@ - (Lisp_Object)runDialogAt: (NSPoint)p
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 94472ec107..0b7e27c00f 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -1130,8 +1130,6 @@ ns_query_color (void *col, Emacs_Color *color_def, bool setPixel);
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 2a117a0780..161677484f 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -310,24 +310,6 @@ - (NSColor *)colorUsingDefaultColorSpace
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 @@ in certain situations (rapid incoming events).
}
#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 @@ static Lisp_Object ns_new_font (struct frame *f, Lisp_Object font_object,
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 @@ Needs to be here because ns_initialize_display_info () uses AppKit classes.
[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.29.2
next prev parent reply other threads:[~2020-12-26 17:07 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-30 17:53 bug#44333: 27.1; macOS menu bar 2-clicks Viktor Kharitonovich
2020-10-30 22:42 ` Alan Third
2020-10-31 14:08 ` Mattias Engdegård
2020-10-31 15:01 ` Alan Third
2020-11-01 10:50 ` Mattias Engdegård
2020-11-01 17:28 ` Alan Third
2020-12-23 20:33 ` Alan Third
2020-12-25 16:06 ` Mattias Engdegård
2020-12-25 17:26 ` Alan Third
2020-12-25 19:20 ` Alan Third
2020-12-25 22:28 ` Mattias Engdegård
2020-12-26 17:07 ` Alan Third [this message]
2020-12-26 17:42 ` Mattias Engdegård
2020-12-26 21:52 ` Alan Third
2020-12-27 16:56 ` Alan Third
2020-12-27 17:14 ` Mattias Engdegård
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=X+dt7qND/U5z5Zt0@breton.holly.idiocy.org \
--to=alan@idiocy.org \
--cc=44333@debbugs.gnu.org \
--cc=mattiase@acm.org \
--cc=viktor.kharitonovich@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).