Reset stale touchpad contacts after interrupted input
This commit is contained in:
@@ -153,13 +153,18 @@ local function emit_action()
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function reset_if_clear(state)
|
local function reset_contacts(state)
|
||||||
if contact_count(state, false) == 0 then
|
|
||||||
state.mode = "idle"
|
state.mode = "idle"
|
||||||
|
state.contacts = {}
|
||||||
state.anchor_slot = nil
|
state.anchor_slot = nil
|
||||||
state.candidate_slot = nil
|
state.candidate_slot = nil
|
||||||
state.candidate_anchor_x = nil
|
state.candidate_anchor_x = nil
|
||||||
state.candidate_anchor_y = nil
|
state.candidate_anchor_y = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function reset_if_clear(state)
|
||||||
|
if contact_count(state, false) == 0 then
|
||||||
|
reset_contacts(state)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -178,6 +183,12 @@ local function new_contact(state, slot, tracking_id, timestamp)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function handle_tracking_begin(device, state, tracking_id, timestamp)
|
local function handle_tracking_begin(device, state, tracking_id, timestamp)
|
||||||
|
if state.contacts[state.source_slot] then
|
||||||
|
libinput:log_debug(
|
||||||
|
"touchpad-hold-tap: resetting stale contact state")
|
||||||
|
reset_contacts(state)
|
||||||
|
end
|
||||||
|
|
||||||
if state.mode == "candidate" then
|
if state.mode == "candidate" then
|
||||||
restore_candidate(device, state, "extra contact")
|
restore_candidate(device, state, "extra contact")
|
||||||
end
|
end
|
||||||
@@ -361,6 +372,13 @@ local function handle_frame(device, frame, timestamp)
|
|||||||
else
|
else
|
||||||
modified = true
|
modified = true
|
||||||
end
|
end
|
||||||
|
elseif event.usage == evdev.BTN_TOUCH and event.value == 0 then
|
||||||
|
table.insert(output, event)
|
||||||
|
if contact_count(state, false) > 0 then
|
||||||
|
libinput:log_debug(
|
||||||
|
"touchpad-hold-tap: resetting empty touch state")
|
||||||
|
reset_contacts(state)
|
||||||
|
end
|
||||||
elseif tool_counts[event.usage] then
|
elseif tool_counts[event.usage] then
|
||||||
if state.mode == "candidate" or override_tools then
|
if state.mode == "candidate" or override_tools then
|
||||||
local desired = tool_counts[event.usage] ==
|
local desired = tool_counts[event.usage] ==
|
||||||
|
|||||||
@@ -307,6 +307,37 @@ function tests.rejected_tap_does_not_poison_anchor()
|
|||||||
up(device, 300000, 0, 0)
|
up(device, 300000, 0, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function tests.empty_touch_state_clears_stale_contacts()
|
||||||
|
local device = new_device("touchpad")
|
||||||
|
|
||||||
|
-- A suspend may interrupt the stream without individual tracking-ID
|
||||||
|
-- releases. The following no-touch report must still reset the plugin.
|
||||||
|
down(device, 0, 1, 70, 1000, 1000, 1)
|
||||||
|
feed(device, 100000, {
|
||||||
|
event(evdev.BTN_TOUCH, 0),
|
||||||
|
event(evdev.BTN_TOOL_FINGER, 0),
|
||||||
|
})
|
||||||
|
|
||||||
|
down(device, 200000, 0, 71, 1000, 1000, 1)
|
||||||
|
down(device, 400000, 1, 72, 1400, 1000, 2)
|
||||||
|
up(device, 450000, 1, 1)
|
||||||
|
assert(action_count() == 1)
|
||||||
|
up(device, 500000, 0, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.reused_slot_clears_stale_contacts()
|
||||||
|
local device = new_device("touchpad")
|
||||||
|
|
||||||
|
down(device, 0, 0, 73, 1000, 1000, 1)
|
||||||
|
-- A new tracking ID in an occupied slot also proves that the previous
|
||||||
|
-- contact disappeared without a complete event sequence.
|
||||||
|
down(device, 200000, 0, 74, 1000, 1000, 1)
|
||||||
|
down(device, 400000, 1, 75, 1400, 1000, 2)
|
||||||
|
up(device, 450000, 1, 1)
|
||||||
|
assert(action_count() == 1)
|
||||||
|
up(device, 500000, 0, 0)
|
||||||
|
end
|
||||||
|
|
||||||
function tests.tap_while_moving_does_not_poison_anchor()
|
function tests.tap_while_moving_does_not_poison_anchor()
|
||||||
if allow_moving_anchor then
|
if allow_moving_anchor then
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Name: touchpad-hold-tap
|
Name: touchpad-hold-tap
|
||||||
Version: 0.1.0
|
Version: 0.1.0
|
||||||
Release: 9%{?dist}
|
Release: 10%{?dist}
|
||||||
Summary: Hold-tap middle-click gesture for touchpads
|
Summary: Hold-tap middle-click gesture for touchpads
|
||||||
|
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -57,6 +57,9 @@ if [ "$1" -eq 0 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sat Sep 05 2026 fedora-tools contributors - 0.1.0-10
|
||||||
|
- Reset stale touch contacts after an interrupted input stream
|
||||||
|
|
||||||
* Sat Sep 05 2026 fedora-tools contributors - 0.1.0-9
|
* Sat Sep 05 2026 fedora-tools contributors - 0.1.0-9
|
||||||
- Separate minimum anchor age from the optional stationary period
|
- Separate minimum anchor age from the optional stationary period
|
||||||
- Allow a held anchor to recover after rejected taps
|
- Allow a held anchor to recover after rejected taps
|
||||||
|
|||||||
Reference in New Issue
Block a user