mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-05 11:21:04 -08:00
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.
This commit is contained in:
parent
03c9257b11
commit
4d342f36a6
4 changed files with 61 additions and 16 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue