Deliver input events only to window owner
Peter Hutterer
peter.hutterer at who-t.net
Tue Dec 1 20:42:49 PST 2015
On Mon, Nov 23, 2015 at 04:20:05PM -0800, Keith Packard wrote:
>
> X allows multiple clients to select for keyboard, motion and button
> release events (button press events generate implicit grabs, and are
> only selectable by one client). This means that a client receiving an
> input event has no way of knowing if some other client has received the
> same event, allowing snooping of the keyboard input stream by selecting
> for keyboard input on the right windows in the system.
>
> Here's a patch which says that if the owner of the window receives a
> core input event, then don't go try and send it to other clients. Other
> clients can still ask for events, they will simply never receive
> them.
>
> This has no effect on key grabbing; a grabbed key will still be
> delivered to the grabbing client, even if that is not the owner of the
> window and if the owner has selected for non-grabbed key events.
>
> -keith
>
> From 8c84031b5f33fa4574c5c9db6b1257ff0e34c8a9 Mon Sep 17 00:00:00 2001
> From: Keith Packard <keithp at keithp.com>
> Date: Mon, 23 Nov 2015 16:04:54 -0800
> Subject: [PATCH xserver] Deliver input events exclusively to window owner
>
> When the window owner selects for core keyboard and mouse events,
> don't go looking for other clients to deliver those events to. This
> means that if the window owner receives a key or mouse event, then it
> can know that no other client could have also received the same event.
>
> This could be generalized to deliver input events to only one client,
> but which client would receive the event is less well defined as it
> would depend on the order that clients selected for input on
> particular windows.
>
> Signed-off-by: Keith Packard <keithp at keithp.com>
> ---
> dix/events.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/dix/events.c b/dix/events.c
> index 4114471..d223e97 100644
> --- a/dix/events.c
> +++ b/dix/events.c
> @@ -160,6 +160,12 @@ Equipment Corporation.
> #define PropagateMask ( \
> KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
> MotionMask )
> +
> +/* Deliver these events only to the owner if the owner selects them */
> +#define OwnerPriorityMask (\
> + KeyPressMask | KeyReleaseMask | \
> + ButtonPressMask | ButtonReleaseMask | PointerMotionMask)
> +
> #define PointerGrabMask ( \
> ButtonPressMask | ButtonReleaseMask | \
> EnterWindowMask | LeaveWindowMask | \
> @@ -2253,6 +2259,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
> Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
> this mask is the mask of the grab. */
> int type = pEvents->u.u.type;
> + Bool deliver_other_clients = TRUE;
>
> /* Deliver to window owner */
> if ((filter == CantBeFiltered) || core_get_type(pEvents) != 0) {
> @@ -2269,6 +2276,8 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
> case EVENT_DELIVERED:
> /* We delivered to the owner, with our event mask */
> deliveries++;
> + if (filter & OwnerPriorityMask)
> + deliver_other_clients = FALSE;
> client = wClient(pWin);
> deliveryMask = pWin->eventMask;
> break;
> @@ -2278,7 +2287,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
> }
>
> /* CantBeFiltered means only window owner gets the event */
> - if (filter != CantBeFiltered) {
> + if (filter != CantBeFiltered && deliver_other_clients) {
> enum EventDeliveryState rc;
>
> rc = DeliverEventToWindowMask(pDev, pWin, pEvents, count, filter,
> --
> 2.6.1
looks correct, and it would also be fairly trivial to add test cases for
this to XIT. I didn't check the spec for the exact wording, but either way
we should add it.
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
note that this does not handle XI2 raw keyboard events, they will need to be
handled as well.
Cheers,
Peter
More information about the xorg-devel
mailing list