]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve reliability of menu bar updates on Haiku
authorPo Lu <luangruo@yahoo.com>
Tue, 25 Jan 2022 11:19:20 +0000 (11:19 +0000)
committerPo Lu <luangruo@yahoo.com>
Tue, 25 Jan 2022 11:19:20 +0000 (11:19 +0000)
* 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.

src/haiku_support.cc
src/haiku_support.h
src/haikumenu.c
src/haikuterm.c

index af30bc8b3cb412d4864f8bc8a1d371201507ac3f..41e5b71182f0b280b80c1b67101f3ebad8b76a33 100644 (file)
@@ -408,6 +408,9 @@ public:
   window_look pre_override_redirect_style;
   window_feel pre_override_redirect_feel;
   uint32 pre_override_redirect_workspaces;
+  pthread_mutex_t menu_update_mutex = PTHREAD_MUTEX_INITIALIZER;
+  pthread_cond_t menu_update_cv = PTHREAD_COND_INITIALIZER;
+  bool menu_updated_p = false;
 
   EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK,
                            B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS)
@@ -433,6 +436,9 @@ public:
     if (this->parent)
       UnparentAndUnlink ();
     child_frame_lock.Unlock ();
+
+    pthread_cond_destroy (&menu_update_cv);
+    pthread_mutex_destroy (&menu_update_mutex);
   }
 
   void
@@ -805,9 +811,36 @@ 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;
 
     haiku_write (MENU_BAR_OPEN, &rq);
+
+    if (!rq.no_lock)
+      {
+       while (IsLocked ())
+         {
+           ++lock_count;
+           UnlockLooper ();
+         }
+       pthread_mutex_lock (&menu_update_mutex);
+       while (!menu_updated_p)
+         pthread_cond_wait (&menu_update_cv,
+                            &menu_update_mutex);
+       menu_updated_p = false;
+       pthread_mutex_unlock (&menu_update_mutex);
+       for (; lock_count; --lock_count)
+         {
+           if (!LockLooper ())
+             gui_abort ("Failed to lock after cv signal denoting menu update");
+         }
+      }
     menu_bar_active_p = true;
   }
 
@@ -3212,3 +3245,14 @@ be_find_setting (const char *name)
 
   return value;
 }
+
+void
+EmacsWindow_signal_menu_update_complete (void *window)
+{
+  EmacsWindow *w = (EmacsWindow *) window;
+
+  pthread_mutex_lock (&w->menu_update_mutex);
+  w->menu_updated_p = true;
+  pthread_cond_signal (&w->menu_update_cv);
+  pthread_mutex_unlock (&w->menu_update_mutex);
+}
index 6ddc28759b5649dfac5f4c65164561490e217c14..8d4dddd90fac039528206ec4c83604a12fe19e5f 100644 (file)
@@ -299,6 +299,7 @@ struct haiku_menu_bar_resize_event
 struct haiku_menu_bar_state_event
 {
   void *window;
+  bool no_lock;
 };
 
 #define HAIKU_THIN 0
@@ -864,6 +865,9 @@ extern "C"
   extern const char *
   be_find_setting (const char *name);
 
+  extern void
+  EmacsWindow_signal_menu_update_complete (void *window);
+
 #ifdef __cplusplus
   extern void *
   find_appropriate_view_for_draw (void *vw);
index 1c75e0f9a42e6b2a470c58dfb5f0df257b87ebcf..3fee5831608986c7192884da691e732f178cf718 100644 (file)
@@ -644,10 +644,7 @@ the position of the last non-menu event instead.  */)
   struct frame *f = decode_window_system_frame (frame);
 
   if (FRAME_EXTERNAL_MENU_BAR (f))
-    {
-      if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
-       set_frame_menubar (f, 1);
-    }
+    set_frame_menubar (f, 1);
   else
     {
       return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map),
index 7ab41805ead31288e600568d8c6673b23edf3b09..c8cc02a29885f9695e94421767e5c72bb8cc98a7 100644 (file)
@@ -3178,20 +3178,20 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
 
            if (type == MENU_BAR_OPEN)
              {
-               if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
-                 {
-                   BView_draw_lock (FRAME_HAIKU_VIEW (f));
-                   /* 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));
-                 }
+               BView_draw_lock (FRAME_HAIKU_VIEW (f));
+               /* 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));
                FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
                popup_activated_p += 1;
+
+               if (!b->no_lock)
+                 EmacsWindow_signal_menu_update_complete (b->window);
              }
            else
              {