3
[PATH lisgd 1/4] spawn actions asyncronously
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
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
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
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