Rewrite of a widely used Python program that binds touchpad gestures to external commands. This C rewrite is motivated by the limitations of using an interpreted language to read events from libinput
.
Project README
libinput-gestures
This work is inspired by the Python version of libinput-gestures
.
This is still a work in progress.
Motivation
From the Python version’s README :
You must be a member of the input group to have permission to read the touchpad device:
Adding your user to the input
group is a security risk, as it allows any
process running under your session to read all inputs regardless of window
focus, including inputs from the keyboard.
The recommended way to run a program that accesses input devices without the
user being a member of the input
group is to use
setgid()
. However, this is
not possible to do that using an interpreted language, as the sgid
bit needs
to be set on the binary itself. Doing this with the Python version would
require changing the group ownership and setting the sgid
bit on the Python
interpreter, which would allow any Python program on the computer to read all
inputs.
Rewriting this in C makes it possible to use setgid()
in the proper way.
Moreover, I happened to have issues with the Python implementation where some libinput messages would get stuck in the buffer.
User manual (short draft)
While this project is still a bit rough around the edges, it currently provides most of the python version’s features :
- Ability to map gestures to external commands
- Handles 4 directions for swipes
- Handles pinch in and out
- Handles gesture thresholds and timeouts
After cloning the repo, cd
into it and build the executable. make
libinput-gestures
builds the executable and changes the permissions on it to
enable setgid(...)
(requires root privileges, you will be prompted via
sudo
). Running the program does NOT require you to add your user to the
input
group : just run ./libinput-gestures
.
Configuration
The program tries to load a configuration file from the following locations (in decreasing order of priority) :
- The first argument to the program if supplied
config.yaml
in the running dir$HOME/.config/libinput-gestures.yaml
/etc/libinput-gestures.yaml
When there is an error reading a file (including syntax errors or non-existing file), the program reports the error and skips to the next file in the list. It stops on the first successful configuration load.
trigger_configs
lets you define named gesture configuration in the following format :
trigger_configs:
- name: default
- name: swipe_threshold
config:
threshold: 50
- name: swipe_timeout
config:
threshold: 50
min_duration: 0 # No minimum duration for detecting the gesture
max_duration: 3000 # The gesture will timeout 3s after being started
- name: pinch_out
config:
threshold: 1.2
- name: pinch_in
config:
threshold: 0.75
All values for the config
parts are optional (as well as the config part itself). If omitted, parameters will default to 0.
triggers
defines the conditions for triggering actions and the corresponding actions :
triggers:
- type: swipe
direction: left
fingers: 3
trigger_on: end
config: default
command:
- notify-send
- Test yaml swipe left
- type: swipe
direction: right
fingers: 3
trigger_on: end
config: default
command:
- notify-send
- Test yaml swipe right
- type: swipe
fingers: 3
trigger_on: end
config: swipe_threshold
command:
- notify-send
- Test yaml swipe vertical
- type: pinch
fingers: 2
trigger_on: end
config: pinch_out
command:
- notify-send
- Test yaml pinch out 2 end
- type: pinch
fingers: 2
trigger_on: end
config: pinch_in
command:
- notify-send
- Test yaml pinch in 2 end
Each trigger has the following fields :
type
(required) :swipe
orpinch
fingers
(required) : integertrigger_on
(required) :end
orthreshold
orrepeat
direction
(optional):none
(default) orleft
orright
orup
ordown
. Only used for swipe gestures, not used for pinch gestures.none
matches any direction when used with swipe gestures.config
(required) : string matching the name of a config from thetrigger_configs
sectioncommand
(required) : list of args for the command to run when this trigger is matched (the 1st is the command name)
TODO notes
- Triggers that are not external program calls
- Clean seat detection ?
- Install config file in
make install