aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-01-25 11:19:20 +0000
committerPo Lu2022-01-25 11:19:20 +0000
commit4d342f36a6764aaf33c76d48d19899be621dc59b (patch)
tree8b305d8ed3e6fb9ceb7a0a6e91bea6fd47da3d79 /src
parent03c9257b119637703482e00816d054320b81f214 (diff)
downloademacs-4d342f36a6764aaf33c76d48d19899be621dc59b.tar.gz
emacs-4d342f36a6764aaf33c76d48d19899be621dc59b.zip
Improve reliability of menu bar updates on Haiku
* src/haiku_support.cc (class EmacsWindow): New fields `menu_update_cv', `menu_update_mutex' and `menu_updated_p'. (~EmacsWindow): Destroy cv and mutex. (MenusBeginning): Release lock and wait for condition to be become true. (EmacsWindow_signal_menu_update_complete): New function. * src/haiku_support.h (struct haiku_menu_bar_state_event): New field `no_lock'. * src/haikumenu.c (Fhaiku_menu_bar_open): Always update menu bar. * src/haikuterm.c (haiku_read_socket): Always update menu bar and signal the window thread after update completion.
Diffstat (limited to 'src')
-rw-r--r--src/haiku_support.cc44
-rw-r--r--src/haiku_support.h4
-rw-r--r--src/haikumenu.c5
-rw-r--r--src/haikuterm.c24
4 files changed, 61 insertions, 16 deletions
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index af30bc8b3cb..41e5b71182f 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -408,6 +408,9 @@ public:
408 window_look pre_override_redirect_style; 408 window_look pre_override_redirect_style;
409 window_feel pre_override_redirect_feel; 409 window_feel pre_override_redirect_feel;
410 uint32 pre_override_redirect_workspaces; 410 uint32 pre_override_redirect_workspaces;
411 pthread_mutex_t menu_update_mutex = PTHREAD_MUTEX_INITIALIZER;
412 pthread_cond_t menu_update_cv = PTHREAD_COND_INITIALIZER;
413 bool menu_updated_p = false;
411 414
412 EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK, 415 EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK,
413 B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS) 416 B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS)
@@ -433,6 +436,9 @@ public:
433 if (this->parent) 436 if (this->parent)
434 UnparentAndUnlink (); 437 UnparentAndUnlink ();
435 child_frame_lock.Unlock (); 438 child_frame_lock.Unlock ();
439
440 pthread_cond_destroy (&menu_update_cv);
441 pthread_mutex_destroy (&menu_update_mutex);
436 } 442 }
437 443
438 void 444 void
@@ -805,9 +811,36 @@ public:
805 MenusBeginning () 811 MenusBeginning ()
806 { 812 {
807 struct haiku_menu_bar_state_event rq; 813 struct haiku_menu_bar_state_event rq;
814 int lock_count = 0;
815 thread_id current_thread = find_thread (NULL);
816 thread_id window_thread = Thread ();
808 rq.window = this; 817 rq.window = this;
818 rq.no_lock = false;
819
820 if (window_thread != current_thread)
821 rq.no_lock = true;
809 822
810 haiku_write (MENU_BAR_OPEN, &rq); 823 haiku_write (MENU_BAR_OPEN, &rq);
824
825 if (!rq.no_lock)
826 {
827 while (IsLocked ())
828 {
829 ++lock_count;
830 UnlockLooper ();
831 }
832 pthread_mutex_lock (&menu_update_mutex);
833 while (!menu_updated_p)
834 pthread_cond_wait (&menu_update_cv,
835 &menu_update_mutex);
836 menu_updated_p = false;
837 pthread_mutex_unlock (&menu_update_mutex);
838 for (; lock_count; --lock_count)
839 {
840 if (!LockLooper ())
841 gui_abort ("Failed to lock after cv signal denoting menu update");
842 }
843 }
811 menu_bar_active_p = true; 844 menu_bar_active_p = true;
812 } 845 }
813 846
@@ -3212,3 +3245,14 @@ be_find_setting (const char *name)
3212 3245
3213 return value; 3246 return value;
3214} 3247}
3248
3249void
3250EmacsWindow_signal_menu_update_complete (void *window)
3251{
3252 EmacsWindow *w = (EmacsWindow *) window;
3253
3254 pthread_mutex_lock (&w->menu_update_mutex);
3255 w->menu_updated_p = true;
3256 pthread_cond_signal (&w->menu_update_cv);
3257 pthread_mutex_unlock (&w->menu_update_mutex);
3258}
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 6ddc28759b5..8d4dddd90fa 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -299,6 +299,7 @@ struct haiku_menu_bar_resize_event
299struct haiku_menu_bar_state_event 299struct haiku_menu_bar_state_event
300{ 300{
301 void *window; 301 void *window;
302 bool no_lock;
302}; 303};
303 304
304#define HAIKU_THIN 0 305#define HAIKU_THIN 0
@@ -864,6 +865,9 @@ extern "C"
864 extern const char * 865 extern const char *
865 be_find_setting (const char *name); 866 be_find_setting (const char *name);
866 867
868 extern void
869 EmacsWindow_signal_menu_update_complete (void *window);
870
867#ifdef __cplusplus 871#ifdef __cplusplus
868 extern void * 872 extern void *
869 find_appropriate_view_for_draw (void *vw); 873 find_appropriate_view_for_draw (void *vw);
diff --git a/src/haikumenu.c b/src/haikumenu.c
index 1c75e0f9a42..3fee5831608 100644
--- a/src/haikumenu.c
+++ b/src/haikumenu.c
@@ -644,10 +644,7 @@ the position of the last non-menu event instead. */)
644 struct frame *f = decode_window_system_frame (frame); 644 struct frame *f = decode_window_system_frame (frame);
645 645
646 if (FRAME_EXTERNAL_MENU_BAR (f)) 646 if (FRAME_EXTERNAL_MENU_BAR (f))
647 { 647 set_frame_menubar (f, 1);
648 if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
649 set_frame_menubar (f, 1);
650 }
651 else 648 else
652 { 649 {
653 return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map), 650 return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map),
diff --git a/src/haikuterm.c b/src/haikuterm.c
index 7ab41805ead..c8cc02a2988 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -3178,20 +3178,20 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3178 3178
3179 if (type == MENU_BAR_OPEN) 3179 if (type == MENU_BAR_OPEN)
3180 { 3180 {
3181 if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p) 3181 BView_draw_lock (FRAME_HAIKU_VIEW (f));
3182 { 3182 /* This shouldn't be here, but nsmenu does it, so
3183 BView_draw_lock (FRAME_HAIKU_VIEW (f)); 3183 it should probably be safe. */
3184 /* This shouldn't be here, but nsmenu does it, so 3184 int was_waiting_for_input_p = waiting_for_input;
3185 it should probably be safe. */ 3185 if (waiting_for_input)
3186 int was_waiting_for_input_p = waiting_for_input; 3186 waiting_for_input = 0;
3187 if (waiting_for_input) 3187 set_frame_menubar (f, 1);
3188 waiting_for_input = 0; 3188 waiting_for_input = was_waiting_for_input_p;
3189 set_frame_menubar (f, 1); 3189 BView_draw_unlock (FRAME_HAIKU_VIEW (f));
3190 waiting_for_input = was_waiting_for_input_p;
3191 BView_draw_unlock (FRAME_HAIKU_VIEW (f));
3192 }
3193 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1; 3190 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
3194 popup_activated_p += 1; 3191 popup_activated_p += 1;
3192
3193 if (!b->no_lock)
3194 EmacsWindow_signal_menu_update_complete (b->window);
3195 } 3195 }
3196 else 3196 else
3197 { 3197 {