[PATCH xserver] xwayland: Don't send KeyRelease events on wl_keyboard::leave
Rui Matos
tiagomatos at gmail.com
Thu Nov 24 18:56:18 UTC 2016
Commits 816015648ffe660ddaa0f7d4d192e555b723c372 and
fee0827a9a695600765f3d04376fc9babe497401 made it so that
wl_keyboard::enter doesn't result in X clients getting KeyPress events
while still updating our internal xkb state to be in sync with the
host compositor.
wl_keyboard::leave needs to be handled in the same way as its
semantics from an X client POV should be the same as an X grab getting
triggered, i.e. X clients shouldn't get KeyRelease events for keys
that are still down at that point.
This patch uses LeaveNotify for these events on wl_keyboard::leave and
changes the current use of KeymapNotify to EnterNotify instead just to
keep some symmetry between both cases.
On ProcessDeviceEvent() we still need to deactivate X grabs if needed
for KeyReleases.
Signed-off-by: Rui Matos <tiagomatos at gmail.com>
---
v2: Daniel Stone pointed out on IRC that I should leave the early exit
for press events, otherwise we could activate passive grabs (in
CheckDeviceGrabs) which is wrong in this case.
Xi/exevents.c | 22 +++++++++++++---------
dix/getevents.c | 5 ++++-
hw/xwayland/xwayland-input.c | 8 ++------
3 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/Xi/exevents.c b/Xi/exevents.c
index fc5298e..17d751e 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1798,15 +1798,19 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
break;
}
- if (grab)
- DeliverGrabbedEvent((InternalEvent *) event, device,
- deactivateDeviceGrab);
- else if (device->focus && !IsPointerEvent(ev))
- DeliverFocusedEvent(device, (InternalEvent *) event,
- GetSpriteWindow(device));
- else
- DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent *) event,
- NullGrab, NullWindow, device);
+ /* Don't deliver focus events (e.g. from KeymapNotify when running
+ * nested) to clients. */
+ if (event->source_type != EVENT_SOURCE_FOCUS) {
+ if (grab)
+ DeliverGrabbedEvent((InternalEvent *) event, device,
+ deactivateDeviceGrab);
+ else if (device->focus && !IsPointerEvent(ev))
+ DeliverFocusedEvent(device, (InternalEvent *) event,
+ GetSpriteWindow(device));
+ else
+ DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent *) event,
+ NullGrab, NullWindow, device);
+ }
if (deactivateDeviceGrab == TRUE) {
(*device->deviceGrab.DeactivateGrab) (device);
diff --git a/dix/getevents.c b/dix/getevents.c
index 4d06818..0d87453 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1101,9 +1101,12 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
}
#endif
- if (type == KeymapNotify) {
+ if (type == EnterNotify) {
source_type = EVENT_SOURCE_FOCUS;
type = KeyPress;
+ } else if (type == LeaveNotify) {
+ source_type = EVENT_SOURCE_FOCUS;
+ type = KeyRelease;
}
/* refuse events from disabled devices */
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index d6eadad..5671b50 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -655,7 +655,7 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
wl_array_copy(&xwl_seat->keys, keys);
wl_array_for_each(k, &xwl_seat->keys)
- QueueKeyboardEvents(xwl_seat->keyboard, KeymapNotify, *k + 8);
+ QueueKeyboardEvents(xwl_seat->keyboard, EnterNotify, *k + 8);
}
static void
@@ -667,12 +667,8 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
xwl_seat->xwl_screen->serial = serial;
- /* Unlike keymap_handle_enter above, this time we _do_ want to trigger
- * full release, as we don't know how long we'll be out of focus for.
- * Notify clients that the keys have been released, disable autorepeat,
- * etc. */
wl_array_for_each(k, &xwl_seat->keys)
- QueueKeyboardEvents(xwl_seat->keyboard, KeyRelease, *k + 8);
+ QueueKeyboardEvents(xwl_seat->keyboard, LeaveNotify, *k + 8);
xwl_seat->keyboard_focus = NULL;
}
--
2.9.3
More information about the xorg-devel
mailing list