~mil/sxmo-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
2 2

[PATCH lisgd] Add double-tap gesture

Details
Message ID
<20210721182927.126116-1-dropkick@razvrat.org>
DKIM signature
pass
Download raw message
Patch: +34 -10
---
 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
Details
Message ID
<20210722181121.luu4pd3exkhf2ult@worker.anaproy.lxd>
In-Reply-To
<20210721182927.126116-1-dropkick@razvrat.org> (view parent)
DKIM signature
missing
Download raw message
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:
> ---
>  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
>

--

Maarten van Gompel

proycon@anaproy.nl
https://proycon.anaproy.nl
https://github.com/proycon

GnuPG key:  0x39FE11201A31555C
XMPP:       proycon@anaproy.nl       Matrix: @proycon:matrix.anaproy.nl
Telegram:   proycon                  IRC: proycon (libera.chat + oftc)
Mastodon:   https://social.anaproy.nl/@proycon   (@proycon@social.anaproy.nl)
Twitter:    https://twitter.com/proycon
Details
Message ID
<94f4a7cb-96e6-4491-89bd-c8f22cf3122b@www.fastmail.com>
In-Reply-To
<20210721182927.126116-1-dropkick@razvrat.org> (view parent)
DKIM signature
pass
Download raw message
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.
Reply to thread Export thread (mbox)