diff options
| author | Po Lu | 2022-03-01 13:48:36 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-01 13:49:49 +0800 |
| commit | 68740117211a104ffd59b570aa40d1b5cfcef93e (patch) | |
| tree | 9a0c0d2500a5ee8a3ca84ec1ce389025d5dea98b /src | |
| parent | dfb52654a2a636183d0c5fada0ff28ec2d03872f (diff) | |
| download | emacs-68740117211a104ffd59b570aa40d1b5cfcef93e.tar.gz emacs-68740117211a104ffd59b570aa40d1b5cfcef93e.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfns.c | 86 | ||||
| -rw-r--r-- | src/xmenu.c | 4 |
2 files changed, 77 insertions, 13 deletions
diff --git a/src/xfns.c b/src/xfns.c index 03adb5ab8d7..65218b3fc07 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, | |||
| 8381 | result = 0; | 8381 | result = 0; |
| 8382 | while (result == 0) | 8382 | while (result == 0) |
| 8383 | { | 8383 | { |
| 8384 | XEvent event; | 8384 | XEvent event, copy; |
| 8385 | #ifdef HAVE_XINPUT2 | ||
| 8386 | x_menu_wait_for_event (FRAME_X_DISPLAY (f)); | ||
| 8387 | #else | ||
| 8385 | x_menu_wait_for_event (0); | 8388 | x_menu_wait_for_event (0); |
| 8386 | XtAppNextEvent (Xt_app_con, &event); | 8389 | #endif |
| 8387 | if (event.type == KeyPress | ||
| 8388 | && FRAME_X_DISPLAY (f) == event.xkey.display) | ||
| 8389 | { | ||
| 8390 | KeySym keysym = XLookupKeysym (&event.xkey, 0); | ||
| 8391 | 8390 | ||
| 8392 | /* Pop down on C-g. */ | 8391 | if ( |
| 8393 | if (keysym == XK_g && (event.xkey.state & ControlMask) != 0) | 8392 | #ifndef HAVE_XINPUT2 |
| 8394 | XtUnmanageChild (dialog); | 8393 | XtAppPending (Xt_app_con) |
| 8395 | } | 8394 | #else |
| 8395 | XPending (FRAME_X_DISPLAY (f)) | ||
| 8396 | #endif | ||
| 8397 | ) | ||
| 8398 | { | ||
| 8399 | #ifndef HAVE_XINPUT2 | ||
| 8400 | XtAppNextEvent (Xt_app_con, &event); | ||
| 8401 | #else | ||
| 8402 | XNextEvent (FRAME_X_DISPLAY (f), &event); | ||
| 8403 | #endif | ||
| 8404 | |||
| 8405 | copy = event; | ||
| 8406 | if (event.type == KeyPress | ||
| 8407 | && FRAME_X_DISPLAY (f) == event.xkey.display) | ||
| 8408 | { | ||
| 8409 | KeySym keysym = XLookupKeysym (&event.xkey, 0); | ||
| 8396 | 8410 | ||
| 8397 | (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f)); | 8411 | /* Pop down on C-g. */ |
| 8412 | if (keysym == XK_g && (event.xkey.state & ControlMask) != 0) | ||
| 8413 | XtUnmanageChild (dialog); | ||
| 8414 | } | ||
| 8415 | #ifdef HAVE_XINPUT2 | ||
| 8416 | else if (event.type == GenericEvent | ||
| 8417 | && FRAME_X_DISPLAY (f) == event.xgeneric.display | ||
| 8418 | && FRAME_DISPLAY_INFO (f)->supports_xi2 | ||
| 8419 | && (event.xgeneric.extension | ||
| 8420 | == FRAME_DISPLAY_INFO (f)->xi2_opcode) | ||
| 8421 | && event.xgeneric.evtype == XI_KeyPress) | ||
| 8422 | { | ||
| 8423 | KeySym keysym; | ||
| 8424 | XIDeviceEvent *xev; | ||
| 8425 | |||
| 8426 | if (event.xcookie.data) | ||
| 8427 | emacs_abort (); | ||
| 8428 | |||
| 8429 | if (XGetEventData (FRAME_X_DISPLAY (f), &event.xcookie)) | ||
| 8430 | { | ||
| 8431 | xev = (XIDeviceEvent *) event.xcookie.data; | ||
| 8432 | |||
| 8433 | copy.xkey.type = KeyPress; | ||
| 8434 | copy.xkey.serial = xev->serial; | ||
| 8435 | copy.xkey.send_event = xev->send_event; | ||
| 8436 | copy.xkey.display = FRAME_X_DISPLAY (f); | ||
| 8437 | copy.xkey.window = xev->event; | ||
| 8438 | copy.xkey.root = xev->root; | ||
| 8439 | copy.xkey.subwindow = xev->child; | ||
| 8440 | copy.xkey.time = xev->time; | ||
| 8441 | copy.xkey.x = lrint (xev->event_x); | ||
| 8442 | copy.xkey.y = lrint (xev->event_y); | ||
| 8443 | copy.xkey.x_root = lrint (xev->root_x); | ||
| 8444 | copy.xkey.y_root = lrint (xev->root_y); | ||
| 8445 | copy.xkey.state = xev->mods.effective; | ||
| 8446 | copy.xkey.keycode = xev->detail; | ||
| 8447 | copy.xkey.same_screen = True; | ||
| 8448 | |||
| 8449 | keysym = XLookupKeysym (©.xkey, 0); | ||
| 8450 | |||
| 8451 | if (keysym == XK_g | ||
| 8452 | && (copy.xkey.state & ControlMask) != 0) /* Any escape, ignore modifiers. */ | ||
| 8453 | XtUnmanageChild (dialog); | ||
| 8454 | |||
| 8455 | XFreeEventData (FRAME_X_DISPLAY (f), &event.xcookie); | ||
| 8456 | } | ||
| 8457 | } | ||
| 8458 | #endif | ||
| 8459 | |||
| 8460 | (void) x_dispatch_event (©, FRAME_X_DISPLAY (f)); | ||
| 8461 | } | ||
| 8398 | } | 8462 | } |
| 8399 | 8463 | ||
| 8400 | /* Get the result. */ | 8464 | /* Get the result. */ |
diff --git a/src/xmenu.c b/src/xmenu.c index 4683e856c2e..a8185d8346e 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -184,8 +184,8 @@ x_menu_wait_for_event (void *data) | |||
| 184 | instead of the small ifdefs below. */ | 184 | instead of the small ifdefs below. */ |
| 185 | 185 | ||
| 186 | while ( | 186 | while ( |
| 187 | #ifdef USE_X_TOOLKIT | 187 | #if defined USE_X_TOOLKIT |
| 188 | ! XtAppPending (Xt_app_con) | 188 | ! (data ? XPending (data) : XtAppPending (Xt_app_con)) |
| 189 | #elif defined USE_GTK | 189 | #elif defined USE_GTK |
| 190 | ! gtk_events_pending () | 190 | ! gtk_events_pending () |
| 191 | #else | 191 | #else |