From 24c019196c865268a2ad3aedf5706b54b80e4e2c Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 20 Oct 2021 10:54:27 +0800 Subject: [PATCH] Support opening the toolkit menu bar on NS * src/nsmenu.m (ns_activate_menubar, Fns_open_menubar): New functions. * src/nsterm.m (ns_create_terminal): Add activate_menubar_hook. * lisp/menu-bar.el (menu-bar-open): Use ns-menu-bar-open on Nextstep. --- lisp/menu-bar.el | 8 ++++--- src/nsmenu.m | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ src/nsterm.m | 1 + 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index fafc99eb95..b66f620276 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -2659,9 +2659,10 @@ menu-bar-open this is the numeric argument to the command. This function decides which method to use to access the menu depending on FRAME's terminal device. On X displays, it calls -`x-menu-bar-open'; on Windows, `w32-menu-bar-open'; otherwise it -calls either `popup-menu' or `tmm-menubar' depending on whether -`tty-menu-open-use-tmm' is nil or not. +`x-menu-bar-open'; on Windows, `w32-menu-bar-open'; +on NS, `ns-menu-bar-open'; otherwise it calls either `popup-menu' +or `tmm-menubar' depending on whether `tty-menu-open-use-tmm' +is nil or not. If FRAME is nil or not given, use the selected frame." (interactive @@ -2670,6 +2671,7 @@ menu-bar-open (cond ((eq type 'x) (x-menu-bar-open frame)) ((eq type 'w32) (w32-menu-bar-open frame)) + ((eq type 'ns) (ns-menu-bar-open frame)) ((and (null tty-menu-open-use-tmm) (not (zerop (or (frame-parameter nil 'menu-bar-lines) 0)))) ;; Make sure the menu bar is up to date. One situation where diff --git a/src/nsmenu.m b/src/nsmenu.m index 29201e6907..b93d3a79bd 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -439,6 +439,44 @@ ns_update_menubar (f, deep_p); } +void +ns_activate_menubar (struct frame *frame) +{ + if (frame != SELECTED_FRAME () + || !FRAME_EXTERNAL_MENU_BAR (frame)) + return; + + block_input (); + NSApplication *app = [NSApplication sharedApplication]; + NSMenu *menu = [app mainMenu]; + for (NSMenuItem *item in [menu itemArray]) + { + if ([item hasSubmenu]) + { +#ifdef NS_IMPL_GNUSTEP + [[item submenu] display]; +#else + NSWindow *window = [FRAME_NS_VIEW (frame) window]; + NSScreen *screen = [window screen]; + + NSRect screen_frame = [screen frame]; + [app postEvent: [NSEvent mouseEventWithType: NSLeftMouseDown + location: NSMakePoint (NSMinX (screen_frame), + NSMinY (screen_frame) + 10) + modifierFlags: 0 + timestamp: 0 + windowNumber: [window windowNumber] + context: [NSGraphicsContext currentContext] + eventNumber: 0 + clickCount: 1 + pressure: 1.0f] + atStart: YES]; +#endif + break; + } + } + unblock_input (); +} /* ========================================================================== @@ -1916,6 +1954,22 @@ - (Lisp_Object)runDialogAt: (NSPoint)p return popup_activated () ? Qt : Qnil; } +DEFUN ("ns-menu-bar-open", Fns_menu_bar_open, Sns_menu_bar_open, 0, 1, "i", + doc: /* Start key navigation of the menu bar in FRAME. +This initially opens the first menu bar item and you can then navigate with the +arrow keys, select a menu entry with the return key or cancel with the +escape key. If FRAME has no menu bar this function does nothing. + +If FRAME is nil or not given, use the selected frame. */) + (Lisp_Object frame) +{ + struct frame *f = decode_window_system_frame (frame); + + ns_activate_menubar (f); + + return Qnil; +} + /* ========================================================================== Lisp interface declaration @@ -1927,6 +1981,7 @@ - (Lisp_Object)runDialogAt: (NSPoint)p { defsubr (&Sns_reset_menu); defsubr (&Smenu_or_popup_active_p); + defsubr (&Sns_menu_bar_open); DEFSYM (Qdebug_on_next_call, "debug-on-next-call"); } diff --git a/src/nsterm.m b/src/nsterm.m index c10b6feca1..d9c28cb191 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -5078,6 +5078,7 @@ static Lisp_Object ns_new_font (struct frame *f, Lisp_Object font_object, terminal->delete_frame_hook = ns_destroy_window; terminal->delete_terminal_hook = ns_delete_terminal; terminal->change_tab_bar_height_hook = ns_change_tab_bar_height; + terminal->activate_menubar_hook = ns_activate_menubar; /* Other hooks are NULL by default. */ return terminal; -- 2.31.1