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>
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>
Causes an error message in the device_disable_release_tap_n_drag test. When
the touchpad is suspended, all touches are ended in tp_clear_state. Since the
hovering support was added, this returns the touches to TOUCH_HOVERING, a
subsequent tp_handle_state() will turn them back into TOUCH_BEGIN based on
BTN_TOUCH and BTN_TOOL_FINGER still being down.
Clear the fake touch buttons as well after ending the touches, this way the
touch points are reset to TOUCH_NONE as intended.
Once we do that we don't need to manually change the tap finger count when
releasing taps, we can just let the count reset naturally.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Those touchpads presents an actual lower resolution that what is
advertised.
We see some jumps from the cursor due to the big steps in X and Y
when we are receiving data.
For instance, we receive:
E: 13.471932 0003 0000 16366 # EV_ABS / ABS_X 16366
E: 13.471932 0003 0001 9591 # EV_ABS / ABS_Y 9591
E: 13.471932 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
E: 13.479924 0003 0000 16316 # EV_ABS / ABS_X 16316
E: 13.479924 0003 0001 9491 # EV_ABS / ABS_Y 9491
E: 13.479924 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
E: 13.487939 0003 0000 16271 # EV_ABS / ABS_X 16271
E: 13.487939 0003 0001 9403 # EV_ABS / ABS_Y 9403
E: 13.487939 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
-> jumps of ~50 in X in each report, and ~100 for Y.
Apply a factor to minimize those jumps at low speed, and try
keeping the same feeling as regular touchpads at high speed.
It still feels slower but it is usable at least
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Tested-by: Vasily Khoruzhick <anarsoul@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
https://bugzilla.redhat.com/show_bug.cgi?id=1209753 lists a touchpad 76mm wide
that suffers from palm touches
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>
Internal touchpads with trackpoints are either BUS_I8042 or BUS_I2C, but not
BUS_USB. Lenovo sells external keyboards with a trackpoint built-in, make sure
we don't pair that trackpoint with the internal touchpad.
And likewise, the internal trackpoint should not be paired with e.g. a wacom
touch device.
Lenovo had one external device that has a trackpoint and a touchpad on an
external keyboard. That device won't be covered with this patch, if we have a
user we can re-consider.
https://bugs.freedesktop.org/show_bug.cgi?id=89935
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>
Up to QUINTTAP, we count fake fingers through the BTN_TOOL_*TAP kernel defines.
Once we exceed QUINTTAP, the nfake_finger count returns to 0 and
tp_unhover_touches terminates all touch sequences. The most visible effect of
this was stopped in 591a41f but the problem remained.
Since we're not using 5 fingers for anything, use that to set the
overflow flag. The kernel gives us either a BTN_TOUCH 0 (all
released) or a lower BTN_TOOL_*TAP to unset the flag when we go below 5
fingers again.
And if we overflow, we can skip the unhovering of touch points since we a)
have a decent touchpad that gives us real touchpoints and b) hovering isn't
supported for 5 touches anyway.
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>
A switch from BTN_TOOL_FINGER to BTN_TOOL_DOUBLETAP sets the former to 0, then
the latter to 1, within the same frame. In the previous code we'd end the
first touchpoint, then start two new ones immediately after when the DOUBLETAP
comes in. This causes bug notices in the edge scrolling code and finger
miscounts in the tapping code (since neither processes the change, there is no
SYN_REPORT between the two).
Only update the state bits when we get the events, handle the fake touch
sequence start/end on SYN_REPORT instead.
https://bugs.freedesktop.org/show_bug.cgi?id=89949
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Change vector_get_direction input to a normalized_coords type rather than
passing in a separate x,y pair, and rename it normalized_get_direction to
match. Since it now depends on the normalized_coords type which gets declared
in libinput-private.h also move it to libinput-private.h .
Note this commit also contains a functional change wrt the get_direction
usuage in the palm detection. The palm-detection code was calling get_direction
on non normalized coordinates, this commits changes the code to normalize
the coordinates first. This is the right thing to do as calling get_direction
on non normalized coordinates may result in a wrong direction getting returned
when the x and y resolution of the touchpad are not identical.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
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>
Add a normalized_is_zero helper function, and use it where applicable.
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 reverts commit 0e64837f30.
Rather than a customized touchpad property, let udev handle this and set the
absinfo struct during the normal setup procedures. No need for libinput to
have a custom workaround here.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This reverts commit d101d43dd0.
This commit was accidentally merged, it was sitting on top of the wip branch.
With the 0e64837f30 commit this isn't necessary
anymore.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
A large range of the Apple touchpads seem to have the same dimensions. Use
that fact to force-set a resolution.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Not all touchpad kernel drivers supply the x/y resolution. Let the udev hwdb
fix this up where possible and read the value from it.
This is intentionally only used on touchpads, touchscreen devices without
resolution should be considered buggy and fixed in the kernel.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
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>
The struct evdev_device's absinfo_x/y point to the right axis
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
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>
If a tool is in proximity when we init, send a proximity event immediately.
This is only partially reliable due to the current kernel behavior:
* if the tool comes into proximity when there is no evdev client, the device
won't send any events and must be lifted out-of-proximity first. Patch is in
the works, see https://patchwork.kernel.org/patch/5924611/
* before 3.19, if the tool was in proximity (with an evdev client attached),
but goes out of proximity and back in with no client connected, we get an
immediate proximity out event from the kernel once we connect to the device
and no further events after that.
See kernel commit b905811a49bcd6e6726ce5bbb591f57aaddfd3be
Otherwise, things work as expected. The above should be fixed in the kernel
anyway.
Note that this changes the order of events during a udev seat init, before we
had all DEVICE_ADDED events in a row, now the proximity event may be
interspersed.
Reported-by: Jason Gerecke <killertofu@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Benjamin Tissoires <benjamin.tissoires@gmail.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>
Add a tp_get_average_touches_delta helper function, and rename
tp_get_active_touches_delta to tp_get_combined_touches_delta to better
differentiate the two.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Not only stop 2fg scrolling, but also edge scrolling when the trackpoint
becomes active.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
With the upcoming gesture support 2fg scrolling will be handled as part of
the main gesture state machine, whereas edge scrolling has its own state
machine, our current way of dispatching scroll "actions" does not play well
with this.
Change the scroll method handling to treat edge and 2fg scrolling as 2
separate state machines. The double scroll calls this introduces will mostly
be removed when the gesture handling code lands.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Don't rely on a magic version tag, instead let a device define a udev rule and
drop that into the udev runtime directory before the device is created.
There are a couple of caveats with this approach: first, since this changes
system-wide state it may cause issues on the device the test suite is run on.
This can be avoided if the udev rules have filter patterns that ensure only
test devices are affected.
Second, the check test suite aborts but it doesn't run the teardown() function
if a test fails. So far this wasn't a problem since uinput devices disappear
whenever we exit. The rules files will hang around though, so an unchecked
fixture was added to delete all litest-foo.rules files before and after a test
case starts. Unchecked fixtures are run regardless of the exit status of the
test but run in the same address space - i.e. no ck_assert() usage.
Also unchecked fixtures are only run once per test-case, not once per test
function. For us, that means they're only run once per device (we use the
devices as test case), i.e. if a test fails and the udev rule isn't tidied up,
the next test may be unpredictable. This shouldn't matter too much though.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
The laptops on this series have the physical trackpoint buttons back but
wired them up to the touchpad instead of the trackpoint device and they appear
as BTN_0, BTN_1 and BTN_2 for left, right, middle.
The udev hwdb marks these for us with the TOUCHPAD_HAS_TRACKPOINT_BUTTONS tag
[1]. Use that tag to identify them and re-route the events through the
trackstick device after mangling the event codes to represent the actual
buttons.
[1] http://cgit.freedesktop.org/systemd/systemd/tree/hwdb/70-touchpad.hwdb
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
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>
Allow the center of pinned fingers to drift over time, to avoid accidentally
unpinning fingers.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=86807
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>
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>
BTN_TOOL_FINGER, DOUBLETAP, etc. are mutually exclusive in the kernel, so we
can use ffs here instead of manually counting.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
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>
Some devices require more than just flipping around the buttons, such as
tablets.
When it comes to devices like tablets, because the position of the palm rest is
on the right, the entire tablet has to be flipped around in order to be usable
by lefties. As such, this requires that we reverse the coordinates of the
tablets in addition to flipping the buttons on the tablet. As such, renaming
these functions so that they aren't specific to devices where only the buttons
are flipped seems appropriate.
Signed-off-by: Stephen Chandler Paul <thatslyude@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
For a caller to implement/provide kinetic scrolling ("inertial scrolling",
"fling scrolling"), it needs to know how the scrolling motion was implemented,
and what to expect in the future. Add this information to the pointer axis
event.
The three scroll sources we have are:
* wheels: scrolling is in discreet steps, you don't know when it ends, the
wheel will just stop sending events
* fingers: scrolling is continuous coordinate space, we know when it stops and
we can tell the caller
* continuous: scrolling is in continuous coordinate space but we may or may not
know when it stops. if scroll lock is used, the device may never technically
get out of scroll mode even if it doesn't send events at any given moment
Use case: trackpoint/trackball scroll emulation on button press
The stop event is now codified in the API documentation, so callers can use
that for kinetic scrolling. libinput does not implement kinetic scrolling
itself.
Not covered by this patch:
* The wheel event is currently defined as "typical mouse wheel step", this is
different to Qt where the step value is 1/8 of a degree. Some better
definition here may help.
* It is unclear how an absolute device would map into relative motion if the
device itself is not controlling absolute motion.
* For diagonal scrolling, the vertical/horizontal terminator events would come
in separately. The caller would have to deal with that somehow.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Original patch, before the rebase onto today's master:
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>