From cbbe235a9093c6939b4984843e11247b3b991b7c Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 4 Jan 2022 06:48:08 +0000 Subject: [PATCH] Make menu bar key navigation work on Haiku * src/haiku_support.cc (menu_bar_active_p): New variable. (DispatchMessage): Pass through key events if the menu bar is active. (MenusBeginning, MenusEnd): Set `menu_bar_active_p' according to the state of the menu bar. (BMenuBar_delete): Clear `menu_bar_active_p'. * src/haikufns.c (haiku_free_frame_resources): Block input only after checking that F is a window system frame. * src/haikumenu.c (Fhaiku_menu_bar_open): Update doc string. --- src/haiku_support.cc | 26 ++++++++++++++++++++++++++ src/haikufns.c | 2 +- src/haikumenu.c | 12 ++++++------ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 2171b7bf817..84f5756f8ca 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -266,6 +266,7 @@ public: int zoomed_p = 0; int shown_flag = 0; volatile int was_shown_p = 0; + bool menu_bar_active_p = false; EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS) @@ -563,6 +564,15 @@ public: if (msg->what == B_KEY_DOWN || msg->what == B_KEY_UP) { struct haiku_key_event rq; + + /* Pass through key events to the regular dispatch mechanism + if the menu bar active, so that key navigation can work. */ + if (menu_bar_active_p) + { + BWindow::DispatchMessage (msg, handler); + return; + } + rq.window = this; int32_t code = msg->GetInt32 ("raw_char", 0); @@ -635,6 +645,7 @@ public: rq.window = this; haiku_write (MENU_BAR_OPEN, &rq); + menu_bar_active_p = true; } void @@ -644,6 +655,7 @@ public: rq.window = this; haiku_write (MENU_BAR_CLOSE, &rq); + menu_bar_active_p = false; } void @@ -908,6 +920,14 @@ public: { } + void + AttachedToWindow (void) + { + BWindow *window = Window (); + + window->SetKeyMenuBar (this); + } + void FrameResized (float newWidth, float newHeight) { @@ -2274,8 +2294,14 @@ BMenuBar_delete (void *menubar) { BView *vw = (BView *) menubar; BView *p = vw->Parent (); + EmacsWindow *window = (EmacsWindow *) p->Window (); + if (!p->LockLooper ()) gui_abort ("Failed to lock menu bar parent while removing menubar"); + window->SetKeyMenuBar (NULL); + /* MenusEnded isn't called if the menu bar is destroyed + before it closes. */ + window->menu_bar_active_p = false; vw->RemoveSelf (); p->UnlockLooper (); delete vw; diff --git a/src/haikufns.c b/src/haikufns.c index f010867fd93..4a0d2272d08 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -1291,8 +1291,8 @@ haiku_free_frame_resources (struct frame *f) Lisp_Object bar; struct scroll_bar *b; - block_input (); check_window_system (f); + block_input (); hlinfo = MOUSE_HL_INFO (f); window = FRAME_HAIKU_WINDOW (f); diff --git a/src/haikumenu.c b/src/haikumenu.c index 5cfcc75132d..f335bdacb40 100644 --- a/src/haikumenu.c +++ b/src/haikumenu.c @@ -630,12 +630,12 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_ } DEFUN ("haiku-menu-bar-open", Fhaiku_menu_bar_open, Shaiku_menu_bar_open, 0, 1, "i", - doc: /* Show the menu bar in FRAME. - -Move the mouse pointer onto the first element of FRAME's menu bar, and -cause it to be opened. If FRAME is nil or not given, use the selected -frame. If FRAME has no menu bar, a pop-up is displayed at the position -of the last non-menu event instead. */) + doc: /* Show and 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 is nil or not given, use the +selected frame. If FRAME has no menu bar, a pop-up is displayed at +the position of the last non-menu event instead. */) (Lisp_Object frame) { struct frame *f = decode_window_system_frame (frame); -- 2.39.2