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:

(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_.)

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.

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.).

>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.

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.

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.).

"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?

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

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/