~mil/sxmo-devel

3

[PATH lisgd 1/4] spawn actions asyncronously

Details
Message ID
<20240508193041.334855-1-aren@peacevolution.org>
DKIM signature
pass
Download raw message
Patch: +17 -2
This might help a little with the responsiveness of repeated gestures
such as volume and brightness in sxmo.

I wrote it so I can compare the time it takes to execute a gesture to
the time between touch-down and touch-up.
---
 lisgd.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/lisgd.c b/lisgd.c
index 921f5bc..b462446 100644
--- a/lisgd.c
+++ b/lisgd.c
@@ -8,6 +8,7 @@
#include <string.h>
#include <sys/prctl.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#ifdef WITH_X11
@@ -211,6 +212,14 @@ gesturecalculateedge(double x0, double y0, double x1, double y1) {
		}
}

void run_action(Gesture *gest) {
	int pid = fork();
	if (pid == -1)
		perror("fork");
	else if (pid == 0)
		execlp("sh", "sh", "-c", gest->command, NULL);
}

int
gestureexecute(Swipe swipe, int nfingers, Edge edge, Distance distance, ActMode actmode) {
	int i;
@@ -233,7 +242,7 @@ gestureexecute(Swipe swipe, int nfingers, Edge edge, Distance distance, ActMode
			&& (actmode == ActModeReleased || gestsarr[i].actmode == actmode)
			) {
			if (verbose) fprintf(stderr, "Execute %s\n", gestsarr[i].command);
			system(gestsarr[i].command);
			run_action(&gestsarr[i]);
			return 1; //execute first match only
		}
	}
@@ -436,7 +445,7 @@ run(void)
	FD_SET(libinput_get_fd(li), &fdset);
	for (;;) {
		selectresult = select(FD_SETSIZE, &fdset, NULL, NULL, NULL);
		if (selectresult == -1) {
		if (selectresult == -1 && errno != EINTR) {
			die("Can't select on device node?");
		} else {
			libinput_dispatch(li);
@@ -514,6 +523,10 @@ wl_registry_listener wl_registry_listener = {
};
#endif

void handle_sigcld() {
	waitpid(-1, NULL, WNOHANG);
}

int
main(int argc, char *argv[])
{
@@ -669,6 +682,8 @@ main(int argc, char *argv[])
		if (gestsarr[i].actmode == ActModePressed) have_actmode_pressed++;
	}

	signal(SIGCLD, handle_sigcld);

	run();
	return 0;
}
-- 
2.45.0

[PATH lisgd 2/4] add -F flag to execute all gestures as soon as they are matched

Details
Message ID
<20240508193041.334855-2-aren@peacevolution.org>
In-Reply-To
<20240508193041.334855-1-aren@peacevolution.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +27 -3
This gives the system a head start on executing the gesture, at the cost
of some accuracy. This is a noticeable performance improvement, but it
requires adjusting how the gestures are used (to avoid incorrect
triggers). Put it behind a flag because of this.
---
My goal (we'll see if it's possible) is to optimize the common actions in sxmo
(such as opening the context menu or switching worksapces) to a point where the
action finishes before the touch up event.

 lisgd.1 |  6 ++++++
 lisgd.c | 24 +++++++++++++++++++++---
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/lisgd.1 b/lisgd.1
index dd197cc..5a0e107 100644
--- a/lisgd.1
+++ b/lisgd.1
@@ -13,6 +13,7 @@ lisgd \- libinput synthetic gesture daemon
[\fB\-w\fR \fIwidth\fR]
[\fB\-h\fR \fIheight\fR]
[\fB\-r\fR \fIdegreesofleniency\fR]
[\fB\-F]
[\fB\-v]


@@ -43,6 +44,11 @@ you're using.
.BR \-d ", " \-d\ devicepath\fR
Path of the dev filesystem device to monitor (like /dev/input/event1).

.TP
.BR \-F \fR
Fast match, all actions are run as soon as they are matched instead of when the
touch-up event occurs.

.TP
.BR \-g ", " \-g\ nfingers,gesture,edge,distance,actmode,command\fR
Allows you to bind a gesture wherein nfingers is an integer, gesture is
diff --git a/lisgd.c b/lisgd.c
index b462446..13f0f18 100644
--- a/lisgd.c
+++ b/lisgd.c
@@ -3,6 +3,7 @@
#include <libinput.h>
#include <math.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -93,6 +94,9 @@ struct wl_output *wl_output;
#endif
static int screenwidth = 0, screenheight = 0;

int greedy = false;
int executed = false;

void
die(char * msg)
{
@@ -213,6 +217,15 @@ gesturecalculateedge(double x0, double y0, double x1, double y1) {
}

void run_action(Gesture *gest) {
	if (executed)
		return;

	if (greedy && gest->actmode == ActModeReleased)
		executed = true;

	if (verbose)
		fprintf(stderr, "Execute %s\n", gest->command);

	int pid = fork();
	if (pid == -1)
		perror("fork");
@@ -239,9 +252,8 @@ gestureexecute(Swipe swipe, int nfingers, Edge edge, Distance distance, ActMode
				((edge == CornerTopLeft || edge == CornerBottomLeft) && gestsarr[i].edge == EdgeLeft) ||
				((edge == CornerTopRight || edge == CornerBottomRight) && gestsarr[i].edge == EdgeRight)
			   )
			&& (actmode == ActModeReleased || gestsarr[i].actmode == actmode)
			&& (gestsarr[i].actmode == actmode || greedy)
			) {
			if (verbose) fprintf(stderr, "Execute %s\n", gestsarr[i].command);
			run_action(&gestsarr[i]);
			return 1; //execute first match only
		}
@@ -367,6 +379,7 @@ touchup(struct libinput_event *e)
	int slot;
	struct libinput_event_touch *tevent;
	struct timespec now;
	executed = false;

	tevent = libinput_event_get_touch_event(e);
	slot = libinput_event_touch_get_slot(tevent);
@@ -545,6 +558,8 @@ main(int argc, char *argv[])
		} else if (!strcmp(argv[i], "-d")) {
			if (i == argc - 1) die("option -d expects a value");
			device = argv[++i];
		} else if (!strcmp(argv[i], "-F")) {
			greedy = true;
		} else if (!strcmp(argv[i], "-t")) {
			if (i == argc - 1) die("option -t expects a value");
			distancethreshold = atoi(argv[++i]);
@@ -624,7 +639,7 @@ main(int argc, char *argv[])
				}
			}
		} else {
			fprintf(stderr, "lisgd [-v] [-d /dev/input/0] [-o 0] [-t 200] [-r 20] [-m 400] [-g '1,LR,L,*,R,notify-send swiped left to right from left edge']\n");
			fprintf(stderr, "lisgd [-v] [-F] [-d /dev/input/0] [-o 0] [-t 200] [-r 20] [-m 400] [-g '1,LR,L,*,R,notify-send swiped left to right from left edge']\n");
			exit(1);
		}
	}
