libinput: add hold gesture public API and tool support

Add hold gestures to the public API and the private functions to notify them.
Also add hold gestures to debug-events and debug-gui.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
This commit is contained in:
José Expósito 2021-05-27 19:19:38 +02:00 committed by Peter Hutterer
parent 781cee2d8b
commit b6b15fa304
6 changed files with 131 additions and 9 deletions

View file

@ -627,6 +627,17 @@ gesture_notify_pinch_end(struct libinput_device *device,
double scale,
bool cancelled);
void
gesture_notify_hold(struct libinput_device *device,
uint64_t time,
int finger_count);
void
gesture_notify_hold_end(struct libinput_device *device,
uint64_t time,
int finger_count,
bool cancelled);
void
tablet_notify_axis(struct libinput_device *device,
uint64_t time,

View file

@ -106,6 +106,8 @@ event_type_to_str(enum libinput_event_type type)
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_BEGIN);
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_UPDATE);
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_END);
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_HOLD_BEGIN);
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_HOLD_END);
CASE_RETURN_STRING(LIBINPUT_EVENT_SWITCH_TOGGLE);
case LIBINPUT_EVENT_NONE:
abort();
@ -405,7 +407,9 @@ libinput_event_get_gesture_event(struct libinput_event *event)
LIBINPUT_EVENT_GESTURE_SWIPE_END,
LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
LIBINPUT_EVENT_GESTURE_PINCH_END);
LIBINPUT_EVENT_GESTURE_PINCH_END,
LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
LIBINPUT_EVENT_GESTURE_HOLD_END);
return (struct libinput_event_gesture *) event;
}
@ -892,7 +896,9 @@ libinput_event_gesture_get_time(struct libinput_event_gesture *event)
LIBINPUT_EVENT_GESTURE_PINCH_END,
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
LIBINPUT_EVENT_GESTURE_SWIPE_END);
LIBINPUT_EVENT_GESTURE_SWIPE_END,
LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
LIBINPUT_EVENT_GESTURE_HOLD_END);
return us2ms(event->time);
}
@ -908,7 +914,9 @@ libinput_event_gesture_get_time_usec(struct libinput_event_gesture *event)
LIBINPUT_EVENT_GESTURE_PINCH_END,
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
LIBINPUT_EVENT_GESTURE_SWIPE_END);
LIBINPUT_EVENT_GESTURE_SWIPE_END,
LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
LIBINPUT_EVENT_GESTURE_HOLD_END);
return event->time;
}
@ -924,7 +932,9 @@ libinput_event_gesture_get_finger_count(struct libinput_event_gesture *event)
LIBINPUT_EVENT_GESTURE_PINCH_END,
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
LIBINPUT_EVENT_GESTURE_SWIPE_END);
LIBINPUT_EVENT_GESTURE_SWIPE_END,
LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
LIBINPUT_EVENT_GESTURE_HOLD_END);
return event->finger_count;
}
@ -936,7 +946,8 @@ libinput_event_gesture_get_cancelled(struct libinput_event_gesture *event)
event->base.type,
0,
LIBINPUT_EVENT_GESTURE_PINCH_END,
LIBINPUT_EVENT_GESTURE_SWIPE_END);
LIBINPUT_EVENT_GESTURE_SWIPE_END,
LIBINPUT_EVENT_GESTURE_HOLD_END);
return event->cancelled;
}
@ -2890,6 +2901,29 @@ gesture_notify_pinch_end(struct libinput_device *device,
finger_count, cancelled, &zero, &zero, scale, 0.0);
}
void
gesture_notify_hold(struct libinput_device *device,
uint64_t time,
int finger_count)
{
const struct normalized_coords zero = { 0.0, 0.0 };
gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
finger_count, 0, &zero, &zero, 0.0, 0.0);
}
void
gesture_notify_hold_end(struct libinput_device *device,
uint64_t time,
int finger_count,
bool cancelled)
{
const struct normalized_coords zero = { 0.0, 0.0 };
gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_HOLD_END,
finger_count, cancelled, &zero, &zero, 0, 0.0);
}
void
switch_notify_toggle(struct libinput_device *device,
uint64_t time,

View file

@ -896,6 +896,11 @@ enum libinput_event_type {
LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
LIBINPUT_EVENT_GESTURE_PINCH_END,
/**
* @since 1.19
*/
LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
LIBINPUT_EVENT_GESTURE_HOLD_END,
/**
* @since 1.7

View file

@ -3130,6 +3130,12 @@ litest_event_type_str(enum libinput_event_type type)
case LIBINPUT_EVENT_GESTURE_PINCH_END:
str = "GESTURE PINCH END";
break;
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
str = "GESTURE HOLD BEGIN";
break;
case LIBINPUT_EVENT_GESTURE_HOLD_END:
str = "GESTURE HOLD END";
break;
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
str = "TABLET TOOL AXIS";
break;

View file

@ -119,6 +119,12 @@ print_event_header(struct libinput_event *ev)
case LIBINPUT_EVENT_GESTURE_PINCH_END:
type = "GESTURE_PINCH_END";
break;
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
type = "GESTURE_HOLD_BEGIN";
break;
case LIBINPUT_EVENT_GESTURE_HOLD_END:
type = "GESTURE_HOLD_END";
break;
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
type = "TABLET_TOOL_AXIS";
break;
@ -657,7 +663,8 @@ print_gesture_event_without_coords(struct libinput_event *ev)
type = libinput_event_get_type(ev);
if (type == LIBINPUT_EVENT_GESTURE_SWIPE_END ||
type == LIBINPUT_EVENT_GESTURE_PINCH_END)
type == LIBINPUT_EVENT_GESTURE_PINCH_END ||
type == LIBINPUT_EVENT_GESTURE_HOLD_END)
cancelled = libinput_event_gesture_get_cancelled(t);
print_event_time(libinput_event_gesture_get_time(t));
@ -879,6 +886,12 @@ handle_and_print_events(struct libinput *li)
case LIBINPUT_EVENT_GESTURE_PINCH_END:
print_gesture_event_without_coords(ev);
break;
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
print_gesture_event_without_coords(ev);
break;
case LIBINPUT_EVENT_GESTURE_HOLD_END:
print_gesture_event_without_coords(ev);
break;
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
print_tablet_axis_event(ev);
break;

View file

@ -130,6 +130,11 @@ struct window {
double x, y;
} pinch;
struct {
int nfingers;
bool active;
} hold;
struct {
double x, y;
double x_in, y_in;
@ -311,19 +316,18 @@ draw_outline:
static inline void
draw_gestures(struct window *w, cairo_t *cr)
{
int i;
int offset;
/* swipe */
cairo_save(cr);
cairo_translate(cr, w->swipe.x, w->swipe.y);
for (i = 0; i < w->swipe.nfingers; i++) {
for (int i = 0; i < w->swipe.nfingers; i++) {
cairo_set_source_rgb(cr, .8, .8, .4);
cairo_arc(cr, (i - 2) * 40, 0, 20, 0, 2 * M_PI);
cairo_fill(cr);
}
for (i = 0; i < 4; i++) { /* 4 fg max */
for (int i = 0; i < 4; i++) { /* 4 fg max */
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_arc(cr, (i - 2) * 40, 0, 20, 0, 2 * M_PI);
cairo_stroke(cr);
@ -349,6 +353,29 @@ draw_gestures(struct window *w, cairo_t *cr)
cairo_stroke(cr);
cairo_restore(cr);
/* hold */
cairo_save(cr);
cairo_translate(cr, w->width/2, w->height/2 + 100);
for (int i = 4; i > 0; i--) { /* 4 fg max */
double r, g, b, hold_alpha;
r = .4 + .2 * (i % 2);
g = .2;
b = .2;
hold_alpha = (w->hold.active && i <= w->hold.nfingers) ? 1 : .5;
cairo_set_source_rgba(cr, r, g, b, hold_alpha);
cairo_arc(cr, 0, 0, 20 * i, 0, 2 * M_PI);
cairo_fill(cr);
cairo_set_source_rgba(cr, 0, 0, 0, hold_alpha);
cairo_arc(cr, 0, 0, 20 * i, 0, 2 * M_PI);
cairo_stroke(cr);
}
cairo_restore(cr);
}
static inline void
@ -1311,6 +1338,28 @@ handle_event_pinch(struct libinput_event *ev, struct window *w)
}
}
static void
handle_event_hold(struct libinput_event *ev, struct window *w)
{
struct libinput_event_gesture *g = libinput_event_get_gesture_event(ev);
int nfingers;
nfingers = libinput_event_gesture_get_finger_count(g);
switch (libinput_event_get_type(ev)) {
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
w->hold.nfingers = nfingers;
w->hold.active = true;
break;
case LIBINPUT_EVENT_GESTURE_HOLD_END:
w->hold.nfingers = nfingers;
w->hold.active = false;
break;
default:
abort();
}
}
static void
handle_event_tablet(struct libinput_event *ev, struct window *w)
{
@ -1485,6 +1534,10 @@ handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data)
case LIBINPUT_EVENT_GESTURE_PINCH_END:
handle_event_pinch(ev, w);
break;
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
case LIBINPUT_EVENT_GESTURE_HOLD_END:
handle_event_hold(ev, w);
break;
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
case LIBINPUT_EVENT_TABLET_TOOL_TIP: