Skip to content

Commit 380b9b3

Browse files
authored
[Wayland]: Add support for hold gesture (#735)
1 parent 3948b27 commit 380b9b3

20 files changed

+498
-7
lines changed

clutter/clutter/clutter-actor.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13994,6 +13994,7 @@ clutter_actor_event (ClutterActor *actor,
1399413994
break;
1399513995
case CLUTTER_TOUCHPAD_PINCH:
1399613996
case CLUTTER_TOUCHPAD_SWIPE:
13997+
case CLUTTER_TOUCHPAD_HOLD:
1399713998
detail = quark_touchpad;
1399813999
break;
1399914000
case CLUTTER_PROXIMITY_IN:

clutter/clutter/clutter-enums.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,11 @@ typedef enum /*< flags prefix=CLUTTER_EVENT >*/
896896
* determined by its phase field; event added in 1.24
897897
* @CLUTTER_TOUCHPAD_SWIPE: A swipe gesture event, the current state is
898898
* determined by its phase field; event added in 1.24
899+
* @CLUTTER_TOUCHPAD_HOLD: A hold gesture event, the current state is
900+
* determined by its phase field. A hold gesture starts when the user places a
901+
* finger on the touchpad and ends when all fingers are lifted. It is
902+
* cancelled when the finger(s) move past a certain threshold.
903+
* Event added in 6.5
899904
* @CLUTTER_PROXIMITY_IN: A tool entered in proximity to a tablet;
900905
* event added in 1.28
901906
* @CLUTTER_PROXIMITY_OUT: A tool left from the proximity area of a tablet;
@@ -928,6 +933,7 @@ typedef enum /*< prefix=CLUTTER >*/
928933
CLUTTER_TOUCH_CANCEL,
929934
CLUTTER_TOUCHPAD_PINCH,
930935
CLUTTER_TOUCHPAD_SWIPE,
936+
CLUTTER_TOUCHPAD_HOLD,
931937
CLUTTER_PROXIMITY_IN,
932938
CLUTTER_PROXIMITY_OUT,
933939
CLUTTER_PAD_BUTTON_PRESS,

clutter/clutter/clutter-event.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,11 @@ clutter_event_get_position (const ClutterEvent *event,
457457
graphene_point_init (position, event->touchpad_swipe.x,
458458
event->touchpad_swipe.y);
459459
break;
460+
461+
case CLUTTER_TOUCHPAD_HOLD:
462+
graphene_point_init (position, event->touchpad_hold.x,
463+
event->touchpad_hold.y);
464+
break;
460465
}
461466

462467
}
@@ -540,6 +545,11 @@ clutter_event_set_coords (ClutterEvent *event,
540545
event->touchpad_swipe.x = x;
541546
event->touchpad_swipe.y = y;
542547
break;
548+
549+
case CLUTTER_TOUCHPAD_HOLD:
550+
event->touchpad_hold.x = x;
551+
event->touchpad_hold.y = y;
552+
break;
543553
}
544554
}
545555

@@ -1154,6 +1164,7 @@ clutter_event_set_device (ClutterEvent *event,
11541164

11551165
case CLUTTER_TOUCHPAD_PINCH:
11561166
case CLUTTER_TOUCHPAD_SWIPE:
1167+
case CLUTTER_TOUCHPAD_HOLD:
11571168
/* Rely on priv data for these */
11581169
break;
11591170

@@ -1259,6 +1270,7 @@ clutter_event_get_device (const ClutterEvent *event)
12591270

12601271
case CLUTTER_TOUCHPAD_PINCH:
12611272
case CLUTTER_TOUCHPAD_SWIPE:
1273+
case CLUTTER_TOUCHPAD_HOLD:
12621274
/* Rely on priv data for these */
12631275
break;
12641276

@@ -1814,6 +1826,7 @@ clutter_event_get_axes (const ClutterEvent *event,
18141826

18151827
case CLUTTER_TOUCHPAD_PINCH:
18161828
case CLUTTER_TOUCHPAD_SWIPE:
1829+
case CLUTTER_TOUCHPAD_HOLD:
18171830
case CLUTTER_PAD_BUTTON_PRESS:
18181831
case CLUTTER_PAD_BUTTON_RELEASE:
18191832
case CLUTTER_PAD_STRIP:
@@ -2073,12 +2086,15 @@ clutter_event_get_touchpad_gesture_finger_count (const ClutterEvent *event)
20732086
{
20742087
g_return_val_if_fail (event != NULL, 0);
20752088
g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_SWIPE ||
2076-
event->type == CLUTTER_TOUCHPAD_PINCH, 0);
2089+
event->type == CLUTTER_TOUCHPAD_PINCH ||
2090+
event->type == CLUTTER_TOUCHPAD_HOLD, 0);
20772091

20782092
if (event->type == CLUTTER_TOUCHPAD_SWIPE)
20792093
return event->touchpad_swipe.n_fingers;
20802094
else if (event->type == CLUTTER_TOUCHPAD_PINCH)
20812095
return event->touchpad_pinch.n_fingers;
2096+
else if (event->type == CLUTTER_TOUCHPAD_HOLD)
2097+
return event->touchpad_hold.n_fingers;
20822098

20832099
return 0;
20842100
}
@@ -2137,12 +2153,15 @@ clutter_event_get_gesture_phase (const ClutterEvent *event)
21372153
{
21382154
g_return_val_if_fail (event != NULL, 0);
21392155
g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH ||
2140-
event->type == CLUTTER_TOUCHPAD_SWIPE, 0);
2156+
event->type == CLUTTER_TOUCHPAD_SWIPE ||
2157+
event->type == CLUTTER_TOUCHPAD_HOLD, 0);
21412158

