]> git.eshelyaron.com Git - emacs.git/commitdiff
Support opening the toolkit menu bar on NS
authoroldosfan <luangruo@yahoo.com>
Wed, 20 Oct 2021 02:54:27 +0000 (10:54 +0800)
committerPo Lu <luangruo@yahoo.com>
Wed, 10 Nov 2021 05:27:01 +0000 (13:27 +0800)
* 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
src/nsmenu.m
src/nsterm.m

index 1a81f1a3d06c2a7ad247649584c44570018ead05..e50d4fee487b35c7edaf129a305ffc2b54bb2891 100644 (file)
@@ -2665,9 +2665,10 @@ first TTY menu-bar menu to be dropped down.  Interactively,
 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
@@ -2676,6 +2677,7 @@ If FRAME is nil or not given, use the selected frame."
     (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
index 29201e69079ef01a69732a3d0d5d7c6a5fd97cca..b93d3a79bdc3da3af15786448906b7059b594781 100644 (file)
@@ -439,6 +439,44 @@ set_frame_menubar (struct frame *f, bool deep_p)
   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 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_
   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 @@ syms_of_nsmenu (void)
 {
   defsubr (&Sns_reset_menu);
   defsubr (&Smenu_or_popup_active_p);
+  defsubr (&Sns_menu_bar_open);
 
   DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
 }
index ed0e7a2aae82a8b55dbef31028d4c7ccd1e8deb6..4e84e130b89c374a6499539cee5447ebde84bd3e 100644 (file)
@@ -5067,6 +5067,7 @@ ns_create_terminal (struct ns_display_info *dpyinfo)
   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;