emacs-diffs
[Top][All Lists]
Advanced

[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;
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]