]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix C-g inside toolkit file dialogs with XI2
authorPo Lu <luangruo@yahoo.com>
Tue, 1 Mar 2022 05:48:36 +0000 (13:48 +0800)
committerPo Lu <luangruo@yahoo.com>
Tue, 1 Mar 2022 05:49:49 +0000 (13:49 +0800)
* 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
src/xmenu.c

index 03adb5ab8d75291acf54e1cf5911f61148f09b36..65218b3fc0738fa779fb37865ad9da982b5681d1 100644 (file)
@@ -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.  */
index 4683e856c2e23d8f666dc7b2f20ce5f6be769b49..a8185d8346e6f01213cab5926da1c5efe2258d14 100644 (file)
@@ -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