21422159
if (event->type == CLUTTER_TOUCHPAD_PINCH)
21432160
return event->touchpad_pinch.phase;
21442161
else if (event->type == CLUTTER_TOUCHPAD_SWIPE)
21452162
return event->touchpad_swipe.phase;
2163+
else if (event->type == CLUTTER_TOUCHPAD_HOLD)
2164+
return event->touchpad_hold.phase;
21462165

21472166
/* Shouldn't ever happen */
21482167
return CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN;
@@ -2168,7 +2187,8 @@ clutter_event_get_gesture_motion_delta (const ClutterEvent *event,
21682187
{
21692188
g_return_if_fail (event != NULL);
21702189
g_return_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH ||
2171-
event->type == CLUTTER_TOUCHPAD_SWIPE);
2190+
event->type == CLUTTER_TOUCHPAD_SWIPE ||
2191+
event->type == CLUTTER_TOUCHPAD_HOLD);
21722192

21732193
if (event->type == CLUTTER_TOUCHPAD_PINCH)
21742194
{
@@ -2184,6 +2204,13 @@ clutter_event_get_gesture_motion_delta (const ClutterEvent *event,
21842204
if (dy)
21852205
*dy = event->touchpad_swipe.dy;
21862206
}
2207+
else if (event->type == CLUTTER_TOUCHPAD_HOLD)
2208+
{
2209+
if (dx)
2210+
*dx = 0;
2211+
if (dy)
2212+
*dy = 0;
2213+
}
21872214
}
21882215

