diff options
author | Povilas Kanapickas <povilas@radix.lt> | 2021-05-30 13:26:42 +0300 |
---|---|---|
committer | Povilas Kanapickas <povilas@radix.lt> | 2021-05-30 13:26:42 +0300 |
commit | 5163fc8bc28ce8bc2703cddcd9f2775ebc311766 (patch) | |
tree | a2d05dcb160f9f6955751e008863c818f7698cdb /dix/events.c | |
parent | d3c52df16105de5ac37e196a49b173e426caf417 (diff) |
Implement gesture processing logic
Diffstat (limited to 'dix/events.c')
-rw-r--r-- | dix/events.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/dix/events.c b/dix/events.c index e2455a4bb..d29868ef0 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1328,6 +1328,15 @@ ComputeFreezes(void) TouchListenerAcceptReject(replayDev, ti, 0, XIRejectTouch); } + else if (IsGestureEvent(event)) { + GestureInfoPtr gi = + GestureFindActiveByEventType(replayDev, event->any.type); + if (gi) { + GestureEmitGestureEndToOwner(replayDev, gi); + GestureEndGesture(gi); + } + ProcessGestureEvent(event, replayDev); + } else { WindowPtr w = XYToWindow(replayDev->spriteInfo->sprite, event->device_event.root_x, @@ -1510,6 +1519,46 @@ UpdateTouchesForGrab(DeviceIntPtr mouse) } /** + * Update gesture records when an explicit grab is activated. Any gestures owned + * by the grabbing client are updated so the listener state reflects the new + * grab. + */ +static void +UpdateGesturesForGrab(DeviceIntPtr mouse) +{ + if (!mouse->gesture || mouse->deviceGrab.fromPassiveGrab) + return; + + GestureInfoPtr gi = &mouse->gesture->gesture; + GestureListener *listener = &gi->listener; + GrabPtr grab = mouse->deviceGrab.grab; + + if (gi->active && CLIENT_BITS(listener->listener) == grab->resource) { + if (grab->grabtype == CORE || grab->grabtype == XI || + !xi2mask_isset(grab->xi2mask, mouse, GetXI2Type(gi->type))) { + + if (listener->type == GESTURE_LISTENER_REGULAR) { + /* if the listener already got any events relating to the gesture, we must send + a gesture end because the grab overrides the previous listener and won't + itself send any gesture events. + */ + GestureEmitGestureEndToOwner(mouse, gi); + } + listener->type = GESTURE_LISTENER_NONGESTURE_GRAB; + } else { + listener->type = GESTURE_LISTENER_GRAB; + } + + listener->listener = grab->resource; + listener->window = grab->window; + + if (listener->grab) + FreeGrab(listener->grab); + listener->grab = AllocGrab(grab); + } +} + +/** * Activate a pointer grab on the given device. A pointer grab will cause all * core pointer events of this device to be delivered to the grabbing client only. * No other device will send core events to the grab client while the grab is @@ -1559,6 +1608,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, grabinfo->implicitGrab = autoGrab & ImplicitGrabMask; PostNewCursor(mouse); UpdateTouchesForGrab(mouse); + UpdateGesturesForGrab(mouse); CheckGrabForSyncs(mouse, (Bool) grab->pointerMode, (Bool) grab->keyboardMode); if (oldgrab) @@ -1614,6 +1664,16 @@ DeactivatePointerGrab(DeviceIntPtr mouse) if (dev->deviceGrab.sync.other == grab) dev->deviceGrab.sync.other = NullGrab; } + + /* in case of explicit gesture grab, send end event to the grab client */ + if (!wasPassive && mouse->gesture) { + GestureInfoPtr gi = &mouse->gesture->gesture; + if (gi->active && GestureResourceIsOwner(gi, grab_resource)) { + GestureEmitGestureEndToOwner(mouse, gi); + GestureEndGesture(gi); + } + } + DoEnterLeaveEvents(mouse, mouse->id, grab->window, mouse->spriteInfo->sprite->win, NotifyUngrab); if (grab->confineTo) |