That's the most likely area it will be resting in, if it's sitting anywhere
above that it's likely part of an interaction.
A thumb in the lowest 15mm needs to trigger the pressure threshold before it's
labelled a thumb. A thumb in the lowest 8mm is considered a thumb if it
remains there for 300ms. Regardless of the pressure, since we can't reliably
get pressure here. If a thumb moves out of the area, or starts outside of that
area it is never a thumb.
If edge scrolling is enabled, the 8mm threshold is ineffective since we'll
have normal interaction in that zone for horizontal scrolling.
The thumb tests now require all touchpads to be switched to clickfinger, if we
test for thumb detection on the bottom of the pad we won't get expected
motion events due to the software button area.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Thumb detection interfered with gestures a fair bit but it shouldn't. A pinch
gesture with a thumb is a fairly natural move so we shouldn't cancel that.
A swipe gesture with a thumb on the touchpad - well, don't do that. No need
for code here.
Reported-by: Carlos Garnacho <carlosg@gnome.org>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Carlos Garnacho <carlosg@gnome.org>
All touchpad recordings seen so far show that a value above 100 is definitely
a thumb or a palm. Values below are harder to discern, and the same isn't true
for touchpads supporting ABS_PRESSURE instead of ABS_MT_PRESSURE.
The handling of a touch is as outlined in tp_thumb_detect:
* thumbs are ignored for pointer motion
* thumbs cancel gestures
* thumbs are ignored for clickfinger count
* edge scrolling doesn't care either way
* software buttons don't care either way
* tap: only if thumb on begin
The handling of thumbs while tapping is the simplest approach only, more to
come in follow-up patches.
Note that "thumb" is the synonym for "this touch is too big to be a
fingertip". Which means that a light thumb touch will still be counted as a
finger. The side-effect here is that thumbs resting a the bottom edge of the
touchpad will almost certainly not trigger the pressure threshold because
most of the thumb is off the touchpad.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Implement touchpad pinch (and rotate) gesture support.
Note that two two-finger scrolling tests are slightly tweaked to assure that
there is enough touch movement to allow the scroll-or-pinch detect code to do
its work.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Jason Gerecke <jason.gerecke@wacom.com>
This simply doesn't work for low-dpi mice. Normalizing a 400dpi mouse to a
1000dpi mouse forces a minimum movement of 2.5 units and the resulting pixel
jumps. It is impossible for the caller to detect whether the jump was caused
by a single motion or multiple motion events.
This is technically an API break, but not really.
The accelerated data was already relatively meaningless, even if normalized as
the data did not correspond predictably to any input motion (unless you know
the implementation acceleration function in the caller). So we can drop the
mention from there without expecting any ill effects in the caller.
The unaccelerated data was useless for low-dpi mice and could only be used to
measure the physical distance of the mouse movement - something not used in
any caller we're aware of (if needed, we can add that functionality as a
separate call). Dropping motion normalization for unaccelerated deltas also
restores true dpi capabilities to users of that API, mostly games that want to
make use of high-dpi mice.
This is a simplified patch, the normalization is still in place for most of
libinput, it merely carries the original coordinates in the event itself.
In the case of touchpads, the coordinates are unnormalized into the x-axis
coordinate space as per the documentation.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested on three laptops here, Lenovo T61, X220 and an HP EliteBook (?), all
with small touchpads. It's hard to have a hand position where the palm touches
the touchpad while using the trackpoint. So we might as well save us the
effort of monitoring events and enabling/disabling it on demand.
As a side-effect this fixes 1233844, but that's more a coincidence.
https://bugzilla.redhat.com/show_bug.cgi?id=1233844
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
The touchpad is disabled for 500ms after a trackpoint event to avoid
erroneous palm touches. This is currently refreshed on every trackpoint event
and thus forces a delay of 500ms when switching between the two.
Instead, reduce the timeout to 300ms but ignore any touches started while the
trackpoint was active (i.e. before the last trackpoint event). A touch started
after the last event is released once the timeout expires.
This is the same logic used for disable-while-typing.
https://bugzilla.redhat.com/show_bug.cgi?id=1233844
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
No functional changes, just rearranging where it fits better.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Most scroll motions would be labelled a palm.
https://bugs.freedesktop.org/show_bug.cgi?id=90980
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
To quote Bryce Harrington from [1]:
"MIT has released software under several slightly different licenses,
including the old 'X11 License' or 'MIT License'. Some code under this
license was in fact included in X.org's Xserver in the past. However,
X.org now prefers the MIT Expat License as the standard (which,
confusingly, is also referred to as the 'MIT License'). See
http://cgit.freedesktop.org/xorg/xserver/tree/COPYING
When Wayland started, it was Kristian Høgsberg's intent to license it
compatibly with X.org. "I wanted Wayland to be usable (license-wise)
whereever X was usable." But, the text of the older X11 License was
taken for Wayland, rather than X11's current standard. This patch
corrects this by swapping in the intended text."
libinput is a fork of weston and thus inherited the original license intent
and the license boilerplate itself.
See this thread on wayland-devel here for a discussion:
http://lists.freedesktop.org/archives/wayland-devel/2015-May/022301.html
[1] http://lists.freedesktop.org/archives/wayland-devel/2015-June/022552.html
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Acked-by: Jonas Ådahl <jadahl@gmail.com>
On touchpads with resolutions, use a 5mm motion threshold before we unpin the
finger (allow motion events while a clickpad button is down). This should
remove any erroneous finger movements while clicking, at the cost of having to
move the finger a bit more for a single-finger click-and-drag (use two fingers
already!)
And drop the finger drifting, it was per-event based rather than time-based.
So unless the motion threshold was hit in a single event it was possible to
move the finger around the whole touchpad without ever unpinning it.
Drop the finger drifting altogether, if the touchpad drifts by more than 5mm
we have other issues.
https://bugzilla.redhat.com/show_bug.cgi?id=1230462
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
The current code labels a touch as palm if it started within the typing
timeouts. To move the pointer even after the timeout expires, a user has to
lift the finger which is quite annoying and different to the old synaptics
driver behaviour (which had a simple on/off toggle on whether to let events
through or not).
Be smarter about this: if a touch starts _after_ the last key press event,
release it for pointer motion once the timeout expires. Touches started before
the last key press remain labelled as palms. This makes it possible to rest
the palm on the touchpad while typing without getting interference but also
provides a more responsive UI when moving from typing to using the touchpad
normally.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Check a couple of easy yes/no definitives that cover most Lenovo laptops,
and avoid false positives on Wacoms.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
On some touchpads, typing triggers touches in areas of the touchpad that
cannot easily be distinguished from other fingers. Pressure information is
useless too, so we have to go back to a timeout-based handling of touch data.
If we see non-modifier key events, disable the touchpad for a timeout and set
any touches starting during that timeout as palm.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Preparation to add different palm detection types. Not all of them need to be
un-done when leaving the edge area so a boolean is not enough.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Currently for the tap-and-drag gesture to end user has to wait for a
timeout to expire. Make it possible to end the drag gesture by just tapping.
The allowed finger sequences to start and end a drag are thus:
tap, down, .... move ...., up <wait for timeout>
tap, down, .... move ...., up, tap
https://bugs.freedesktop.org/show_bug.cgi?id=90255
Signed-off-by: Velimir Lisec <lisec.velimir@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
State diagram changes and a doc change squashed in.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
When the device supports true hovering, it reports this
information through ABS_MT_DISTANCE.
When this axis is available, we should rely on it to
(un)hover the touches as BTN_TOUCH is most of the time
unreliable (generated by the mouse emulation in the kernel).
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Use tp->nfingers_down as trigger when we have no fingers left on the touchpad
and when we should return to idle. If all touchpoints end in the same frame
tp->nfingers is 0. Thus when we handle the first tap release we transition to
IDLE which now needs to handle (and discard) any touch release events.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Once we have a doubletap, enter a loop in the state machine where we can tap
multiple times and either get a multi-click or a multi-click drag-and-drop.
The sequence down/up down/up down/up produces a triple-click. The sequence
down/up down/up down/up down produces a triple-click with a button down for
dragging. Yes, that glorious octuple-tap-and-drag, it is now possible. World
domination has been achieved, thank you for playing.
We don't know when we finish tapping now, so add a timeout to send the last
click event once the finger has been released for the last time. This
guarantees that the timestamp of the last button down is later than the
last release. This avoids the bug fixed in synaptics commit
xf86-input-synaptics-1.8.0-21-g37d34f0 (some application don't handle
doubletap correctly without the timestamps).
This works for double-tap immediately, for multi-tap we need to remember the
timestamp of the first press event and use it for the release event so that
there's a forced gap between the release and the second press.
https://bugs.freedesktop.org/show_bug.cgi?id=89511
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Touches in the exclusion zone are ignored for palm detection and don't move
the cursor. Tapping however triggers before we know whether something is a
palm or not, so we get erroneous button clickst.
If a tap happens in the top half of the touchpad, within the palm exclusion
zones, ignore it for tap purposes. To avoid further complicating the state
machine simply pretend there was a movement > threshold on that finger. This
advances the tap state machine properly that no button events are sent for
this finger.
https://bugs.freedesktop.org/show_bug.cgi?id=89625
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Less ambiguous since real_touches can be interpreted to "current number of
real touches as opposed to fake touches". Which it isn't, this variable holds
the number of slots.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
tp->nfingers_down gives us the current state of the touchpad but in the case
of the tapping state we need the touchpoints separately. If all touchpoints
end in the same SYN_REPORT frame, tp->nfingers_down is 0 when we handle the
touch releases. This changes the tap state to IDLE on the first release and
then logs a bug when the remaining touches are released while the touchpad is
in IDLE.
Avoid this by counting the fingers separately for the tap state, this way we
can count up/down with the down/up events as we process them for the tapping
state machine.
This also adds tests for 4 and 5-finger tapping which is how the bug was
discovered in the first place.
https://bugs.freedesktop.org/show_bug.cgi?id=89800
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
What we really need is not a specific delta type, but a type which can hold
non discrete device coordinates, this is e.g. also needed for the center
coordinates of gestures. So rename delta_coords to device_float_coords to
properly reflect what we really need.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Change tp_filter_motion to use normalized_coords, rather then having it take
separate x and y values.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
tp_normalize_coords is one of the last functions taking separate x, y
values rather a coordinate pair, this commit cleans this up.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This way the unaccelerated deltas returned by libinput are correct.
To maintain the current behavior we slow down the input speed by the magic
factor and likewise the accelerated output speed. This produces virtually the
same accelerated deltas as the previous code.
The magic factor is applied to the default denominator for guessing a
resolution based on the touchpad diagonal. We can't really get around this
without having a resolution from the touchpad; meanwhile this produces
virtually the same coordinates before/after.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Now that we've separate handling of the EDGE_NEW vs EDGE states in
tp_edge_scroll_post_events() we can drop the threshold variable, in EDGE_NEW
we always want to check against DEFAULT_SCROLL_THRESHOLD and in the EDGE
state we only want to make sure that the delta != 0.0 which is already
checked later on in tp_edge_scroll_post_events().
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The previous setting of 10 wasn't 10 mm, it was used against the deltas
normalized to a 1000DPI mouse, i.e. closer to 4mm. It was also also per-event,
so a slow movement or a high-frequency touchpad can struggle to meet the
threshold.
Change the trigger to be ~5 mm from the initial touch down, accumulated until
we either meet the threshold or the timeout expires. The first scroll event
includes the delta since the touch down rather than the most recent delta.
This removes the delay otherwise seen in scrolling and makes the scroll motion
match the finger motion. This accumulated delta only applies when exceeding
the motion threshold, when the timeout triggers the switch to scrolling the
first delta posted is the current delta.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Previous code used a device coordinate threshold of 300 which won't work on
Elantech touchpads (1280 vs the ~4000 that synaptics has).
Convert to normalized DPI and reduce the threshold to 3mm.
https://bugs.freedesktop.org/show_bug.cgi?id=89206
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Ideally we want to specify various thresholds in mm, but not all touchpads
set the hardware resolutions. Rather than conditions to check for resolutions
everywhere, use a macro to give us a normalized value that we use for motion
as well.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
All callers except the tap motion threshold call
tp_get_delta() followed by tp_filter_motion() - the latter normalized it
before calling into the accleration code.
Move the normalization into tp_get_delta() so we don't deal with
device-specific coordinates but normalized deltas instead.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Just moving some code around, no functional changes.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Handle everything which is not handled by the tap, (soft)button or edge-scroll
code/statemachines in a unified way. Everything is treated as a X-finger
gesture now, and the action to take on finger movement is decided by
the gesture.finger_count setting. Pointer control now simply is seen as a
1 finger gesture, and 2fg scrolling as a 2fg gesture.
This removed the need for special-casing things like switching back to
pointer mode when lifting a finger in 2fg scrolling mode, and also lays the
groundwork for adding 3+ fg gesture support.
Note that 1 test-case needs to be updated to wait for the finger mode
switching when switching mode while a gesture has already been started.
This is actually an improvement as this stops sending spurious pointer
motion events at the end of 2fg scrolling when not lifting both fingers at
exactly the same time.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Allow switching between softbuttons and clickfinger on any mt-capable
clickpad.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
[hdegoede@redhat.com] Keep top softbuttons working when enabling clickfinger
[hdegoede@redhat.com] Simply touchpad click method switching
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Some touchpads provide touch information while the finger hovers over the
touchpad, i.e. before BTN_TOUCH. Add a touch state for those touchpads so we
can ignore the touches until they actually start.
The approach is now: instead of BEGIN we mark a new touch as HOVERING.
Use the BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP information during
tp_process_state() to mark any touches that are hovering as down or ended.
i.e. provided BTN_TOUCH is down: if BTN_TOOL_FINGER is down, one hovering
touch gets marked as down, if DOUBLETAP is down, two touches are marked as
down, etc.
When ending touches, switch them back into HOVERING if the BTN_TOOL_FINGER
is still set, otherwise end them properly.
https://bugs.freedesktop.org/show_bug.cgi?id=87197
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
We need this for determining hovering touches on some semi-mt touchpads.
This makes the fake_touches mask use bit 0 for BTN_TOUCH, and the other bits
for BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, etc. BTN_TOUCH is independent of the
rest, the others are mutually exclusive in the kernel.
Since the mask isn't a straightforward bitmask anymore, abstract it all
through helper functions.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Add a boolean state machine for two-finger scrolling so we know when we're
currently scrolling. If we were scrolling and it stops, pick the active
touch as pointer touch so we can go back to pointer movement without having to
lift the finger off the touchpad.
https://bugs.freedesktop.org/show_bug.cgi?id=86807
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>