21892216
/**

clutter/clutter/clutter-event.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ typedef struct _ClutterCrossingEvent ClutterCrossingEvent;
117117
typedef struct _ClutterTouchEvent ClutterTouchEvent;
118118
typedef struct _ClutterTouchpadPinchEvent ClutterTouchpadPinchEvent;
119119
typedef struct _ClutterTouchpadSwipeEvent ClutterTouchpadSwipeEvent;
120+
typedef struct _ClutterTouchpadHoldEvent ClutterTouchpadHoldEvent;
120121
typedef struct _ClutterProximityEvent ClutterProximityEvent;
121122
typedef struct _ClutterPadButtonEvent ClutterPadButtonEvent;
122123
typedef struct _ClutterPadStripEvent ClutterPadStripEvent;
@@ -500,6 +501,43 @@ struct _ClutterTouchpadSwipeEvent
500501
gfloat dy;
501502
};
502503

504+
/**
505+
* ClutterTouchpadHoldEvent
506+
* @type: event type
507+
* @time: event time
508+
* @flags: event flags
509+
* @stage: event source stage
510+
* @source: event source actor (unused)
511+
* @phase: the current phase of the gesture
512+
* @n_fingers: the number of fingers triggering the swipe
513+
* @x: the X coordinate of the pointer, relative to the stage
514+
* @y: the Y coordinate of the pointer, relative to the stage
515+
*
516+
* Used for touchpad hold gesture events. The current state of the
517+
* gesture will be determined by the @phase field.
518+
*
519+
* A hold gesture starts when the user places one or many fingers on the
520+
* touchpad and ends when all fingers are lifted. It is cancelled when the
521+
* finger(s) move past a certain threshold.
522+
* Unlike swipe and pinch, @phase can only be
523+
* CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN, CLUTTER_TOUCHPAD_GESTURE_PHASE_END and
524+
* CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL.
525+
*/
526+
struct _ClutterTouchpadHoldEvent
527+
{
528+
ClutterEventType type;
529+
guint32 time;
530+
ClutterEventFlags flags;
531+
ClutterStage *stage;
532+
ClutterActor *source;
533+
534+
ClutterTouchpadGesturePhase phase;
535+
uint32_t n_fingers;
536+
float x;
537+
float y;
538+
};
539+
540+
503541
struct _ClutterPadButtonEvent
504542
{
505543
ClutterEventType type;
@@ -592,6 +630,7 @@ union _ClutterEvent
592630
ClutterTouchEvent touch;
593631
ClutterTouchpadPinchEvent touchpad_pinch;
594632
ClutterTouchpadSwipeEvent touchpad_swipe;
633+
ClutterTouchpadHoldEvent touchpad_hold;
595634
ClutterProximityEvent proximity;
596635
ClutterPadButtonEvent pad_button;
597636
ClutterPadStripEvent pad_strip;

clutter/clutter/clutter-main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,6 +1892,7 @@ _clutter_process_event_details (ClutterActor *stage,
18921892
case CLUTTER_SCROLL:
18931893
case CLUTTER_TOUCHPAD_PINCH:
18941894
case CLUTTER_TOUCHPAD_SWIPE:
1895+
case CLUTTER_TOUCHPAD_HOLD:
18951896
{
18961897
ClutterActor *actor;
18971898
gfloat x, y;

meson.build

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ gudev_req = '>= 232'
3838

3939
# wayland version requirements
4040
wayland_server_req = '>= 1.20'
41-
wayland_protocols_req = '>= 1.19'
41+
wayland_protocols_req = '>= 1.23'
4242

4343
# native backend version requirements
44-
libinput_req = '>= 1.7'
44+
libinput_req = '>= 1.19.0'
4545
gbm_req = '>= 10.3'
4646

4747
# screen cast version requirements

src/backends/native/meta-seat-native.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,48 @@ notify_swipe_gesture_event (ClutterInputDevice *input_device,
10941094
queue_event (event);
10951095
}
10961096

1097+
static void
1098+
notify_hold_gesture_event (ClutterInputDevice *input_device,
1099+
ClutterTouchpadGesturePhase phase,
1100+
uint64_t time_us,
1101+
uint32_t n_fingers)
1102+
{
1103+
MetaInputDeviceNative *device_evdev;
1104+
MetaSeatNative *seat;
1105+
ClutterStage *stage;
1106+
ClutterEvent *event = NULL;
1107+
graphene_point_t pos;
1108+
1109+
/* We can drop the event on the floor if no stage has been
1110+
* associated with the device yet. */
1111+
stage = _clutter_input_device_get_stage (input_device);
1112+
if (stage == NULL)
1113+
return;
1114+
1115+
device_evdev = META_INPUT_DEVICE_NATIVE (input_device);
1116+
seat = meta_input_device_native_get_seat (device_evdev);
1117+
1118+
event = clutter_event_new (CLUTTER_TOUCHPAD_HOLD);
1119+
1120+
meta_event_native_set_time_usec (event, time_us);
1121+
event->touchpad_hold.phase = phase;
1122+
event->touchpad_hold.time = us2ms (time_us);
1123+
event->touchpad_hold.stage = CLUTTER_STAGE (stage);
1124+
1125+
clutter_input_device_get_coords (seat->core_pointer, NULL, &pos);
1126+
event->touchpad_hold.x = pos.x;
1127+
event->touchpad_hold.y = pos.y;
1128+
event->touchpad_hold.n_fingers = n_fingers;
1129+
1130+
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
1131+
1132+
clutter_event_set_device (event, seat->core_pointer);
1133+
clutter_event_set_source_device (event, input_device);
1134+
1135+
queue_event (event);
1136+
}
1137+
1138+
10971139
static void
10981140
notify_proximity (ClutterInputDevice *input_device,
10991141
uint64_t time_us,
@@ -2187,6 +2229,28 @@ process_device_event (MetaSeatNative *seat,
21872229
time_us, n_fingers, dx, dy);
21882230
break;
21892231
}
2232+
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
2233+
case LIBINPUT_EVENT_GESTURE_HOLD_END:
2234+
{
2235+
struct libinput_event_gesture *gesture_event =
2236+
libinput_event_get_gesture_event (event);
2237+
ClutterTouchpadGesturePhase phase;
2238+
uint32_t n_fingers;
2239+
uint64_t time_us;
2240+
2241+
device = libinput_device_get_user_data (libinput_device);
2242+
time_us = libinput_event_gesture_get_time_usec (gesture_event);
2243+
n_fingers = libinput_event_gesture_get_finger_count (gesture_event);
2244+
2245+
if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_HOLD_BEGIN)
2246+
phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN;
2247+
else
2248+
phase = libinput_event_gesture_get_cancelled (gesture_event) ?
2249+
CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END;
2250+
2251+
notify_hold_gesture_event (device, phase, time_us, n_fingers);
2252+
break;
2253+
}
21902254
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
21912255
{
21922256
process_tablet_axis (seat, event);

src/core/events.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
#define IS_GESTURE_EVENT(e) ((e)->type == CLUTTER_TOUCHPAD_SWIPE || \
4444
(e)->type == CLUTTER_TOUCHPAD_PINCH || \
45+
(e)->type == CLUTTER_TOUCHPAD_HOLD || \
4546
(e)->type == CLUTTER_TOUCH_BEGIN || \
4647
(e)->type == CLUTTER_TOUCH_UPDATE || \
4748
(e)->type == CLUTTER_TOUCH_END || \

src/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,8 @@ if have_wayland
530530
'wayland/meta-wayland-pointer.c',
531531
'wayland/meta-wayland-pointer-constraints.c',
532532
'wayland/meta-wayland-pointer-constraints.h',
533+
'wayland/meta-wayland-pointer-gesture-hold.c',
534+
'wayland/meta-wayland-pointer-gesture-hold.h',
533535
'wayland/meta-wayland-pointer-gesture-pinch.c',
534536
'wayland/meta-wayland-pointer-gesture-pinch.h',
535537
'wayland/meta-wayland-pointer-gestures.c',

0 commit comments

Comments
 (0)