[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master fe8d49e1ad 1/2: Make XInput 2 features work on GTK 2 builds
From: |
Po Lu |
Subject: |
master fe8d49e1ad 1/2: Make XInput 2 features work on GTK 2 builds |
Date: |
Wed, 9 Mar 2022 08:34:39 -0500 (EST) |
branch: master
commit fe8d49e1add8421afb16f5666bdbbabc7704f9c1
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
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.
---
src/xfns.c | 6 ++++--
src/xmenu.c | 17 +++++++++++++++++
src/xterm.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/src/xfns.c b/src/xfns.c
index cf5823c645..a3236efbcc 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -3579,7 +3579,7 @@ setup_xi_event_mask (struct frame *f)
mask.mask_len = l;
block_input ();
-#ifndef USE_GTK
+#ifndef HAVE_GTK3
mask.deviceid = XIAllMasterDevices;
XISetMask (m, XI_ButtonPress);
@@ -3587,8 +3587,10 @@ setup_xi_event_mask (struct frame *f)
XISetMask (m, XI_Motion);
XISetMask (m, XI_Enter);
XISetMask (m, XI_Leave);
+#ifndef USE_GTK
XISetMask (m, XI_FocusIn);
XISetMask (m, XI_FocusOut);
+#endif
XISetMask (m, XI_KeyPress);
XISetMask (m, XI_KeyRelease);
XISelectEvents (FRAME_X_DISPLAY (f),
@@ -3596,7 +3598,7 @@ setup_xi_event_mask (struct frame *f)
&mask, 1);
memset (m, 0, l);
-#endif /* !USE_GTK */
+#endif /* !HAVE_GTK3 */
#ifdef USE_X_TOOLKIT
XISetMask (m, XI_KeyPress);
diff --git a/src/xmenu.c b/src/xmenu.c
index 4d0e5bd81c..d19fe13c29 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,
if (i == 5) i = 0;
}
+#if !defined HAVE_GTK3 && defined HAVE_XINPUT2
+ if (FRAME_DISPLAY_INFO (f)->num_devices)
+ {
+ for (int i = 0; i < FRAME_DISPLAY_INFO (f)->num_devices; ++i)
+ {
+ if (FRAME_DISPLAY_INFO (f)->devices[i].grab)
+ {
+ FRAME_DISPLAY_INFO (f)->devices[i].grab = 0;
+
+ XIUngrabDevice (FRAME_X_DISPLAY (f),
+ FRAME_DISPLAY_INFO (f)->devices[i].device_id,
+ CurrentTime);
+ }
+ }
+ }
+#endif
+
/* Display the menu. */
gtk_widget_show_all (menu);
diff --git a/src/xterm.c b/src/xterm.c
index 772a9238a7..68f7588af4 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10021,6 +10021,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
being passed to XtDispatchEvent. */
bool use_copy = false;
XEvent copy;
+#elif defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
+ GdkEvent *copy = NULL;
+ GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
#endif
*finish = X_EVENT_NORMAL;
@@ -12186,6 +12189,20 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
x_display_set_last_user_time (dpyinfo, xev->time);
+#if defined USE_GTK && !defined HAVE_GTK3
+ /* Unlike on Motif, we can't select for XI
+ events on the scroll bar window under GTK+ 2.
+ So instead of that, just ignore XI wheel
+ events which land on a scroll bar.
+
+ Here we assume anything which isn't the edit
+ widget window is a scroll bar. */
+
+ if (xev->child != None
+ && xev->child != FRAME_X_WINDOW (f))
+ goto OTHER;
+#endif
+
if (fabs (total_x) > 0 || fabs (total_y) > 0)
{
inev.ie.kind = (fabs (total_y) >= fabs (total_x)
@@ -12390,6 +12407,37 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (XIMaskIsSet (xev->buttons.mask, 3))
copy.xbutton.state |= Button3Mask;
}
+#elif defined USE_GTK && !defined HAVE_GTK3
+ copy = gdk_event_new (xev->evtype == XI_ButtonPress
+ ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
+
+ copy->button.window = gdk_x11_window_lookup_for_display (gdpy,
xev->event);
+ copy->button.send_event = xev->send_event;
+ copy->button.time = xev->time;
+ copy->button.x = xev->event_x;
+ copy->button.y = xev->event_y;
+ copy->button.x_root = xev->root_x;
+ copy->button.y_root = xev->root_y;
+ copy->button.state = xev->mods.effective;
+ copy->button.button = xev->detail;
+
+ if (xev->buttons.mask_len)
+ {
+ if (XIMaskIsSet (xev->buttons.mask, 1))
+ copy->button.state |= GDK_BUTTON1_MASK;
+ if (XIMaskIsSet (xev->buttons.mask, 2))
+ copy->button.state |= GDK_BUTTON2_MASK;
+ if (XIMaskIsSet (xev->buttons.mask, 3))
+ copy->button.state |= GDK_BUTTON3_MASK;
+ }
+
+ if (!copy->button.window)
+ emacs_abort ();
+
+ g_object_ref (copy->button.window);
+
+ gtk_main_do_event (copy);
+ gdk_event_free (copy);
#endif
#ifdef HAVE_XINPUT2_1