nixos-configs/nixosModules/ags/config/services/touch-gestures.ts
matt1432 24aa4b9842
All checks were successful
Discord / discord commits (push) Has been skipped
refactor: make modules independant and exposed in the flake for outside use
2024-08-02 22:32:29 -04:00

143 lines
3.3 KiB
TypeScript

const { subprocess } = Utils;
const SCREEN = '/dev/input/by-path/platform-AMDI0010\:00-event';
const GESTURE_VERIF = [
'LR', // Left to Right
'RL', // Right to Left
'DU', // Down to Up
'UD', // Up to Down
'DLUR', // Down to Left to Up to Right (clockwise motion from Down)
'DRUL', // Down to Right to Up to Left (counter-clockwise from Down)
'URDL', // Up to Right to Down to Left (clockwise motion from Up)
'ULDR', // Up to Left to Down to Right (counter-clockwise from Up)
];
const EDGE_VERIF = [
'*', // Any
'N', // None
'L', // Left
'R', // Right
'T', // Top
'B', // Bottom
'TL', // Top left
'TR', // Top right
'BL', // Bottom left
'BR', // Bottom right
];
const DISTANCE_VERIF = [
'*', // Any
'S', // Short
'M', // Medium
'L', // Large
];
// Types
import { Subprocess } from 'types/@girs/gio-2.0/gio-2.0.cjs';
// TODO: add actmode param
// TODO: support multiple daemons for different thresholds
class TouchGestures extends Service {
static {
Service.register(this, {
'daemon-started': ['boolean'],
'daemon-destroyed': ['boolean'],
});
}
#gestures = new Map();
#gestureDaemon = null as Subprocess | null;
get gestures() {
return this.#gestures;
}
get gestureDaemon() {
return this.#gestureDaemon;
}
addGesture({
name,
nFingers = '1',
gesture,
edge = '*',
distance = '*',
command,
}) {
gesture = String(gesture).toUpperCase();
if (!GESTURE_VERIF.includes(gesture)) {
logError('Wrong gesture id');
return;
}
edge = String(edge).toUpperCase();
if (!EDGE_VERIF.includes(edge)) {
logError('Wrong edge id');
return;
}
distance = String(distance).toUpperCase();
if (!DISTANCE_VERIF.includes(distance)) {
logError('Wrong distance id');
return;
}
if (typeof command !== 'string') {
globalThis[name] = command;
command = `ags -r "${name}()"`;
}
this.#gestures.set(name, [
'-g',
`${nFingers},${gesture},${edge},${distance},${command}`,
]);
if (this.#gestureDaemon) {
this.killDaemon();
}
this.startDaemon();
}
startDaemon() {
if (this.#gestureDaemon) {
return;
}
let command = [
'lisgd', '-d', SCREEN,
// Orientation
'-o', '0',
// Threshold of gesture recognized
'-t', '125',
// Leniency of gesture angle
'-r', '25',
// Timeout time
'-m', '3200',
];
this.#gestures.forEach((gesture) => {
command = command.concat(gesture);
});
this.#gestureDaemon = subprocess(
command,
() => { /**/ },
);
this.emit('daemon-started', true);
}
killDaemon() {
if (this.#gestureDaemon) {
this.#gestureDaemon.force_exit();
this.#gestureDaemon = null;
this.emit('daemon-destroyed', true);
}
}
}
const touchGesturesService = new TouchGestures();
export default touchGesturesService;