Perhaps one of the biggest difficulties in setting up a Linux system for desktop/home use is the fragmentation of the ecosystem, with many different options claiming to get you from point a to somewhere in the vicinity of point b, each with their subtle differences (and at least a few “gotchas” along the way). An easy example: in 2020, you’d think there would be an easy answer to getting a trackpad/touchpad up and running with support for multi-touch gestures at least on par with the experience on Windows and macOS – after all, it’s been 12 years since Apple made multi-touch popular with 2008 MacBook Air.
The state of Linux multi-touch input in 2020
Unfortunately, it’s not so simple. First there was
xf86-input-synaptics, initially written to specifically target Synaptics touchpads but later updated with support for many different devices – for the longest time this was both the best and the only way of getting Linux to recognize and support the most common trackpads. Along the way to no longer being a Synaptics-only PS/2 touchpad driver,
xf86-input-synaptics started to use the
evdev Linux kernel input driver, which also gave birth to the more generic input/mouse/touchpad
xf86-input-evdev driver that used the same kernel abstraction, which most distributions now use because it featured some (limited) multi-touch gesture support and was viewed as the way forward. Then came Wayland with its “let’s rewrite everything” approach and brought with it
libinput, as yet another replacement abstraction for all input devices. Unlike previous projects, libinput and its accompanying
xf86-input-libinput X11 integration, promised native support for touchpads and multi-touch gestures, touting its superior abstraction as the reason why it could provide a better multi-touch experience where its predecessors couldn’t.
While it’s true that libinput comes with out-of-the-box gesture support, it’s unfortunately a gigantic step back in terms of the actual touchpad experience. As many people that switched from
xf86-input-libinput can attest (or anyone that’s tried libinput on a laptop after using Windows or macOS): it’s horrible. Regardless of how you tweak it (except perhaps if you have the exact make and model of touchpad the developers used), it feels like you’re either trying to push the cursor through mud or else chasing Blinky, Pinky, Inky and Clyde on the final level of PacMan and just can’t keep up. Instead of using the decades of work that went into the existing drivers, libinput just throws out the baby with the bathwater in the name of rewriting the stack and reinventing the wheel: the acceleration curves are extremely poor, the heuristics for determining acceleration give extremely unnatural results, and the entire experience makes one want to never try Linux on a laptop ever again.
Sidebar: if you haven’t already read it, this historical gem features Ted Selker explaining the decade of work that went into developing IBM’s Trackpoint, and the painstaking effort that it takes to create an input device (and accompanying driver/software) that is ergonomic, natural, intuitive, and user friendly. Anyone thinking of rewriting something as complex and subtle as a touchpad driver should read this before thinking they can do a better job and trying to foist their replacement on others.
Rather than risk falling into the same Wayland/libinput mistake in an attempt at creating “a newer, better alternative” (see XKCD #927) and especially given the fact that
xf86-input-synaptics already does a really good job at providing a great – albeit single-touch – touchpad experience out-of-the-box, I wondered how hard it would be to simply add multi-touch gesture support on top of the synaptics input driver. My aspirations were not high: simply having two-finger forward and backward swipe navigation in Firefox would have been enough for me.
I was prepared to have to dig deep into the drivers to add support for multi-touch gestures, but it turned out not to be not very hard at all: as
xf86-input-synaptics now uses
libevdev under the hood, the driver-level support for reading multi-touch inputs from the trackpad itself is already fully implemented, just ignored. From there, it didn’t take long to create a proof-of-concept that would allow the
xf86-input-synaptics driver to handle cursor motion, acceleration, deceleration, etc. but allow a userland program/daemon to monitor for and act upon multi-touch inputs (via the Linux multi-touch protocol).
syngesture is a configurable, multi-device capable, and rust-powered userland daemon that brings basic multi-touch support for one-, two-, and three-finger gestures to the venerable
xf86-input-synaptics driver. It is, of course, fully open-source and released under the MIT license.
Like many other solutions, it was originally developed to scratch a personal itch, but after hearing from others with similar complaints, I decided to add some fit and polish (such as machine-wide and per-user config files and support for multiple devices with per-device configuration) that will hopefully make it more useful to the open source community at large. It was originally designed as an alternative to libinput and specifically intended for use with
xf86-input-synaptics as explained above, but it should also work with
xf86-input-evdev and other devices implementing the Linux Multi-Touch Protocol.
syngesture is available on GitHub and is considered ready for general use (modulo distribution-specific packages and system integrations for alternatives for manual configuration – e.g. initial device discovery – and deployment).