From 5bc3ed492bffa962ef326387f2476b66442a006c Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 17 Apr 2022 08:13:49 +0000 Subject: [PATCH] Fix race conditions waiting for menu bar resize events on Haiku * src/haikufns.c (haiku_create_frame, haiku_create_tip_frame): Clear `wait_for_event_type'. (haiku_set_menu_bar_lines): Clean up coding style. * src/haikuterm.c (haiku_wait_for_event): New function. (haiku_read_socket): Implement waiting for MENU_BAR_RESIZE events. * src/haikuterm.h (struct haiku_output): New field `wait_for_event_type'. --- src/haikufns.c | 6 +++++- src/haikuterm.c | 45 +++++++++++++++++++++++++++++++++++++++++---- src/haikuterm.h | 4 ++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/haikufns.c b/src/haikufns.c index b040e6cafaa..151874e26fd 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -635,6 +635,7 @@ haiku_create_frame (Lisp_Object parms) f->output_method = output_haiku; f->output_data.haiku = xzalloc (sizeof *f->output_data.haiku); + f->output_data.haiku->wait_for_event_type = -1; fset_icon_name (f, gui_display_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title", @@ -946,6 +947,7 @@ haiku_create_tip_frame (Lisp_Object parms) counts etc. */ f->output_method = output_haiku; f->output_data.haiku = xzalloc (sizeof *f->output_data.haiku); + f->output_data.haiku->wait_for_event_type = -1; f->tooltip = true; fset_icon_name (f, Qnil); @@ -1264,9 +1266,11 @@ haiku_set_override_redirect (struct frame *f, Lisp_Object new_value, static void haiku_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) { + int nlines; + if (FRAME_TOOLTIP_P (f)) return; - int nlines; + if (TYPE_RANGED_FIXNUMP (int, value)) nlines = XFIXNUM (value); else diff --git a/src/haikuterm.c b/src/haikuterm.c index 8499dad932e..203bfa3f81a 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -2766,6 +2766,40 @@ flush_dirty_back_buffers (void) unblock_input (); } +/* N.B. that support for TYPE must be explictly added to + haiku_read_socket. */ +void +haiku_wait_for_event (struct frame *f, int type) +{ + int input_blocked_to; + object_wait_info info; + specpdl_ref depth; + + input_blocked_to = interrupt_input_blocked; + info.object = port_application_to_emacs; + info.type = B_OBJECT_TYPE_PORT; + info.events = B_EVENT_READ; + + depth = SPECPDL_INDEX (); + specbind (Qinhibit_quit, Qt); + + FRAME_OUTPUT_DATA (f)->wait_for_event_type = type; + + while (FRAME_OUTPUT_DATA (f)->wait_for_event_type == type) + { + if (wait_for_objects (&info, 1) < B_OK) + continue; + + pending_signals = true; + /* This will call the read_socket_hook. */ + totally_unblock_input (); + interrupt_input_blocked = input_blocked_to; + info.events = B_EVENT_READ; + } + + unbind_to (depth, Qnil); +} + static int haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) { @@ -3453,7 +3487,6 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) break; } - case MENU_BAR_RESIZE: { struct haiku_menu_bar_resize_event *b = buf; @@ -3462,13 +3495,17 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) if (!f || !FRAME_EXTERNAL_MENU_BAR (f)) continue; + if (FRAME_OUTPUT_DATA (f)->wait_for_event_type + == MENU_BAR_RESIZE) + FRAME_OUTPUT_DATA (f)->wait_for_event_type = -1; + int old_height = FRAME_MENU_BAR_HEIGHT (f); FRAME_MENU_BAR_HEIGHT (f) = b->height + 1; - FRAME_MENU_BAR_LINES (f) = - (b->height + FRAME_LINE_HEIGHT (f)) / FRAME_LINE_HEIGHT (f); + FRAME_MENU_BAR_LINES (f) + = (b->height + FRAME_LINE_HEIGHT (f)) / FRAME_LINE_HEIGHT (f); - if (old_height != b->height) + if (old_height != b->height + 1) { adjust_frame_size (f, -1, -1, 3, true, Qmenu_bar_lines); haiku_clear_under_internal_border (f); diff --git a/src/haikuterm.h b/src/haikuterm.h index df4e7d47e8f..903a21d29f7 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h @@ -179,6 +179,9 @@ struct haiku_output /* If non-NULL, the last menu bar click event received. */ struct haiku_menu_bar_click_event *saved_menu_event; + + /* The type of any event that's being waited for. */ + int wait_for_event_type; }; struct x_output @@ -295,6 +298,7 @@ extern Lisp_Object haiku_menu_show (struct frame *, int, int, int, Lisp_Object, const char **); extern Lisp_Object haiku_popup_dialog (struct frame *, Lisp_Object, Lisp_Object); extern void haiku_activate_menubar (struct frame *); +extern void haiku_wait_for_event (struct frame *, int); extern void haiku_note_drag_motion (void); extern void initialize_frame_menubar (struct frame *); -- 2.39.2