@@ -674,6 +689,9 @@ main(int argc, char *argv[])
		memcpy(gestsarr, gestures, sizeof(gestures));
	}

	if (greedy)
		have_actmode_pressed = 1;

	// Modify gestures swipes based on orientation provided
	for (i = 0; i < gestsarrlen; i++) {
		gestsarr[i].swipe = swipereorient(gestsarr[i].swipe, orientation);
-- 
2.45.0

[PATH lisgd 3/4] log touch events with timestamps

Details
Message ID
<20240508193041.334855-3-aren@peacevolution.org>
In-Reply-To
<20240508193041.334855-1-aren@peacevolution.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +30 -2
I'm interested in analyzing how long gestures take to be recognized, and
how long the handler takes to process, so add log messages with this
information.
---
 lisgd.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/lisgd.c b/lisgd.c
index 13f0f18..a5ab6b2 100644
--- a/lisgd.c
+++ b/lisgd.c
@@ -85,6 +85,7 @@ Edge pendingedge;
Distance pendingdistance;
double xstart[MAXSLOTS], xend[MAXSLOTS], ystart[MAXSLOTS], yend[MAXSLOTS];
unsigned nfdown = 0, nfpendingswipe = 0;
struct timespec time_start;
struct timespec timedown;
static int screen;
#ifdef WITH_WAYLAND
@@ -104,6 +105,28 @@ die(char * msg)
	exit(1);
}

struct timespec elapsed() {
	struct timespec now;
	struct timespec diff;

	clock_gettime(CLOCK_MONOTONIC_RAW, &now);

	diff.tv_sec = now.tv_sec - time_start.tv_sec;
	if (time_start.tv_nsec > now.tv_nsec) {
		diff.tv_sec -= 1;
		diff.tv_nsec = (1e9 - time_start.tv_nsec) + now.tv_nsec;
	} else {
		diff.tv_nsec = now.tv_nsec - time_start.tv_nsec;
	}

	return diff;
}

#define info(fmt, ...) if (verbose) { \
	struct timespec diff = elapsed(); \
	fprintf(stderr, "%lu.%.3u: " fmt "\n", diff.tv_sec, (int)(diff.tv_nsec/1e6), ##__VA_ARGS__); \
}

