From 32ff26329449535261ce027a3ef199718b3d5fb3 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Sun, 14 Aug 2022 21:19:19 +0200 Subject: [PATCH] Input: Don't insert duplicate references to the event list Some drivers can bundle the same slot multiple times in the same input frame. We were only correctly coalescing *consecutive* slots, but some drivers can do that in non-consecutive sequences (e.g., 1a -> 2a -> 1b -> 2b), so, handle that, too. Seen on neonode v2 grids. --- frontend/device/gesturedetector.lua | 7 ++----- frontend/device/input.lua | 24 ++++++++++++++++++++---- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/frontend/device/gesturedetector.lua b/frontend/device/gesturedetector.lua index 99cc83cbe..ad5a9511f 100644 --- a/frontend/device/gesturedetector.lua +++ b/frontend/device/gesturedetector.lua @@ -128,11 +128,8 @@ Feeds touch events to state machine. For drivers that bundle multiple slots in the same input frame, events are consumed in LIFO order, because of table.remove ;). -Note that, in a single input frame, if the same slot gets multiple *consecutive* events, -only the last one is kept. On the other hand, if the slot *changes* after SYN_MT_REPORT, -they are *both* kept: i.e., for a sequence (where the number is the slot, and the letter is the order) -1a -> 1b -> 2a in an input frame, what's processed by this function ends up being 2a -> 1b; -but for 1a -> 2a -> 1b -> 2b, it's 2b -> 1b -> 2a -> 1a ;). +Note that, in a single input frame, if the same slot gets multiple events, +only the last one is kept. --]] function GestureDetector:feedEvent(tevs) repeat diff --git a/frontend/device/input.lua b/frontend/device/input.lua index 9c57cf633..89aae9464 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -199,6 +199,7 @@ local Input = { main_finger_slot = 0, cur_slot = 0, MTSlots = nil, -- table, object may be replaced at runtime + active_slots = nil, -- ditto ev_slots = nil, -- table gesture_detector = nil, @@ -227,6 +228,7 @@ function Input:init() -- NOTE: Both of these arrays may be destroyed & recreated at runtime, so we don't want a parent/class object for those. self.timer_callbacks = {} self.MTSlots = {} + self.active_slots = {} -- Handle default finger slot self.cur_slot = self.main_finger_slot @@ -741,7 +743,7 @@ function Input:handleTouchEv(ev) end -- feed ev in all slots to state machine local touch_ges = self.gesture_detector:feedEvent(self.MTSlots) - self.MTSlots = {} + self:newFrame() if touch_ges then self:gestureAdjustHook(touch_ges) return Event:new("Gesture", @@ -800,7 +802,7 @@ function Input:handleTouchEvPhoenix(ev) end -- feed ev in all slots to state machine local touch_ges = self.gesture_detector:feedEvent(self.MTSlots) - self.MTSlots = {} + self:newFrame() if touch_ges then self:gestureAdjustHook(touch_ges) return Event:new("Gesture", @@ -836,7 +838,7 @@ function Input:handleTouchEvLegacy(ev) -- feed ev in all slots to state machine local touch_ges = self.gesture_detector:feedEvent(self.MTSlots) - self.MTSlots = {} + self:newFrame() if touch_ges then self:gestureAdjustHook(touch_ges) return Event:new("Gesture", @@ -1013,15 +1015,29 @@ function Input:getCurrentMtSlotData(key) return nil end +function Input:newFrame() + -- Array of references to the data for each slot seen in this input frame + -- (Points to self.ev_slots, c.f., getMtSlot) + self.MTSlots = {} + -- Simple hash to keep track of which references we've inserted into self.MTSlots (keys are slot numbers) + self.active_slots = {} +end + function Input:addSlot(value) self:initMtSlot(value) table.insert(self.MTSlots, self:getMtSlot(value)) + self.active_slots[value] = true self.cur_slot = value end function Input:addSlotIfChanged(value) if self.cur_slot ~= value then - self:addSlot(value) + -- We've already seen that slot in this frame, don't insert a duplicate reference! + if self.active_slots[value] then + self.cur_slot = value + else + self:addSlot(value) + end end end