142 lines
3.3 KiB
JavaScript
142 lines
3.3 KiB
JavaScript
import Service from 'resource:///com/github/Aylur/ags/service.js';
|
|
import { subprocess } from 'resource:///com/github/Aylur/ags/utils.js';
|
|
|
|
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
|
|
];
|
|
|
|
|
|
// 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();
|
|
/** @type typeof imports.gi.Gio.Subprocess */
|
|
#gestureDaemon;
|
|
|
|
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;
|