aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-04-13 00:47:00 +0000
committerPo Lu2022-04-13 00:51:13 +0000
commit2e0a2ecc294aa2273ffbef27f49706db2cf40062 (patch)
treedac4ecc80fb38252570fc8efabfbd3bf639a2cdb /src
parent33cc12498b0f9191437d1f273d0467d0f69d48f3 (diff)
downloademacs-2e0a2ecc294aa2273ffbef27f49706db2cf40062.tar.gz
emacs-2e0a2ecc294aa2273ffbef27f49706db2cf40062.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/haiku_support.cc72
-rw-r--r--src/haiku_support.h3
-rw-r--r--src/haikumenu.c15
-rw-r--r--src/haikuterm.c28
4 files changed, 70 insertions, 48 deletions
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index cb38a572f7c..826e1c21005 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -87,6 +87,8 @@ enum
87 WAIT_FOR_RELEASE = 3001, 87 WAIT_FOR_RELEASE = 3001,
88 RELEASE_NOW = 3002, 88 RELEASE_NOW = 3002,
89 CANCEL_DROP = 3003, 89 CANCEL_DROP = 3003,
90 SHOW_MENU_BAR = 3004,
91 BE_MENU_BAR_OPEN = 3005,
90 }; 92 };
91 93
92static color_space dpy_color_space = B_NO_COLOR_SPACE; 94static color_space dpy_color_space = B_NO_COLOR_SPACE;
@@ -423,6 +425,7 @@ public:
423 pthread_cond_t menu_update_cv = PTHREAD_COND_INITIALIZER; 425 pthread_cond_t menu_update_cv = PTHREAD_COND_INITIALIZER;
424 bool menu_updated_p = false; 426 bool menu_updated_p = false;
425 int window_id; 427 int window_id;
428 bool *menus_begun = NULL;
426 429
427 EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK, 430 EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK,
428 B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS) 431 B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS)
@@ -902,19 +905,14 @@ public:
902 MenusBeginning () 905 MenusBeginning ()
903 { 906 {
904 struct haiku_menu_bar_state_event rq; 907 struct haiku_menu_bar_state_event rq;
905 int lock_count = 0; 908 int lock_count;
906 thread_id current_thread = find_thread (NULL);
907 thread_id window_thread = Thread ();
908 rq.window = this;
909 rq.no_lock = false;
910
911 if (window_thread != current_thread)
912 rq.no_lock = true;
913 909
914 haiku_write (MENU_BAR_OPEN, &rq); 910 rq.window = this;
911 lock_count = 0;
915 912
916 if (!rq.no_lock) 913 if (!menus_begun)
917 { 914 {
915 haiku_write (MENU_BAR_OPEN, &rq);
918 while (IsLocked ()) 916 while (IsLocked ())
919 { 917 {
920 ++lock_count; 918 ++lock_count;
@@ -932,6 +930,9 @@ public:
932 gui_abort ("Failed to lock after cv signal denoting menu update"); 930 gui_abort ("Failed to lock after cv signal denoting menu update");
933 } 931 }
934 } 932 }
933 else
934 *menus_begun = true;
935
935 menu_bar_active_p = true; 936 menu_bar_active_p = true;
936 } 937 }
937 938
@@ -1244,6 +1245,37 @@ public:
1244 1245
1245 BMenuBar::MouseMoved (point, transit, msg); 1246 BMenuBar::MouseMoved (point, transit, msg);
1246 } 1247 }
1248
1249 void
1250 MessageReceived (BMessage *msg)
1251 {
1252 BRect frame;
1253 BPoint pt, l;
1254 EmacsWindow *window;
1255 bool menus_begun;
1256
1257 if (msg->what == SHOW_MENU_BAR)
1258 {
1259 window = (EmacsWindow *) Window ();
1260 frame = Frame ();
1261 pt = frame.LeftTop ();
1262 l = pt;
1263 menus_begun = false;
1264 Parent ()->ConvertToScreen (&pt);
1265
1266 window->menus_begun = &menus_begun;
1267 set_mouse_position (pt.x, pt.y);
1268 MouseDown (l);
1269 window->menus_begun = NULL;
1270
1271 if (!menus_begun)
1272 msg->SendReply (msg);
1273 else
1274 msg->SendReply (BE_MENU_BAR_OPEN);
1275 }
1276 else
1277 BMenuBar::MessageReceived (msg);
1278 }
1247}; 1279};
1248 1280
1249class EmacsView : public BView 1281class EmacsView : public BView
@@ -3748,20 +3780,18 @@ EmacsWindow_unzoom (void *window)
3748 w->UnZoom (); 3780 w->UnZoom ();
3749} 3781}
3750 3782
3751/* Move the pointer into MBAR and start tracking. */ 3783/* Move the pointer into MBAR and start tracking. Return whether the
3752void 3784 menu bar was opened correctly. */
3785bool
3753BMenuBar_start_tracking (void *mbar) 3786BMenuBar_start_tracking (void *mbar)
3754{ 3787{
3755 EmacsMenuBar *mb = (EmacsMenuBar *) mbar; 3788 EmacsMenuBar *mb = (EmacsMenuBar *) mbar;
3756 if (!mb->LockLooper ()) 3789 BMessenger messenger (mb);
3757 gui_abort ("Couldn't lock menubar"); 3790 BMessage reply;
3758 BRect frame = mb->Frame (); 3791
3759 BPoint pt = frame.LeftTop (); 3792 messenger.SendMessage (SHOW_MENU_BAR, &reply);
3760 BPoint l = pt; 3793
3761 mb->Parent ()->ConvertToScreen (&pt); 3794 return reply.what == BE_MENU_BAR_OPEN;
3762 set_mouse_position (pt.x, pt.y);
3763 mb->MouseDown (l);
3764 mb->UnlockLooper ();
3765} 3795}
3766 3796
3767#ifdef HAVE_NATIVE_IMAGE_API 3797#ifdef HAVE_NATIVE_IMAGE_API
diff --git a/src/haiku_support.h b/src/haiku_support.h
index d0a78c693b9..1de135c55b3 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -328,7 +328,6 @@ struct haiku_menu_bar_resize_event
328struct haiku_menu_bar_state_event 328struct haiku_menu_bar_state_event
329{ 329{
330 void *window; 330 void *window;
331 bool no_lock;
332}; 331};
333 332
334#define HAIKU_THIN 0 333#define HAIKU_THIN 0
@@ -869,7 +868,7 @@ extern "C"
869 be_translate_bitmap_from_memory (const void *buf, size_t bytes); 868 be_translate_bitmap_from_memory (const void *buf, size_t bytes);
870#endif 869#endif
871 870
872 extern void 871 extern bool
873 BMenuBar_start_tracking (void *mbar); 872 BMenuBar_start_tracking (void *mbar);
874 873
875 extern size_t 874 extern size_t
diff --git a/src/haikumenu.c b/src/haikumenu.c
index 4cee69826da..22e9c4ecad3 100644
--- a/src/haikumenu.c
+++ b/src/haikumenu.c
@@ -752,19 +752,24 @@ the position of the last non-menu event instead. */)
752 (Lisp_Object frame) 752 (Lisp_Object frame)
753{ 753{
754 struct frame *f = decode_window_system_frame (frame); 754 struct frame *f = decode_window_system_frame (frame);
755 int rc;
755 756
756 if (FRAME_EXTERNAL_MENU_BAR (f)) 757 if (FRAME_EXTERNAL_MENU_BAR (f))
757 { 758 {
758 block_input (); 759 block_input ();
759 set_frame_menubar (f, 1); 760 set_frame_menubar (f, 1);
760 BMenuBar_start_tracking (FRAME_HAIKU_MENU_BAR (f)); 761 rc = BMenuBar_start_tracking (FRAME_HAIKU_MENU_BAR (f));
761 unblock_input (); 762 unblock_input ();
763
764 if (!rc)
765 return Qnil;
766
767 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
768 popup_activated_p += 1;
762 } 769 }
763 else 770 else
764 { 771 return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map),
765 return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map), 772 last_nonmenu_event);
766 last_nonmenu_event);
767 }
768 773
769 return Qnil; 774 return Qnil;
770} 775}
diff --git a/src/haikuterm.c b/src/haikuterm.c
index f07e9e0b296..667ed685c52 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -3517,36 +3517,24 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3517 { 3517 {
3518 struct haiku_menu_bar_state_event *b = buf; 3518 struct haiku_menu_bar_state_event *b = buf;
3519 struct frame *f = haiku_window_to_frame (b->window); 3519 struct frame *f = haiku_window_to_frame (b->window);
3520 int was_waiting_for_input_p;
3520 3521
3521 if (!f || !FRAME_EXTERNAL_MENU_BAR (f)) 3522 if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
3522 continue; 3523 continue;
3523 3524
3524 if (type == MENU_BAR_OPEN) 3525 if (type == MENU_BAR_OPEN)
3525 { 3526 {
3526 /* b->no_lock means that MenusBeginning was called 3527 was_waiting_for_input_p = waiting_for_input;
3527 from the main thread, which means tracking was 3528 if (waiting_for_input)
3528 started manually, and we have already updated the 3529 waiting_for_input = 0;
3529 menu bar. */ 3530
3530 if (!b->no_lock) 3531 set_frame_menubar (f, 1);
3531 { 3532 waiting_for_input = was_waiting_for_input_p;
3532 BView_draw_lock (FRAME_HAIKU_VIEW (f), false, 0, 0, 0, 0);
3533 /* This shouldn't be here, but nsmenu does it, so
3534 it should probably be safe. */
3535 int was_waiting_for_input_p = waiting_for_input;
3536 if (waiting_for_input)
3537 waiting_for_input = 0;
3538 set_frame_menubar (f, 1);
3539 waiting_for_input = was_waiting_for_input_p;
3540 BView_draw_unlock (FRAME_HAIKU_VIEW (f));
3541 }
3542 3533
3543 /* But set the flag anyway, because the menu will end
3544 from the window thread. */
3545 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1; 3534 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
3546 popup_activated_p += 1; 3535 popup_activated_p += 1;
3547 3536
3548 if (!b->no_lock) 3537 EmacsWindow_signal_menu_update_complete (b->window);
3549 EmacsWindow_signal_menu_update_complete (b->window);
3550 } 3538 }
3551 else 3539 else
3552 { 3540 {