[at-spi2-core/gnome-3-40: 3/3] AtspiDevice key grab fixes
- From: Mike Gorse <mgorse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [at-spi2-core/gnome-3-40: 3/3] AtspiDevice key grab fixes
- Date: Sat, 22 May 2021 15:33:45 +0000 (UTC)
commit daa000a8df1d3377916ed06401bd8b011cd465de
Author: Mike Gorse <mgorse suse com>
Date: Wed May 12 15:46:05 2021 -0500
AtspiDevice key grab fixes
atspi/atspi-device-legacy.c | 16 +++++++++++--
atspi/atspi-device-x11.c | 57 +++++++++++++++++++++++++++++++++++++++++----
atspi/atspi-device.c | 16 +++++++++++--
3 files changed, 81 insertions(+), 8 deletions(-)
---
diff --git a/atspi/atspi-device-legacy.c b/atspi/atspi-device-legacy.c
index 6c19b79..eb67768 100644
--- a/atspi/atspi-device-legacy.c
+++ b/atspi/atspi-device-legacy.c
@@ -47,6 +47,7 @@ struct _AtspiDeviceLegacyPrivate
GSList *modifiers;
guint virtual_mods_enabled;
gboolean keyboard_grabbed;
+ unsigned int numlock_physical_mask;
};
GObjectClass *device_legacy_parent_class;
@@ -91,13 +92,19 @@ key_cb (AtspiDeviceEvent *event, void *user_data)
AtspiDeviceLegacy *legacy_device = ATSPI_DEVICE_LEGACY (user_data);
AtspiDeviceLegacyPrivate *priv = atspi_device_legacy_get_instance_private (legacy_device);
gboolean ret = priv->keyboard_grabbed;
-
+ guint modifiers;
+
set_virtual_modifier (legacy_device, event->hw_code,
event->type == (AtspiEventType)ATSPI_KEY_PRESS);
+
+ modifiers = event->modifiers | priv->virtual_mods_enabled;
+ if (modifiers & (1 << ATSPI_MODIFIER_NUMLOCK))
+ modifiers &= ~priv->numlock_physical_mask;
+
ret |= atspi_device_notify_key (ATSPI_DEVICE (legacy_device),
event->type == (AtspiEventType)ATSPI_KEY_PRESS,
event->hw_code, event->id,
- event->modifiers | priv->virtual_mods_enabled,
+ modifiers,
event->event_string);
g_boxed_free (ATSPI_TYPE_DEVICE_EVENT, event);
@@ -126,6 +133,9 @@ check_virtual_modifier (AtspiDeviceLegacy *legacy_device, guint modifier)
AtspiDeviceLegacyPrivate *priv = atspi_device_legacy_get_instance_private (legacy_device);
GSList *l;
+ if (modifier == (1 << ATSPI_MODIFIER_NUMLOCK))
+ return TRUE;
+
for (l = priv->modifiers; l; l = l->next)
{
AtspiLegacyKeyModifier *entry = l->data;
@@ -269,6 +279,8 @@ atspi_device_legacy_init (AtspiDeviceLegacy *device)
priv->display=XOpenDisplay("");
if (priv->display)
priv->window = DefaultRootWindow(priv->display);
+ priv->numlock_physical_mask = XkbKeysymToModifiers (priv->display,
+ XK_Num_Lock);
#endif
}
diff --git a/atspi/atspi-device-x11.c b/atspi/atspi-device-x11.c
index e8f2199..4f88e60 100644
--- a/atspi/atspi-device-x11.c
+++ b/atspi/atspi-device-x11.c
@@ -44,6 +44,7 @@ struct _AtspiDeviceX11Private
GSList *key_grabs;
guint virtual_mods_enabled;
gboolean keyboard_grabbed;
+ unsigned int numlock_physical_mask;
};
GObjectClass *device_x11_parent_class;
@@ -176,7 +177,7 @@ grab_has_active_duplicate (AtspiDeviceX11 *x11_device, AtspiX11KeyGrab *grab)
}
static void
-grab_key (AtspiDeviceX11 *x11_device, int keycode, int modmask)
+grab_key_aux (AtspiDeviceX11 *x11_device, int keycode, int modmask)
{
AtspiDeviceX11Private *priv = atspi_device_x11_get_instance_private (x11_device);
XIGrabModifiers xi_modifiers;
@@ -196,6 +197,22 @@ grab_key (AtspiDeviceX11 *x11_device, int keycode, int modmask)
XIGrabKeycode (priv->display, XIAllMasterDevices, keycode, priv->window, XIGrabModeSync, XIGrabModeAsync,
False, &eventmask, 1, &xi_modifiers);
}
+static void
+grab_key (AtspiDeviceX11 *x11_device, int keycode, int modmask)
+{
+ AtspiDeviceX11Private *priv = atspi_device_x11_get_instance_private (x11_device);
+
+ grab_key_aux (x11_device, keycode, modmask);
+ if (!(modmask & LockMask))
+ grab_key_aux (x11_device, keycode, modmask | LockMask);
+ if (!(modmask & priv->numlock_physical_mask))
+ {
+ grab_key_aux (x11_device, keycode, modmask | priv->numlock_physical_mask);
+ if (!(modmask & LockMask))
+ grab_key_aux (x11_device, keycode, modmask | LockMask | priv->numlock_physical_mask);
+ }
+}
+
static void
enable_key_grab (AtspiDeviceX11 *x11_device, AtspiX11KeyGrab *grab)
{
@@ -209,7 +226,7 @@ enable_key_grab (AtspiDeviceX11 *x11_device, AtspiX11KeyGrab *grab)
}
static void
-ungrab_key (AtspiDeviceX11 *x11_device, int keycode, int modmask)
+ungrab_key_aux (AtspiDeviceX11 *x11_device, int keycode, int modmask)
{
AtspiDeviceX11Private *priv = atspi_device_x11_get_instance_private (x11_device);
XIGrabModifiers xi_modifiers;
@@ -220,6 +237,22 @@ ungrab_key (AtspiDeviceX11 *x11_device, int keycode, int modmask)
XIUngrabKeycode (priv->display, XIAllMasterDevices, keycode, priv->window, sizeof(xi_modifiers),
&xi_modifiers);
}
+static void
+ungrab_key (AtspiDeviceX11 *x11_device, int keycode, int modmask)
+{
+ AtspiDeviceX11Private *priv = atspi_device_x11_get_instance_private (x11_device);
+
+ ungrab_key_aux (x11_device, keycode, modmask);
+ if (!(modmask & LockMask))
+ ungrab_key_aux (x11_device, keycode, modmask | LockMask);
+ if (!(modmask & priv->numlock_physical_mask))
+ {
+ ungrab_key_aux (x11_device, keycode, modmask | priv->numlock_physical_mask);
+ if (!(modmask & LockMask))
+ ungrab_key_aux (x11_device, keycode, modmask | LockMask | priv->numlock_physical_mask);
+ }
+}
+
static void
disable_key_grab (AtspiDeviceX11 *x11_device, AtspiX11KeyGrab *grab)
{
@@ -290,6 +323,7 @@ do_event_dispatch (gpointer user_data)
char text[10];
KeySym keysym;
XComposeStatus status;
+ guint modifiers;
while (XPending (display))
{
@@ -301,7 +335,13 @@ do_event_dispatch (gpointer user_data)
case KeyPress:
case KeyRelease:
XLookupString(&xevent.xkey, text, sizeof (text), &keysym, &status);
- atspi_device_notify_key (ATSPI_DEVICE (device), (xevent.type == KeyPress), xevent.xkey.keycode,
keysym, xevent.xkey.state | priv->virtual_mods_enabled, text);
+ modifiers = xevent.xkey.state | priv->virtual_mods_enabled;
+ if (modifiers & priv->numlock_physical_mask)
+ {
+ modifiers |= (1 << ATSPI_MODIFIER_NUMLOCK);
+ modifiers &= ~priv->numlock_physical_mask;
+ }
+ atspi_device_notify_key (ATSPI_DEVICE (device), (xevent.type == KeyPress), xevent.xkey.keycode,
keysym, modifiers, text);
break;
case GenericEvent:
if (xevent.xcookie.extension == priv->xi_opcode)
@@ -326,8 +366,11 @@ do_event_dispatch (gpointer user_data)
if (!priv->device_id)
priv->device_id = xiDevEv->deviceid;
set_virtual_modifier (device, xiRawEv->detail, xevent.xcookie.evtype == XI_KeyPress);
+ modifiers = keyevent.xkey.state | priv->virtual_mods_enabled;
+ if (modifiers & priv->numlock_physical_mask)
+ modifiers |= (1 << ATSPI_MODIFIER_NUMLOCK);
if (xiDevEv->deviceid == priv->device_id)
- atspi_device_notify_key (ATSPI_DEVICE (device), (xevent.xcookie.evtype == XI_KeyPress),
xiRawEv->detail, keysym, keyevent.xkey.state, text);
+ atspi_device_notify_key (ATSPI_DEVICE (device), (xevent.xcookie.evtype == XI_KeyPress),
xiRawEv->detail, keysym, modifiers, text);
/* otherwise it's probably a duplicate event from a key grab */
XFreeEventData (priv->display, &xevent.xcookie);
break;
@@ -396,6 +439,9 @@ check_virtual_modifier (AtspiDeviceX11 *x11_device, guint modifier)
AtspiDeviceX11Private *priv = atspi_device_x11_get_instance_private (x11_device);
GSList *l;
+ if (modifier == (1 << ATSPI_MODIFIER_NUMLOCK))
+ return TRUE;
+
for (l = priv->modifiers; l; l = l->next)
{
AtspiX11KeyModifier *entry = l->data;
@@ -534,6 +580,9 @@ atspi_device_x11_init (AtspiDeviceX11 *device)
create_event_source (device);
}
}
+
+ priv->numlock_physical_mask = XkbKeysymToModifiers (priv->display,
+ XK_Num_Lock);
}
static void
diff --git a/atspi/atspi-device.c b/atspi/atspi-device.c
index 5f62dc3..e4a564c 100644
--- a/atspi/atspi-device.c
+++ b/atspi/atspi-device.c
@@ -107,6 +107,19 @@ atspi_device_new ()
return ATSPI_DEVICE (atspi_device_legacy_new ());
}
+static gboolean
+key_matches_modifiers (guint key_mods, guint grab_mods)
+{
+ /* The presence or lack thereof of locking modifiers should make no
+ difference when testing, but other modifiers should match. If the
+ keypress has modifiers that (a) the grab does not check for and (b) are
+ not lock modifiers, then we reject the match. Alt + left arrow should not
+ match a grab on left arrow, for instance, but whether numlock is on or
+ off would be irrelevant. */
+ key_mods &= ~((1 << ATSPI_MODIFIER_SHIFTLOCK) | (1 << ATSPI_MODIFIER_NUMLOCK));
+ return (key_mods == grab_mods);
+}
+
gboolean
atspi_device_notify_key (AtspiDevice *device, gboolean pressed, int keycode, int keysym, gint state, gchar
*text)
{
@@ -123,8 +136,7 @@ atspi_device_notify_key (AtspiDevice *device, gboolean pressed, int keycode, int
for (l = priv->keygrabs; l; l = l->next)
{
AtspiKeyGrab *grab = l->data;
- //if (keycode == grab->keycode && (grab->modifiers & state) == grab->modifiers)
- if (keycode == grab->keycode && grab->modifiers == state)
+ if (keycode == grab->keycode && key_matches_modifiers (state, grab->modifiers))
{
if (grab->callback)
grab->callback (device, pressed, keycode, keysym, state, text, grab->callback_data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]