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.
This commit is contained in:
parent
33cc12498b
commit
2e0a2ecc29
4 changed files with 70 additions and 48 deletions
|
@ -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 @@ class EmacsWindow : public BWindow
|
|||
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 @@ class EmacsWindow : public BWindow
|
|||
MenusBeginning ()
|
||||
{
|
||||
struct haiku_menu_bar_state_event rq;
|
||||
int lock_count = 0;
|
||||
thread_id current_thread = find_thread (NULL);
|
||||
thread_id window_thread = Thread ();
|
||||
int lock_count;
|
||||
|
||||
rq.window = this;
|
||||
rq.no_lock = false;
|
||||
lock_count = 0;
|
||||
|
||||
if (window_thread != current_thread)
|
||||
rq.no_lock = true;
|
||||
|
||||
haiku_write (MENU_BAR_OPEN, &rq);
|
||||
|
||||
if (!rq.no_lock)
|
||||
if (!menus_begun)
|
||||
{
|
||||
haiku_write (MENU_BAR_OPEN, &rq);
|
||||
while (IsLocked ())
|
||||
{
|
||||
++lock_count;
|
||||
|
@ -932,6 +930,9 @@ class EmacsWindow : public BWindow
|
|||
gui_abort ("Failed to lock after cv signal denoting menu update");
|
||||
}
|
||||
}
|
||||
else
|
||||
*menus_begun = true;
|
||||
|
||||
menu_bar_active_p = true;
|
||||
}
|
||||
|
||||
|
@ -1244,6 +1245,37 @@ class EmacsMenuBar : public BMenuBar
|
|||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue