Wednesday, June 16, 2010

An (incomplete) roundup of touchpad features

Every once in a while, I stumble across a blog post titled "Multitouch with the synaptics driver" or something similar. Usually I find out that these posts describe how to enable two-finger scrolling or something similar. So I figured, maybe it's time to have something like a roundup of the features of the synaptics driver. As I have posted not too long ago, we have a great many options not all of them as useful as they could be.

First of all - the name "synaptics" is historical and now woefully inadequate. On Linux, we now rely on the kernel to address device-specifics and simply use the event API. In fact, synaptics is just like evdev with different features. (Note to non-Linux users: we still have the backends for hardware communication in the driver as well)

So whenever we talk about "synaptics devices", the "synaptics driver", or "synaptics features" in X, we mean "touchpad". All of the features are described in the man page and can be set either as an xorg.conf option or at runtime by tweaking the properties (with xinput or synclient). I'll brush on the capabilities exposed by the GNOME tool, for the KDE tool check the comments, I'm sure Kevin Kofler will point to them as usual.

Furthermore, I won't list the various options required to configure all this - simply look it up in the man page and you may find some other gems in there too.

Edge scrolling


The most commonly used touchpad feature is likely edge scrolling. Four edges are defined on the touchpad and movement outside of these edges is interpreted as scrolling. By convention, scrolling in X is buttons 4,5 and 6,7 for vertical and horizontal scrolling, respectively. If movement in the scrolling areas is detected, the driver converts the motion into a number of button presses for these scroll buttons.

Vertical and horizontal edge scrolling is hardcoded to only work on the right and the bottom part of the touchpad. They can be enabled separately and independently, though the GNOME GUI we have for it ties the horizontal scroll method to the vertical scroll method.

Edge scrolling is quite configurable, allowing for minimum and maximum speed settings and even pressure-dependent scrolling. Of course, the distance required to emit one scrolling event is configurable as well. None of these tweaks are exposed in the GNOME GUI.

Two-finger scrolling


Two-finger scrolling is the basic multi-touch feature that the driver provides. If two fingers are detected on the touchpad (you will need the hardware capabilities to do so), vertical and horizontal two-finger movements are converted into scrolling events. Provided the scroll methods are activated of course. The GNOME GUI allows for either edge or two-finger scrolling, the driver could provide both simultaneously.

Now, the interesting thing about two-finger scrolling is that it is usable on touchpads that only support single-fingers as well - through the two-finger emulation. If enabled, the driver tries to guess based on the width of the finger whether it is a single or dual-finger input and then trigger the required bits.

Other than that, two-finger scrolling is rather unexciting, it just does what it says on the box. As with edge scrolling, the minimum distances for a scroll event to be generated is configurable (but not in the GUI).

Multi-finger tapping


Tapping is the action of quickly putting a finger down on the touchpad and lifting it again. Multi-finger tapping is the same action with more than one finger. Synaptics currently supports up to three-finger tapping plus corner tapping. Each multi-finger tap can be assigned a different button, the default the GNOME tool assigns if tapping is enabled is 1/2/3 finger tapping to left/right/middle. Again, multi-finger support relies on your hardware.
Tap-and-drag is automatically enabled, whereby tapping an object, then dragging it with one finger "locks" the mouse button on the object.

Corner tapping works similar, but instead activates hot-zones in the corners of the touchpad (defined by the edge settings). Each corner can also be assigned a different button action. Corner tapping is not exposed in the GUI at this point.

Click fingers


Click fingers are similar to tapping in configuration and effect, but the trigger is different. The ClickFinger actions are executed when the left button is pressed while fingers are down on the touchpad. So if you leave two fingers resting on the touchpad and press the physical button, the configured action is executed. This can be quite useful for those that cannot or do not want to use tapping but still require left/right mouse button presses from their touchpad.

Circular scrolling


Similar to the edge and two-finger scrolling but detects circular motions instead of up/down and left/right motions. This works quite similar to the iPod interface. Depending on the trigger, a circular motion started in that trigger area (e.g. top right corner) will initialize the scrolling behaviour. Note that the circular scrolling events are generated per angle motion, i.e. by changing the radius of the circle you can change the speed of the scrolling.

Coasting


For scrolling, synaptics has coasting available as well. If enabled, scrolling continues even if the finger has lifted off the pad - provided enough force was to begin with. So if you quickly swipe two fingers up/down, scrolling will only stop once you tap the touchpad again. Coasting is disabled by default and judging by my computer, Firefox seems to be slow enough to give it a coasting feel anyway ;)
Also note that this isn't a physics model, it's a simple start/stop mechanism which arguably isn't quite as useful as a physics model may be.


Multi-touch gestures


We don't have any of the well-known pinch, rotate, swipe, etc. gestures yet. The main issue here is not the driver itself, it would be reasonably easy to add the bits to the driver but we can't do much with it. We have no meaningful way to transmit the gesture data to the client. So it's down to hacks like in the infamous elantech driver that shipped with the Dell Minis. Unfortunately, having the driver generate keystrokes like Ctrl+ to zoom in is hacky at best and nightmarish at worst.
We really need to update the middle-man here (the X server) to provide this information to the client so they can do the appropriate stuff with it. Alas, this work is taking a while.

SHM configuration


I just wanted to add this to have one more place to say it: SHM config doesn't exist anymore. You will need X server 1.6 or later to run the current versions of synaptics and if you see a message asking you to enable SHM configuration, your distribution may need updating or the program that pops up this message may need to be fixed.

15 comments:

Marius Gedminas said...

An awesome summary!

