~mil/sxmo-devel

lisgd: Add double-tap gesture v1 PROPOSED

dropkick: 1
 Add double-tap gesture

 2 files changed, 34 insertions(+), 10 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~mil/sxmo-devel/patches/23928/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH lisgd] Add double-tap gesture Export this patch

---
 lisgd.1 |  2 +-
 lisgd.c | 42 +++++++++++++++++++++++++++++++++---------
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/lisgd.1 b/lisgd.1
index a1a6b7d..d940f5d 100644
--- a/lisgd.1
+++ b/lisgd.1
@@ -44,7 +44,7 @@ Path of the dev filesystem device to monitor (like /dev/input/event1).
.TP
.BR \-g ", " \-g\ nfingers,gesture,edge,distance,actmode,command\fR
Allows you to bind a gesture wherein nfingers is an integer, gesture is
one of {LR,RL,DU,UD,DLUR,URDL,ULDR,DLUR}, edge is one of * (any), N (none), L
one of {LR,RL,DU,UD,DLUR,URDL,ULDR,DLUR,DT}, edge is one of * (any), N (none), L
(left), R (right), T (top), B (bottom), TL (top left), TR (top right), BL
(bottom left), BR (bottom right) and distance is one of * (any), S (short), M
(medium), L (large), actmode is R (release) for normal mode and P (pressed) for
diff --git a/lisgd.c b/lisgd.c
index 124f298..2f1be38 100644
--- a/lisgd.c
+++ b/lisgd.c
@@ -25,7 +25,9 @@ enum {
  SwipeDLUR,
  SwipeDRUL,
  SwipeURDL,
  SwipeULDR
  SwipeULDR,
  TapSingle,
  TapDouble
};
typedef int Swipe;

@@ -79,6 +81,7 @@ Distance pendingdistance;
double xstart[MAXSLOTS], xend[MAXSLOTS], ystart[MAXSLOTS], yend[MAXSLOTS];
unsigned nfdown = 0, nfpendingswipe = 0;
struct timespec timedown;
struct timespec timedelta;
static Display *dpy;
static int screen;
static int screenwidth, screenheight;
@@ -129,6 +132,22 @@ gesturecalculateswipe(double x0, double y0, double x1, double y1, int mindistanc
	return -1;
}

Swipe
gesturecalculatetap(struct timespec now, int elapsedms) {
	if (elapsedms < 150) {
		if (
			pendingswipe == TapSingle &&
			timeoutms > ((now.tv_sec - timedelta.tv_sec) * 1000000 + (now.tv_nsec - timedelta.tv_nsec) / 1000) / 1000
		) {
			return TapDouble;
		} else {
			clock_gettime(CLOCK_MONOTONIC_RAW, &timedelta);
			return TapSingle;
		}
	}
	return -1;
}

Distance
gesturecalculatedistance(double x0, double y0, double x1, double y1, Swipe swipe) {
	double dist = sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2));
@@ -356,21 +375,28 @@ touchup(struct libinput_event *e)
	int slot;
	struct libinput_event_touch *tevent;
	struct timespec now;
	int elapsedms;

	tevent = libinput_event_get_touch_event(e);
	slot = libinput_event_touch_get_slot(tevent);
	nfdown--;
	clock_gettime(CLOCK_MONOTONIC_RAW, &now);
	elapsedms = ((now.tv_sec - timedown.tv_sec) * 1000000 + (now.tv_nsec - timedown.tv_nsec) / 1000) / 1000;

	// E.g. invalid motion, it didn't begin/end from anywhere
	Swipe swipe;
	if (
		xstart[slot] == NOMOTION || ystart[slot] == NOMOTION ||
		xend[slot] == NOMOTION || yend[slot] == NOMOTION
	) return;
	) {
		swipe = gesturecalculatetap(now, elapsedms);
		if (swipe < 0) return;
	} else {
		swipe = gesturecalculateswipe(
			xstart[slot], ystart[slot], xend[slot], yend[slot], distancethreshold
		);
	}

	Swipe swipe = gesturecalculateswipe(
		xstart[slot], ystart[slot], xend[slot], yend[slot], distancethreshold
	);
	Edge edge = gesturecalculateedge(
		xstart[slot], ystart[slot], xend[slot], yend[slot]
	);
@@ -387,10 +413,7 @@ touchup(struct libinput_event *e)

	// All fingers up - check if within millisecond limit, exec, & reset
	if (nfdown == 0) {
		if (
			timeoutms >
			((now.tv_sec - timedown.tv_sec) * 1000000 + (now.tv_nsec - timedown.tv_nsec) / 1000) / 1000
		) gestureexecute(swipe, nfpendingswipe, edge, distance, ActModeReleased);
		if (timeoutms > elapsedms) gestureexecute(swipe, nfpendingswipe, edge, distance, ActModeReleased);

		nfpendingswipe = 0;
	}
@@ -498,6 +521,7 @@ main(int argc, char *argv[])
						if (!strcmp(gestpt, "URDL")) gestsarr[gestsarrlen-1].swipe = SwipeURDL;
						if (!strcmp(gestpt, "ULDR")) gestsarr[gestsarrlen-1].swipe = SwipeULDR;
						if (!strcmp(gestpt, "DRUL")) gestsarr[gestsarrlen-1].swipe = SwipeDRUL;
						if (!strcmp(gestpt, "DT")) gestsarr[gestsarrlen-1].swipe = TapDouble;
						break;
					case 2:
						if (!strcmp(gestpt, "L")) gestsarr[gestsarrlen-1].edge = EdgeLeft;
-- 
2.32.0

Thanks! This looks very good to me, it doesn't look like it conflicts
with any existing functionality (depending on how the user or we
configure the taps of course). I'll test it for a bit first and then
merge it after. It opens up interesting new possibilities for those who
prefer taps over swipes.

--

Maarten van Gompel (proycon)
https://proycon.anaproy.nl


On 21-07-21 02:29, dropkick wrote:
Neat - will have to test this out soon, but generally I'd be receptive
to merge.

One small note, I think it'd be helpful to make the abbreviation TD
instead of DT.  E.g. to follow object - modifier form.

That way in the future if we want to support 3-taps or 4-taps we could
do, TS - tap single, TD - tap double, TT - tap triple, TQ - tap quadruple.
Or maybe even T1, T2, T3, T4 is better.

--

Also as a separate note, since we added TapSingle in this logic
might as well add the associated strcmp / CLI flag opt.