diff options
| author | Po Lu | 2022-03-09 21:29:17 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-09 21:29:17 +0800 |
| commit | fe8d49e1add8421afb16f5666bdbbabc7704f9c1 (patch) | |
| tree | ce5fad64ced4709e851649984d506af067d8d449 /src | |
| parent | b883e8bc65d314273b63da873e1cdbbac23978e9 (diff) | |
| download | emacs-fe8d49e1add8421afb16f5666bdbbabc7704f9c1.tar.gz emacs-fe8d49e1add8421afb16f5666bdbbabc7704f9c1.zip | |
Make XInput 2 features work on GTK 2 builds
* src/xfns.c (setup_xi_event_mask): On GTK 2, select for
button, motion, entry/exit and key events.
* src/xmenu.c (create_and_show_popup_menu): Clear XI grab if
appropriate.
* src/xterm.c (handle_one_xevent): Pass some kinds of input
extension events to GTK manually on versions of GTK+ that don't
understand them.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfns.c | 6 | ||||
| -rw-r--r-- | src/xmenu.c | 17 | ||||
| -rw-r--r-- | src/xterm.c | 48 |
3 files changed, 69 insertions, 2 deletions
diff --git a/src/xfns.c b/src/xfns.c index cf5823c645b..a3236efbcc6 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -3579,7 +3579,7 @@ setup_xi_event_mask (struct frame *f) | |||
| 3579 | mask.mask_len = l; | 3579 | mask.mask_len = l; |
| 3580 | 3580 | ||
| 3581 | block_input (); | 3581 | block_input (); |
| 3582 | #ifndef USE_GTK | 3582 | #ifndef HAVE_GTK3 |
| 3583 | mask.deviceid = XIAllMasterDevices; | 3583 | mask.deviceid = XIAllMasterDevices; |
| 3584 | 3584 | ||
| 3585 | XISetMask (m, XI_ButtonPress); | 3585 | XISetMask (m, XI_ButtonPress); |
| @@ -3587,8 +3587,10 @@ setup_xi_event_mask (struct frame *f) | |||
| 3587 | XISetMask (m, XI_Motion); | 3587 | XISetMask (m, XI_Motion); |
| 3588 | XISetMask (m, XI_Enter); | 3588 | XISetMask (m, XI_Enter); |
| 3589 | XISetMask (m, XI_Leave); | 3589 | XISetMask (m, XI_Leave); |
| 3590 | #ifndef USE_GTK | ||
| 3590 | XISetMask (m, XI_FocusIn); | 3591 | XISetMask (m, XI_FocusIn); |
| 3591 | XISetMask (m, XI_FocusOut); | 3592 | XISetMask (m, XI_FocusOut); |
| 3593 | #endif | ||
| 3592 | XISetMask (m, XI_KeyPress); | 3594 | XISetMask (m, XI_KeyPress); |
| 3593 | XISetMask (m, XI_KeyRelease); | 3595 | XISetMask (m, XI_KeyRelease); |
| 3594 | XISelectEvents (FRAME_X_DISPLAY (f), | 3596 | XISelectEvents (FRAME_X_DISPLAY (f), |
| @@ -3596,7 +3598,7 @@ setup_xi_event_mask (struct frame *f) | |||
| 3596 | &mask, 1); | 3598 | &mask, 1); |
| 3597 | 3599 | ||
| 3598 | memset (m, 0, l); | 3600 | memset (m, 0, l); |
| 3599 | #endif /* !USE_GTK */ | 3601 | #endif /* !HAVE_GTK3 */ |
| 3600 | 3602 | ||
| 3601 | #ifdef USE_X_TOOLKIT | 3603 | #ifdef USE_X_TOOLKIT |
| 3602 | XISetMask (m, XI_KeyPress); | 3604 | XISetMask (m, XI_KeyPress); |
diff --git a/src/xmenu.c b/src/xmenu.c index 4d0e5bd81c2..d19fe13c295 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -1527,6 +1527,23 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, | |||
| 1527 | if (i == 5) i = 0; | 1527 | if (i == 5) i = 0; |
| 1528 | } | 1528 | } |
| 1529 | 1529 | ||
| 1530 | #if !defined HAVE_GTK3 && defined HAVE_XINPUT2 | ||
| 1531 | if (FRAME_DISPLAY_INFO (f)->num_devices) | ||
| 1532 | { | ||
| 1533 | for (int i = 0; i < FRAME_DISPLAY_INFO (f)->num_devices; ++i) | ||
| 1534 | { | ||
| 1535 | if (FRAME_DISPLAY_INFO (f)->devices[i].grab) | ||
| 1536 | { | ||
| 1537 | FRAME_DISPLAY_INFO (f)->devices[i].grab = 0; | ||
| 1538 | |||
| 1539 | XIUngrabDevice (FRAME_X_DISPLAY (f), | ||
| 1540 | FRAME_DISPLAY_INFO (f)->devices[i].device_id, | ||
| 1541 | CurrentTime); | ||
| 1542 | } | ||
| 1543 | } | ||
| 1544 | } | ||
| 1545 | #endif | ||
| 1546 | |||
| 1530 | /* Display the menu. */ | 1547 | /* Display the menu. */ |
| 1531 | gtk_widget_show_all (menu); | 1548 | gtk_widget_show_all (menu); |
| 1532 | 1549 | ||
diff --git a/src/xterm.c b/src/xterm.c index 772a9238a7e..68f7588af4a 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -10021,6 +10021,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 10021 | being passed to XtDispatchEvent. */ | 10021 | being passed to XtDispatchEvent. */ |
| 10022 | bool use_copy = false; | 10022 | bool use_copy = false; |
| 10023 | XEvent copy; | 10023 | XEvent copy; |
| 10024 | #elif defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2 | ||
| 10025 | GdkEvent *copy = NULL; | ||
| 10026 | GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display); | ||
| 10024 | #endif | 10027 | #endif |
| 10025 | 10028 | ||
| 10026 | *finish = X_EVENT_NORMAL; | 10029 | *finish = X_EVENT_NORMAL; |
| @@ -12186,6 +12189,20 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 12186 | { | 12189 | { |
| 12187 | x_display_set_last_user_time (dpyinfo, xev->time); | 12190 | x_display_set_last_user_time (dpyinfo, xev->time); |
| 12188 | 12191 | ||
| 12192 | #if defined USE_GTK && !defined HAVE_GTK3 | ||
| 12193 | /* Unlike on Motif, we can't select for XI | ||
| 12194 | events on the scroll bar window under GTK+ 2. | ||
| 12195 | So instead of that, just ignore XI wheel | ||
| 12196 | events which land on a scroll bar. | ||
| 12197 | |||
| 12198 | Here we assume anything which isn't the edit | ||
| 12199 | widget window is a scroll bar. */ | ||
| 12200 | |||
| 12201 | if (xev->child != None | ||
| 12202 | && xev->child != FRAME_X_WINDOW (f)) | ||
| 12203 | goto OTHER; | ||
| 12204 | #endif | ||
| 12205 | |||
| 12189 | if (fabs (total_x) > 0 || fabs (total_y) > 0) | 12206 | if (fabs (total_x) > 0 || fabs (total_y) > 0) |
| 12190 | { | 12207 | { |
| 12191 | inev.ie.kind = (fabs (total_y) >= fabs (total_x) | 12208 | inev.ie.kind = (fabs (total_y) >= fabs (total_x) |
| @@ -12390,6 +12407,37 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 12390 | if (XIMaskIsSet (xev->buttons.mask, 3)) | 12407 | if (XIMaskIsSet (xev->buttons.mask, 3)) |
| 12391 | copy.xbutton.state |= Button3Mask; | 12408 | copy.xbutton.state |= Button3Mask; |
| 12392 | } | 12409 | } |
| 12410 | #elif defined USE_GTK && !defined HAVE_GTK3 | ||
| 12411 | copy = gdk_event_new (xev->evtype == XI_ButtonPress | ||
| 12412 | ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE); | ||
| 12413 | |||
| 12414 | copy->button.window = gdk_x11_window_lookup_for_display (gdpy, xev->event); | ||
| 12415 | copy->button.send_event = xev->send_event; | ||
| 12416 | copy->button.time = xev->time; | ||
| 12417 | copy->button.x = xev->event_x; | ||
| 12418 | copy->button.y = xev->event_y; | ||
| 12419 | copy->button.x_root = xev->root_x; | ||
| 12420 | copy->button.y_root = xev->root_y; | ||
| 12421 | copy->button.state = xev->mods.effective; | ||
| 12422 | copy->button.button = xev->detail; | ||
| 12423 | |||
| 12424 | if (xev->buttons.mask_len) | ||
| 12425 | { | ||
| 12426 | if (XIMaskIsSet (xev->buttons.mask, 1)) | ||
| 12427 | copy->button.state |= GDK_BUTTON1_MASK; | ||
| 12428 | if (XIMaskIsSet (xev->buttons.mask, 2)) | ||
| 12429 | copy->button.state |= GDK_BUTTON2_MASK; | ||
| 12430 | if (XIMaskIsSet (xev->buttons.mask, 3)) | ||
| 12431 | copy->button.state |= GDK_BUTTON3_MASK; | ||
| 12432 | } | ||
| 12433 | |||
| 12434 | if (!copy->button.window) | ||
| 12435 | emacs_abort (); | ||
| 12436 | |||
| 12437 | g_object_ref (copy->button.window); | ||
| 12438 | |||
| 12439 | gtk_main_do_event (copy); | ||
| 12440 | gdk_event_free (copy); | ||
| 12393 | #endif | 12441 | #endif |
| 12394 | 12442 | ||
| 12395 | #ifdef HAVE_XINPUT2_1 | 12443 | #ifdef HAVE_XINPUT2_1 |