(I wonder if coasting was ever enabled by default. I seem to remember encountering it and thinking I found a bug -- but that could be just my memory throwing false positives. I think there was once a bug where even a slight two-finger scroll _upwards_ would start the driver coasting _downwards_.)

Robin said...

Can you also write something about "pixel-precise" two-finger scrolling like in Mac OS X?

At the moment in Linux, scrolling on a touchpad with two fingers happens in discrete steps. The scrolled area jumps by a number of lines at a time instead of a continuous, smooth motion that corresponds to the motion of the fingers.

Jani said...

Interesting writeup. I always did wonder why the pinch gesture was so awfully bad on my Eee PC 901. I guess not having real support for it explains it.

Then again, the touchpad hardware does seem to be of lower accuracy than Apple's.

Adam said...

Awesome, thanks for the writeup.

Coincidentally I'd been trolling around the web somewhat fruitlessly trying to figure out what the state of linux multitouch was.

I'd love to try this on my desktop. Have you seen any desktop hardware that should/probably supports these bits? Bonus points for a largerish surface and bluetooth.

There have been rumors of an apple "magic pad" recently but nothing shipping.

So this is single device gestural. How close to getting an mpx'ish absolute position'ed touchpad could I get?

Peter Hutterer said...

Robin:
right now we don't have any pixel-precise scrolling. this is a bigger issue, the button 4-7 is by convention which means changing to a different scroll mechanism will require clients to update accordingly.

Jani:
The upstream driver doesn't have pinch gestures. There's various hacks floating around, at least some of them converting pinch in to a Ctrl+/Ctrl- keystroke. None of them are appropriate for upstream, IMO.

Adam:
Try to hook the evdev driver up to the touchpad and it can be positioned absolute. You will lose touchpad specific features though (tapping, etc.).

georg_H said...

>two-finger scrolling is rather unexciting,
>it just does what it says on the box

No, it does not. It is usually very hard to put two fingers and leave them at exactly the same time. If one does not do so that way, for example by putting a finger first, then the other, the driver moves the pointer and then scrolls by the amount of separation between fingers, all of this without moving any of them!

This makes this feature completely unusable. I have tried to fix it, but I failed, I still don't understand the synaptics.c code correctly. I managed to get it slightly better few years ago, but it was not robust enough to publish it, and I have lost the modifications :(.

This is annoying as well as when using two and three fingers to press a button, either by tapping or clicking, because every time you put more than one finger, the cursor moves and the viewport scrolls, so you can never hit the correct link or button or menu or whatever.

OSX gets it right, as well as acceleration, which has not been working for me since a recent git (I have read something about it in the commits but I don't understand how is supposed to work now).

- The cursor should not move when there is more than one finger (including three fingers).
- It should only scroll when exactly two fingers are moved, not when two fingers are just detected.

my 2c.

David said...

Peter: I get the impression that all touchpads are handled by the “synaptics” driver, not just those manufactured by Synaptics. However, I own a netbook with a Sentelic touchpad, and it is controlled by Sentelic’s own open driver. This driver specifically avoids detecting edge-scrolling due to patents held by Synaptics, from what I can tell. This is predictably pretty frustrating. So, I was wondering: if the synaptics driver is supposed to be generic, shouldn’t it be handling my touchpad as well (and, thus, giving me some of the features you describe here)? Thanks.

Peter Hutterer said...

georg_H:
two-finger scrolling scrolls with two fingers. For everything else please file a bug or raise it on the mailing list. my blog is not the right place for feature suggestions, bug fixes or similar. Things will get lost if they are not archived in the list or bugzilla.

David:
if there's a kernel driver for it, synaptics should be able to pick it up. if it's currently handled by another driver, then that is a configuration decision and can be changed. Please raise this on xorg@lists.freedesktop.org, together with some more info (log files, what driver is this, etc.).

Alex Wauck said...

What about touchpads that seem to have multitouch (and therefore, presumably, the ability to detect multiple fingers) in Windows, but not in Linux? Any idea what's up with that? New protocol?

Peter Hutterer said...

Alex:
usually a case of the driver protocol having changed and the kernel driver needing new bits to deal with that protocol.

Ceno said...

I've always been curious about "pixel-precise" scrolling in linux.

"Of course, the distance required to emit one scrolling event is configurable as well"

Can this not be achieved by some clever math? if we were to reduce the distance, thus sending a lot of scrolling events, but also reduce the number of lines that one scrolling event scrolls... is this doable or would the overhead of sending too many scroll events kill the performance?

On a side note, I am currently thinking about doing my master's thesis on a project that would involve multi-touch gestures. You say that work in this area is taking a while, how can I find out what work is being done, what would the end results be and when, etc?

Max said...

Robin, Ceno:
I'm currently hacking something together to support smooth/pixel-precise scrolling.
I got it working with evdev & synaptics.
Post on xorg-devel with more information + demo: http://www.mail-archive.com/xorg-devel@lists.x.org/msg09636.html

David said...

Peter: I finally posted an e-mail to the X.org list. Sorry for taking so long to do it. Thank you for the advice.

The Dark Shadow said...

Useless without xorg.conf instructions.

D.

DanaGoyette said...

"SHM config doesn't exist anymore" -- so, synclient -m will no longer work!

Why did you entirely remove SHMConfig? If it was a security issue, then you could've made the SHared Memory area readable only by root.

Also, it looks like the lack of multi-finger detection on Synaptics touchpads is an artificial firmware limitation -- this Windows driver enables true multi-finger on ALL synaptics touchpads:
http://www.engadget.com/2010/03/19/synaptics-driver-enables-multitouch-gestures-on-older-trackpads/