emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master ba0264e191: Fix processing events from multiple displays during D


From: Po Lu
Subject: master ba0264e191: Fix processing events from multiple displays during DND
Date: Sat, 30 Apr 2022 21:37:43 -0400 (EDT)

branch: master
commit ba0264e19153281bcf264e99c01c130c701151e2
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Fix processing events from multiple displays during DND
    
    * src/xterm.c (x_next_event_from_any_display): New function.
    Only used on no-toolkit builds.
    (x_dnd_begin_drag_and_drop): Compute correct dpyinfo for
    handle_one_xevent.
---
 src/xterm.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 62 insertions(+), 15 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index 4baaaf9ee8..633724b0ff 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9703,6 +9703,45 @@ x_top_window_to_frame (struct x_display_info *dpyinfo, 
int wdesc)
   return x_window_to_frame (dpyinfo, wdesc);
 }
 
+static void
+x_next_event_from_any_display (XEvent *event)
+{
+  struct x_display_info *dpyinfo;
+  fd_set fds;
+  int fd, maxfd;
+
+  while (true)
+    {
+      FD_ZERO (&fds);
+      maxfd = -1;
+
+      for (dpyinfo = x_display_list; dpyinfo;
+          dpyinfo = dpyinfo->next)
+       {
+         if (XPending (dpyinfo->display))
+           {
+             XNextEvent (dpyinfo->display, event);
+             return;
+           }
+
+         fd = XConnectionNumber (dpyinfo->display);
+
+         if (fd > maxfd)
+           maxfd = fd;
+
+         eassert (fd < FD_SETSIZE);
+         FD_SET (XConnectionNumber (dpyinfo->display), &fds);
+       }
+
+      eassert (maxfd >= 0);
+
+      /* We don't have to check the return of pselect, because if an
+        error occurs XPending will call the IO error handler, which
+        then brings us out of this loop.  */
+      pselect (maxfd, &fds, NULL, NULL, NULL, NULL);
+    }
+}
+
 #endif /* USE_X_TOOLKIT || USE_GTK */
 
 static void
@@ -9739,6 +9778,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, 
Atom xaction,
 #ifdef HAVE_XKB
   XkbStateRec keyboard_state;
 #endif
+  struct x_display_info *event_display;
 
   if (!FRAME_VISIBLE_P (f))
     {
@@ -9920,31 +9960,38 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, 
Atom xaction,
 #ifdef USE_X_TOOLKIT
       XtAppNextEvent (Xt_app_con, &next_event);
 #else
-      XNextEvent (FRAME_X_DISPLAY (f), &next_event);
+      x_next_event_from_any_display (&next_event);
 #endif
 
+      event_display
+       = x_display_info_for_display (next_event.xany.display);
+
+      if (event_display)
+       {
 #ifdef HAVE_X_I18N
 #ifdef HAVE_XINPUT2
-      if (next_event.type != GenericEvent
-         || !FRAME_DISPLAY_INFO (f)->supports_xi2
-         || (next_event.xgeneric.extension
-             != FRAME_DISPLAY_INFO (f)->xi2_opcode))
-       {
+         if (next_event.type != GenericEvent
+             || !event_display->supports_xi2
+             || (next_event.xgeneric.extension
+                 != event_display->xi2_opcode))
+           {
 #endif
-         if (!x_filter_event (FRAME_DISPLAY_INFO (f), &next_event))
-           handle_one_xevent (FRAME_DISPLAY_INFO (f),
-                              &next_event, &finish, &hold_quit);
+             if (!x_filter_event (event_display, &next_event))
+               handle_one_xevent (event_display,
+                                  &next_event, &finish, &hold_quit);
 #ifdef HAVE_XINPUT2
-       }
-      else
-       handle_one_xevent (FRAME_DISPLAY_INFO (f),
-                          &next_event, &finish, &hold_quit);
+           }
+         else
+           handle_one_xevent (event_display,
+                              &next_event, &finish, &hold_quit);
 #endif
 #else
-      handle_one_xevent (FRAME_DISPLAY_INFO (f),
-                        &next_event, &finish, &hold_quit);
+         handle_one_xevent (event_display,
+                            &next_event, &finish, &hold_quit);
 #endif
 #endif
+       }
+
       /* The unblock_input below might try to read input, but
         XTread_socket does nothing inside a drag-and-drop event
         loop, so don't let it clear the pending_signals flag.  */



reply via email to

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