emacs-diffs
[Top][All Lists]
Advanced

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

master 6874011721: Fix C-g inside toolkit file dialogs with XI2


From: Po Lu
Subject: master 6874011721: Fix C-g inside toolkit file dialogs with XI2
Date: Tue, 1 Mar 2022 00:49:58 -0500 (EST)

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

    Fix C-g inside toolkit file dialogs with XI2
    
    * src/xfns.c (Fx_file_dialog): Handle GenericEvents when looking
    for quit character.
    * src/xmenu.c (x_menu_wait_for_event): If data is non-nil, use
    XPending.
---
 src/xfns.c  | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 src/xmenu.c |  4 +--
 2 files changed, 77 insertions(+), 13 deletions(-)

diff --git a/src/xfns.c b/src/xfns.c
index 03adb5ab8d..65218b3fc0 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -8381,20 +8381,84 @@ DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 
2, 5, 0,
   result = 0;
   while (result == 0)
     {
-      XEvent event;
+      XEvent event, copy;
+#ifdef HAVE_XINPUT2
+      x_menu_wait_for_event (FRAME_X_DISPLAY (f));
+#else
       x_menu_wait_for_event (0);
-      XtAppNextEvent (Xt_app_con, &event);
-      if (event.type == KeyPress
-          && FRAME_X_DISPLAY (f) == event.xkey.display)
-        {
-          KeySym keysym = XLookupKeysym (&event.xkey, 0);
+#endif
 
-          /* Pop down on C-g.  */
-          if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
-            XtUnmanageChild (dialog);
-        }
+      if (
+#ifndef HAVE_XINPUT2
+         XtAppPending (Xt_app_con)
+#else
+         XPending (FRAME_X_DISPLAY (f))
+#endif
+         )
+       {
+#ifndef HAVE_XINPUT2
+         XtAppNextEvent (Xt_app_con, &event);
+#else
+         XNextEvent (FRAME_X_DISPLAY (f), &event);
+#endif
+
+         copy = event;
+         if (event.type == KeyPress
+             && FRAME_X_DISPLAY (f) == event.xkey.display)
+           {
+             KeySym keysym = XLookupKeysym (&event.xkey, 0);
 
-      (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
+             /* Pop down on C-g.  */
+             if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
+               XtUnmanageChild (dialog);
+           }
+#ifdef HAVE_XINPUT2
+         else if (event.type == GenericEvent
+                  && FRAME_X_DISPLAY (f) == event.xgeneric.display
+                  && FRAME_DISPLAY_INFO (f)->supports_xi2
+                  && (event.xgeneric.extension
+                      == FRAME_DISPLAY_INFO (f)->xi2_opcode)
+                  && event.xgeneric.evtype == XI_KeyPress)
+           {
+             KeySym keysym;
+             XIDeviceEvent *xev;
+
+             if (event.xcookie.data)
+               emacs_abort ();
+
+             if (XGetEventData (FRAME_X_DISPLAY (f), &event.xcookie))
+               {
+                 xev = (XIDeviceEvent *) event.xcookie.data;
+
+                 copy.xkey.type = KeyPress;
+                 copy.xkey.serial = xev->serial;
+                 copy.xkey.send_event = xev->send_event;
+                 copy.xkey.display = FRAME_X_DISPLAY (f);
+                 copy.xkey.window = xev->event;
+                 copy.xkey.root = xev->root;
+                 copy.xkey.subwindow = xev->child;
+                 copy.xkey.time = xev->time;
+                 copy.xkey.x = lrint (xev->event_x);
+                 copy.xkey.y = lrint (xev->event_y);
+                 copy.xkey.x_root = lrint (xev->root_x);
+                 copy.xkey.y_root = lrint (xev->root_y);
+                 copy.xkey.state = xev->mods.effective;
+                 copy.xkey.keycode = xev->detail;
+                 copy.xkey.same_screen = True;
+
+                 keysym = XLookupKeysym (&copy.xkey, 0);
+
+                 if (keysym == XK_g
+                     && (copy.xkey.state & ControlMask) != 0) /* Any escape, 
ignore modifiers.  */
+                   XtUnmanageChild (dialog);
+
+                 XFreeEventData (FRAME_X_DISPLAY (f), &event.xcookie);
+               }
+           }
+#endif
+
+         (void) x_dispatch_event (&copy, FRAME_X_DISPLAY (f));
+       }
     }
 
   /* Get the result.  */
diff --git a/src/xmenu.c b/src/xmenu.c
index 4683e856c2..a8185d8346 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -184,8 +184,8 @@ x_menu_wait_for_event (void *data)
      instead of the small ifdefs below.  */
 
   while (
-#ifdef USE_X_TOOLKIT
-         ! XtAppPending (Xt_app_con)
+#if defined USE_X_TOOLKIT
+         ! (data ? XPending (data) : XtAppPending (Xt_app_con))
 #elif defined USE_GTK
          ! gtk_events_pending ()
 #else



reply via email to

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