[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 2e0a2ecc29: Fix freezes when trying to accelerate menu bar on Hai
From: |
Po Lu |
Subject: |
master 2e0a2ecc29: Fix freezes when trying to accelerate menu bar on Haiku |
Date: |
Tue, 12 Apr 2022 20:51:25 -0400 (EDT) |
branch: master
commit 2e0a2ecc294aa2273ffbef27f49706db2cf40062
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Fix freezes when trying to accelerate menu bar on Haiku
* src/haiku_support.cc (class EmacsWindow): New field
`menus_begun'.
(MenusBeginning): Don't send menu bar open events when that is
set, instead set it to true.
(BMenuBar_start_tracking): Stop locking the menu bar here and
send a special BE_MENU_BAR_OPEN event instead.
* src/haiku_support.h (struct haiku_menu_bar_state_event):
Delete field `no_lock'.
* src/haikumenu.c (Fhaiku_menu_bar_open):
* src/haikuterm.c (haiku_read_socket): Update accordingly.
---
src/haiku_support.cc | 72 +++++++++++++++++++++++++++++++++++++---------------
src/haiku_support.h | 3 +--
src/haikumenu.c | 15 +++++++----
src/haikuterm.c | 28 ++++++--------------
4 files changed, 70 insertions(+), 48 deletions(-)
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index cb38a572f7..826e1c2100 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -87,6 +87,8 @@ enum
WAIT_FOR_RELEASE = 3001,
RELEASE_NOW = 3002,
CANCEL_DROP = 3003,
+ SHOW_MENU_BAR = 3004,
+ BE_MENU_BAR_OPEN = 3005,
};
static color_space dpy_color_space = B_NO_COLOR_SPACE;
@@ -423,6 +425,7 @@ public:
pthread_cond_t menu_update_cv = PTHREAD_COND_INITIALIZER;
bool menu_updated_p = false;
int window_id;
+ bool *menus_begun = NULL;
EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK,
B_NORMAL_WINDOW_FEEL,
B_NO_SERVER_SIDE_WINDOW_MODIFIERS)
@@ -902,19 +905,14 @@ public:
MenusBeginning ()
{
struct haiku_menu_bar_state_event rq;
- int lock_count = 0;
- thread_id current_thread = find_thread (NULL);
- thread_id window_thread = Thread ();
- rq.window = this;
- rq.no_lock = false;
-
- if (window_thread != current_thread)
- rq.no_lock = true;
+ int lock_count;
- haiku_write (MENU_BAR_OPEN, &rq);
+ rq.window = this;
+ lock_count = 0;
- if (!rq.no_lock)
+ if (!menus_begun)
{
+ haiku_write (MENU_BAR_OPEN, &rq);
while (IsLocked ())
{
++lock_count;
@@ -932,6 +930,9 @@ public:
gui_abort ("Failed to lock after cv signal denoting menu update");
}
}
+ else
+ *menus_begun = true;
+
menu_bar_active_p = true;
}
@@ -1244,6 +1245,37 @@ public:
BMenuBar::MouseMoved (point, transit, msg);
}
+
+ void
+ MessageReceived (BMessage *msg)
+ {
+ BRect frame;
+ BPoint pt, l;
+ EmacsWindow *window;
+ bool menus_begun;
+
+ if (msg->what == SHOW_MENU_BAR)
+ {
+ window = (EmacsWindow *) Window ();
+ frame = Frame ();
+ pt = frame.LeftTop ();
+ l = pt;
+ menus_begun = false;
+ Parent ()->ConvertToScreen (&pt);
+
+ window->menus_begun = &menus_begun;
+ set_mouse_position (pt.x, pt.y);
+ MouseDown (l);
+ window->menus_begun = NULL;
+
+ if (!menus_begun)
+ msg->SendReply (msg);
+ else
+ msg->SendReply (BE_MENU_BAR_OPEN);
+ }
+ else
+ BMenuBar::MessageReceived (msg);
+ }
};
class EmacsView : public BView
@@ -3748,20 +3780,18 @@ EmacsWindow_unzoom (void *window)
w->UnZoom ();
}
-/* Move the pointer into MBAR and start tracking. */
-void
+/* Move the pointer into MBAR and start tracking. Return whether the
+ menu bar was opened correctly. */
+bool
BMenuBar_start_tracking (void *mbar)
{
EmacsMenuBar *mb = (EmacsMenuBar *) mbar;
- if (!mb->LockLooper ())
- gui_abort ("Couldn't lock menubar");
- BRect frame = mb->Frame ();
- BPoint pt = frame.LeftTop ();
- BPoint l = pt;
- mb->Parent ()->ConvertToScreen (&pt);
- set_mouse_position (pt.x, pt.y);
- mb->MouseDown (l);
- mb->UnlockLooper ();
+ BMessenger messenger (mb);
+ BMessage reply;
+
+ messenger.SendMessage (SHOW_MENU_BAR, &reply);
+
+ return reply.what == BE_MENU_BAR_OPEN;
}
#ifdef HAVE_NATIVE_IMAGE_API
diff --git a/src/haiku_support.h b/src/haiku_support.h
index d0a78c693b..1de135c55b 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -328,7 +328,6 @@ struct haiku_menu_bar_resize_event
struct haiku_menu_bar_state_event
{
void *window;
- bool no_lock;
};
#define HAIKU_THIN 0
@@ -869,7 +868,7 @@ extern "C"
be_translate_bitmap_from_memory (const void *buf, size_t bytes);
#endif
- extern void
+ extern bool
BMenuBar_start_tracking (void *mbar);
extern size_t
diff --git a/src/haikumenu.c b/src/haikumenu.c
index 4cee69826d..22e9c4ecad 100644
--- a/src/haikumenu.c
+++ b/src/haikumenu.c
@@ -752,19 +752,24 @@ the position of the last non-menu event instead. */)
(Lisp_Object frame)
{
struct frame *f = decode_window_system_frame (frame);
+ int rc;
if (FRAME_EXTERNAL_MENU_BAR (f))
{
block_input ();
set_frame_menubar (f, 1);
- BMenuBar_start_tracking (FRAME_HAIKU_MENU_BAR (f));
+ rc = BMenuBar_start_tracking (FRAME_HAIKU_MENU_BAR (f));
unblock_input ();
+
+ if (!rc)
+ return Qnil;
+
+ FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
+ popup_activated_p += 1;
}
else
- {
- return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map),
- last_nonmenu_event);
- }
+ return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map),
+ last_nonmenu_event);
return Qnil;
}
diff --git a/src/haikuterm.c b/src/haikuterm.c
index f07e9e0b29..667ed685c5 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -3517,36 +3517,24 @@ haiku_read_socket (struct terminal *terminal, struct
input_event *hold_quit)
{
struct haiku_menu_bar_state_event *b = buf;
struct frame *f = haiku_window_to_frame (b->window);
+ int was_waiting_for_input_p;
if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
continue;
if (type == MENU_BAR_OPEN)
{
- /* b->no_lock means that MenusBeginning was called
- from the main thread, which means tracking was
- started manually, and we have already updated the
- menu bar. */
- if (!b->no_lock)
- {
- BView_draw_lock (FRAME_HAIKU_VIEW (f), false, 0, 0, 0, 0);
- /* This shouldn't be here, but nsmenu does it, so
- it should probably be safe. */
- int was_waiting_for_input_p = waiting_for_input;
- if (waiting_for_input)
- waiting_for_input = 0;
- set_frame_menubar (f, 1);
- waiting_for_input = was_waiting_for_input_p;
- BView_draw_unlock (FRAME_HAIKU_VIEW (f));
- }
+ was_waiting_for_input_p = waiting_for_input;
+ if (waiting_for_input)
+ waiting_for_input = 0;
+
+ set_frame_menubar (f, 1);
+ waiting_for_input = was_waiting_for_input_p;
- /* But set the flag anyway, because the menu will end
- from the window thread. */
FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
popup_activated_p += 1;
- if (!b->no_lock)
- EmacsWindow_signal_menu_update_complete (b->window);
+ EmacsWindow_signal_menu_update_complete (b->window);
}
else
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 2e0a2ecc29: Fix freezes when trying to accelerate menu bar on Haiku,
Po Lu <=