int
gesturecalculateswipewithindegrees(double gestdegrees, double wantdegrees) {
	return (
@@ -223,8 +246,7 @@ void run_action(Gesture *gest) {
	if (greedy && gest->actmode == ActModeReleased)
		executed = true;

	if (verbose)
		fprintf(stderr, "Execute %s\n", gest->command);
	info("Execute %s", gest->command);

	int pid = fork();
	if (pid == -1)
@@ -317,6 +339,7 @@ touchdown(struct libinput_event *e)
{
	struct libinput_event_touch *tevent;
	int slot;
	info("touch down");

	tevent = libinput_event_get_touch_event(e);
	slot = libinput_event_touch_get_slot(tevent);
@@ -381,6 +404,8 @@ touchup(struct libinput_event *e)
	struct timespec now;
	executed = false;

	info("touch up");

	tevent = libinput_event_get_touch_event(e);
	slot = libinput_event_touch_get_slot(tevent);
	nfdown--;
@@ -537,6 +562,7 @@ wl_registry_listener wl_registry_listener = {
#endif

void handle_sigcld() {
	info("child exited");
	waitpid(-1, NULL, WNOHANG);
}

@@ -546,6 +572,8 @@ main(int argc, char *argv[])
	int i, j;
	char *gestpt;

	clock_gettime(CLOCK_MONOTONIC_RAW, &time_start);

	gestsarr = NULL;
	gestsarrlen = 0;

-- 
2.45.0

[PATH lisgd 4/4] use info macro for verbose logging

Details
Message ID
<20240508193041.334855-4-aren@peacevolution.org>
In-Reply-To
<20240508193041.334855-1-aren@peacevolution.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +8 -10
This cleans up the code a bit, and will ensure we have a consistent log
format.
---
 lisgd.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/lisgd.c b/lisgd.c
index a5ab6b2..5b9e7e6 100644
--- a/lisgd.c
+++ b/lisgd.c
@@ -143,8 +143,7 @@ gesturecalculateswipe(double x0, double y0, double x1, double y1, int mindistanc
	degrees = 57.2957795130823209 * (t < 0 ? t + 6.2831853071795865 : t);
	dist = sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2));

	if (verbose)
		fprintf(stderr, "Swipe distance=[%.2f]; degrees=[%.2f]\n", dist, degrees);
	info("Swipe distance=[%.2f]; degrees=[%.2f]", dist, degrees);

	if (dist < mindistance) return -1;
	else if (gesturecalculateswipewithindegrees(degrees, 0))   return SwipeDU;
@@ -260,12 +259,11 @@ gestureexecute(Swipe swipe, int nfingers, Edge edge, Distance distance, ActMode
	int i;

	for (i = 0; i < gestsarrlen; i++) {
		if (verbose) {
			fprintf(stderr,
				"[swipe]: Cfg(f=%d/s=%d/e=%d/d=%d) <=> Evt(f=%d/s=%d/e=%d/d=%d)\n",
				gestsarr[i].nfswipe, gestsarr[i].swipe, gestsarr[i].edge, gestsarr[i].distance, nfingers, swipe, edge, distance
			);
		}
		info(
			"[swipe]: Cfg(f=%d/s=%d/e=%d/d=%d) <=> Evt(f=%d/s=%d/e=%d/d=%d)",
			gestsarr[i].nfswipe, gestsarr[i].swipe, gestsarr[i].edge, gestsarr[i].distance, nfingers, swipe, edge, distance
		);

		if (gestsarr[i].nfswipe == nfingers && gestsarr[i].swipe == swipe
			&& gestsarr[i].distance <= distance
			&& (gestsarr[i].edge == EdgeAny || gestsarr[i].edge == edge ||
@@ -383,10 +381,10 @@ touchmotion(struct libinput_event *e)
				timeoutms >
				((now.tv_sec - timedown.tv_sec) * 1000000 + (now.tv_nsec - timedown.tv_nsec) / 1000) / 1000
			) {
				if (verbose) fprintf(stderr, "(Attempting to find matching pressed gesture)\n");
				info("Attempting to find matching pressed gesture");
				if (gestureexecute(swipe, nfdown, edge, DistanceAny, ActModePressed)) {
					//we found and executed a matching gesture, reset the slot
					if (verbose) fprintf(stderr, "(Pressed gestured Executed)\n");
					info("Pressed gestured Executed");
					xstart[slot] = xend[slot];
					ystart[slot] = yend[slot];
					timedown = now;
-- 
2.45.0
Reply to thread Export thread (mbox)