[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master dad7ee2353 1/2: Handle GUI input while inside popup dialog on Hai
From: |
Po Lu |
Subject: |
master dad7ee2353 1/2: Handle GUI input while inside popup dialog on Haiku |
Date: |
Sun, 20 Feb 2022 05:43:46 -0500 (EST) |
branch: master
commit dad7ee23539176561be99f3e124871d893e7c600
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Handle GUI input while inside popup dialog on Haiku
* src/haiku_support.cc (alert_popup_value): New variable.
(be_alert_thread_entry): New function.
(BAlert_go): Complete rewrite that allows async input to be
handled while the popup is active.
* src/haiku_support.h: Update prototypes.
* src/haikumenu.c (haiku_dialog_show, haiku_popup_dialog): Stop
blocking input and pass required callbacks to `BAlert_go'.
* src/haikuterm.c (haiku_term_init): Set interrupt input mode to
t.
---
src/haiku_support.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++++++---
src/haiku_support.h | 7 ++++--
src/haikumenu.c | 9 +++----
src/haikuterm.c | 2 +-
4 files changed, 76 insertions(+), 10 deletions(-)
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index f867e775f8..0f4ed169fb 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -115,6 +115,7 @@ static BLocker child_frame_lock;
static BLocker movement_locker;
static BMessage volatile *popup_track_message;
+static int32 volatile alert_popup_value;
/* This could be a private API, but it's used by (at least) the Qt
port, so it's probably here to stay. */
@@ -2685,12 +2686,73 @@ BAlert_add_button (void *alert, const char *text)
return al->ButtonAt (al->CountButtons () - 1);
}
+static int32
+be_alert_thread_entry (void *thread_data)
+{
+ BAlert *alert = (BAlert *) thread_data;
+ int32 value;
+
+ if (alert->LockLooper ())
+ value = alert->Go ();
+ else
+ value = -1;
+
+ alert_popup_value = value;
+ return 0;
+}
+
/* Run ALERT, returning the number of the button that was selected,
or -1 if no button was selected before the alert was closed. */
-int32_t
-BAlert_go (void *alert)
+int32
+BAlert_go (void *alert,
+ void (*block_input_function) (void),
+ void (*unblock_input_function) (void),
+ void (*process_pending_signals_function) (void))
{
- return ((BAlert *) alert)->Go ();
+ struct object_wait_info infos[2];
+ ssize_t stat;
+ BAlert *alert_object = (BAlert *) alert;
+
+ infos[0].object = port_application_to_emacs;
+ infos[0].type = B_OBJECT_TYPE_PORT;
+ infos[0].events = B_EVENT_READ;
+
+ block_input_function ();
+ /* Alerts are created locked, just like other windows. */
+ alert_object->UnlockLooper ();
+ infos[1].object = spawn_thread (be_alert_thread_entry,
+ "Popup tracker",
+ B_DEFAULT_MEDIA_PRIORITY,
+ alert);
+ infos[1].type = B_OBJECT_TYPE_THREAD;
+ infos[1].events = B_EVENT_INVALID;
+ unblock_input_function ();
+
+ if (infos[1].object < B_OK)
+ return -1;
+
+ block_input_function ();
+ resume_thread (infos[1].object);
+ unblock_input_function ();
+
+ while (true)
+ {
+ stat = wait_for_objects ((object_wait_info *) &infos, 2);
+
+ if (stat == B_INTERRUPTED)
+ continue;
+ else if (stat < B_OK)
+ gui_abort ("Failed to wait for popup dialog");
+
+ if (infos[1].events & B_EVENT_INVALID)
+ return alert_popup_value;
+
+ if (infos[0].events & B_EVENT_READ)
+ process_pending_signals_function ();
+
+ infos[0].events = B_EVENT_READ;
+ infos[1].events = B_EVENT_INVALID;
+ }
}
/* Enable or disable BUTTON depending on ENABLED_P. */
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 67fbd8c5e0..9fc81c2875 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -754,8 +754,11 @@ extern "C"
extern void *
BAlert_add_button (void *alert, const char *text);
- extern int32_t
- BAlert_go (void *alert);
+ extern int32
+ BAlert_go (void *alert,
+ void (*block_input_function) (void),
+ void (*unblock_input_function) (void),
+ void (*process_pending_signals_function) (void));
extern void
BButton_set_enabled (void *button, int enabled_p);
diff --git a/src/haikumenu.c b/src/haikumenu.c
index 002898de7a..61c48a5e10 100644
--- a/src/haikumenu.c
+++ b/src/haikumenu.c
@@ -255,10 +255,13 @@ haiku_dialog_show (struct frame *f, Lisp_Object title,
++nb_buttons;
i += MENU_ITEMS_ITEM_LENGTH;
}
-
- int32_t val = BAlert_go (alert);
unblock_input ();
+ unrequest_sigio ();
+ int32_t val = BAlert_go (alert, block_input, unblock_input,
+ process_pending_signals);
+ request_sigio ();
+
if (val < 0)
quit ();
else
@@ -291,9 +294,7 @@ haiku_popup_dialog (struct frame *f, Lisp_Object header,
Lisp_Object contents)
list_of_panes (list1 (contents));
/* Display them in a dialog box. */
- block_input ();
selection = haiku_dialog_show (f, title, header, &error_name);
- unblock_input ();
unbind_to (specpdl_count, Qnil);
discard_menu_items ();
diff --git a/src/haikuterm.c b/src/haikuterm.c
index f0361c9dbe..1ff38b97bb 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -3615,7 +3615,7 @@ haiku_term_init (void)
Lisp_Object color_file, color_map;
block_input ();
- Fset_input_interrupt_mode (Qnil);
+ Fset_input_interrupt_mode (Qt);
baud_rate = 19200;