The POSIX version of basename modifies the string (and therefore crashes
on static strings), so use safe_strdup before calling it.
glibc provides a POSIX version when libgen.h is included.
FreeBSD 12 provides a POSIX version when nothing is included, which was
causing a segfault.
Using the POSIX version correctly is the right way to avoid any such issues.
If a 2fg scroll motion starts with both fingers in the bottom button area and
one finger moves into the main area before the other, we used to send motion
events for that finger. Once the second finger moved into the main area the
scroll was detected correctly but by then the cursor may have moved out of the
intended focus area.
We have two transitions where we may start sending motion events: when we move
out of the bottom area and when the finger moves by more than 5mm within the
button area. In both cases, check for any touches that are in the
bottom area and started at the 'same' time as our moving touch. Mark those as
'moved' to release them for gestures so we get the right finger count and
axis/gesture events instead of just motion events.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
There's one state with a name longer than allocated but it's virtually never
triggered so let's just ignore the misalignment in that case.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The shape of the average hand implies that two fingers down within the lower
thumb area (the bottom few mm of the touchpad) cannot be thumbs without
significant contortion. So let's not mark them as thumb.
Fixes#126
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
tp_detect_thumb_while_moving() assumes that of the 2 fingers down, at least
one must be in TOUCH_UPDATE, otherwise we wouldn't have a speed to analyze for
thumb.
If a touch starts in HOVERING and exceeds the speed limit, we were previously
increasing the 'exceeded count'. This later leads to an assert() in
tp_detect_thumb_while_moving() when the second finger comes down because
although we have multiple fingers, none of them are in TOUCH_UPDATE.
This only happens when fingers 2 and 3 come down in the same event frame,
because then we have nfingers_down at 2 (the hovering one doesn't count) but
we don't yet have a finger in TOUCH_UPDATE.
Fix this twofold, first by now calculating the speed on anything but
TOUCH_UPDATE. And second by force-resetting the speed count on
TOUCH_BEGIN/TOUCH_END so we definitely cover all the hover transitions.
Fixes#150
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
When we disable the touch device, any existing touches should be cancelled,
not just released.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This touchpad stops sending pressure data after the first frame of the second
finger down. If the initial pressure is too light, the finger doesn't get
detected even when the pressure increases in the future.
This thing is from 2014, so let's just disable the pressure axes on it
and skip the pressure-based touch detection code. Let's hope that it doesn't
also have ghost touches on light interactions...
Fixes#145
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Anything that merely requires a once-off check during initialization can just
use the quirks directly, no need to copy them over to the model flags.
Fixes#146
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The previous check only worked if sizeof(long) > sizeof(int). Rather than be
fancy about it, just cast to a signed long, check for negativity and continue
based on that.
Fixes#137
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
We may get a pointer jump on tip down/up, see #128. For absolute coordinates
we reset the history to avoid smoothing across that jump but deltas still used
to be calculated based on the previous position to the current one. This
can result in a large jump on tip down.
Since the delta is supposed to be useful (and not physically accurate, see the
docs), let's force it to 0/0 on tip down/up to avoid that scenario.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Because we're doing axis smoothing, we may get a nonzero delta between events
even when the real axis hasn't updated. Make sure the bit is set in this case.
One part of #128
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
On Dell i2c touchpads, the controller appears to go to sleep after about 1s of
inactivity on the touchpad. The wakeup takes a while so on the next touch, we
may see a pointer jump, specifially on the third event (i.e. touch down,
event, event+jump). The MSC_TIMESTAMP value carries a hint for what's
happening here, the event sequence for a touchpad with scanout intervals
7300µs is:
...
MSC_TIMESTAMP 0
SYN_REPORT
...
MSC_TIMESTAMP 7300
SYN_REPORT +2ms
...
MSC_TIMESTAMP 123456
SYN_REPORT +7ms
...
MSC_TIMESTAMP 123456+7300
SYN_REPORT +8ms
Note how the SYN_REPORT timestamps don't reflect the MSC_TIMESTAMPS.
This patch adds a quirk activate MSC_TIMESTAMP watching. When we do so, we
monitor for a 0 MSC_TIMESTAMP. Let's assume that the first event after that is
the interval, then check the third event. If that third event's timestamp is too
large rewrite the touches' motion history to reflect the correct timestamps,
i.e. instead of the SYN_REPORT timestamps the motion history now uses
"third-event SYN_REPORT timestamps minus MSC_TIMESTAMP values".
The pointer accel filter code uses absolute timestamps (#123) so we have to
restart the pointer acceleration filter when we detect this jump. This allows
us to reset the 0 time for the filter to the previous event's MSC_TIMESTAMP
time, so that our new large delta has the correct time delta too. This
calculates the acceleration correctly for that window.
The result is that the pointer is still delayed by the wake-up window (not
fixable in libinput) but at least it ends up where it should've.
There are a few side-effects: thumb, gesture, and hysteresis all still use the
unmodified SYN_REPORT time. There is a potential for false detection of either
of these now, but we'll have to fix those as they come up.
Fixes#36
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This function expected distances per-frame, not per-time which gives us
different behaviors depending on the hardware scanout rate. Fix this by
normalizing to a 12ms frame rate which reflects the touchpad I measured all
the existing thresholds on.
This is a bit of a problem for the test suite which doesn't use proper
intervals and the change to do so is rather invasive. So for now we set the
interval for test devices to whatever the time delta is so we can test the
jumps without having to worry about intervals.
Fixes#121
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
In testing on an Apple Magic Trackpad, thumb touches are reliably
detected by being quite large in the major dimension, but around
half the size in the minor dimension.
Use a boolean for whether we need to use it and drop the unneded absinfo
assignment (together with the goto).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
We already had a check to only pair trackpoints and internal keyboards
but for the ThinkPad Compact Bluetooth Keyboard with TrackPoint that isn't
sufficient - it's an external keyboard that contains a trackpoint. Explicitly
ignore external keyboard, we never want to shut those down in tablet mode
anyway.
Fixes#119
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
libinput applies averaging to the velocity of most pointer devices. Averaging
the velocity makes the motion look smooth and may be of benefit to bad input
devices. For good devices, however, it comes at the unfortunate price of
decreased accuaracy.
This change turns velocity averaging off by default (sets ntrackers to 2 instead
of 16) and allows for it to be turned back on via a quirk, for bad devices which
require it.
Previously, we had a hard threshold of 20mm per event frame. That is just
about achievable by really fast movements (in which case you don't care too
much about the jumps anyway because you've already hit the edge of the screen).
Sometimes pointer jumps have lower deltas that are achievable even on slower,
more likely motions. Analysis of finger motion has shown that while a delta
>7mm per event is possible, jumping _by_ 7mm between two events is unlikely
and indicates a pointer jump. So let's diff the most recent delta and the
current delta, if it increases by 7mm between two event frames let's say it's
a pointer jump and discard it.
Helps with but does not fully resolve:
https://gitlab.freedesktop.org/libinput/libinput/issues/80https://gitlab.freedesktop.org/libinput/libinput/issues/36
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
No functional changes, anything that's in the top/bottom area but not in the
respective middle/right area is a left button.
Introduced by 13bda5adcb
Fixes coverity complaint about use of uninitialized variable.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The software button area is currently a partially-dead area. If the finger
moves into or out of the area pointer motion works. Finger motion within the
area however does not generate motion.
The main motivation for this was to avoid accidental pointer motion when a
button is pressed. This is required for stationary fingers but once you move a
significant distance, those bets are off.
So if the finger moves by more than 5mm from where it was put down, release it
and let it move the pointer.
The full impact is largely limited to horizontal movements within the button
area because:
- leaving the finger at the bottom area for 300ms without movement triggers
the thumb identification, so it won't move anyway.
- moving the finger north is likely to go off the button area before we
trigger this threshold.
https://gitlab.freedesktop.org/libinput/libinput/issues/86
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
At least not opening single quotes, same as the double quotes we already have.
Add the tests for both.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
We don't have a sensible use case where we want hex to double, or INF to
double, or any of that. So check the strings for invalid characters and bail
out early. Invalid characters include 'e' and whitespaces too, we don't need
those.
Small chance of things breaking: if the user-exposed calibration matrix
property was specified using hex numbers this will stop working now. I'll take
that risk.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This makes two-finger scrolling in straight lines easier, while still
allowing free/diagonal movement. It works in three stages:
1) Initial movement
- For the first few millimeters, scroll movements within 30 degrees
of horizontal or vertical are straightened to 90-degree angles.
- Scroll movements close to 45 degree diagonals are unchanged.
- If movement continues very close to straight horizontal or
vertical, stage 2 begins and the axis lock engages.
- If movement continues along a diagonal, stage 2 is skipped and
free scrolling is immediately enabled.
2) Axis lock
- If the user scrolls fairly closely to straight vertical, no
horizontal movement will happen at all, and vice versa.
- It is possible to switch between straight vertical and straight
horizontal, and the axis lock will automatically change.
- If deliberate diagonal movement is detected at any point, stage
3 begins and the axis lock disengages.
3) Free scrolling
- Scrolling is unconstrained until the fingers are lifted.
Use the same blurb everywhere, changing from the old style MIT to the Expat
license we're using everywhere else.
Similar to bc9f16b40e
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
If the trackpoint gives us deltas with less than 10ms intervals, something is
wrong. Could be bad hardware, a glitch in the matrix or a discontinuity in
the otherwise appropriately named time-space continuum. Usually it's the
first.
Let's always set up trackpoint delta smoothening for 10ms to improve the
pointer speed calculation and avoid jerky behaviors. i.e. if a trackpoint
delta comes in below 10ms, pretend it came in with a 10ms interval for
calculating the speed.
Fixes https://gitlab.freedesktop.org/libinput/libinput/issues/104
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
A three-finger touch may cause slot N to end, in a frame after the
BTN_TOOL_TRIPLETAP. This causes tp->nfinger_down to be decremented to 2 as the
touch switches to MAYBE_END - which happens to be our num_slots. We exit early
and never restore the touch correctly.
Fix this by checking that the number of fake touches is equal to the slots, if
it is higher then we need to check for recovery.
Fixes https://gitlab.freedesktop.org/libinput/libinput/issues/99
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This used to do a lot more but now it can be handled as simple switch
statement. Bonus: we get to log a bug if we ever get here in NONE state.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>