From 17fa07ee43ed71ae9d1d9ca84c3e9a9f622f1305 Mon Sep 17 00:00:00 2001 From: Frans de Jonge Date: Mon, 4 Mar 2019 19:01:01 +0100 Subject: [PATCH] [fix] GestureDetector: deep copies of events for multiswipes when rotated (#4728) Fixes #4724. --- frontend/device/gesturedetector.lua | 16 +++++++++++++--- frontend/util.lua | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/frontend/device/gesturedetector.lua b/frontend/device/gesturedetector.lua index 40e6ab4fc..a01feb994 100644 --- a/frontend/device/gesturedetector.lua +++ b/frontend/device/gesturedetector.lua @@ -45,6 +45,7 @@ detection result when you feed a touch release event to it. local Geom = require("ui/geometry") local TimeVal = require("ui/timeval") local logger = require("logger") +local util = require("util") local GestureDetector = { -- must be initialized with the Input singleton class @@ -556,16 +557,22 @@ function GestureDetector:handlePan(tev) end if msd_distance > self.MULTISWIPE_THRESHOLD then + local pan_ev_multiswipe = pan_ev + -- store a copy of pan_ev without rotation adjustment + -- for multiswipe calculations when rotated + if self.screen.cur_rotation_mode > 0 then + pan_ev_multiswipe = util.tableDeepCopy(pan_ev) + end if msd_direction ~= msd_direction_prev then self.multiswipe_directions[msd_cnt+1] = { [1] = msd_direction, - [2] = pan_ev, + [2] = pan_ev_multiswipe, } -- update ongoing swipe direction to the new maximum else self.multiswipe_directions[msd_cnt] = { [1] = msd_direction, - [2] = pan_ev, + [2] = pan_ev_multiswipe, } end end @@ -729,7 +736,7 @@ local function translateGesDirCoordinate(direction, translation_table) return translation_table[direction] end local function translateMultiswipeGesDirCoordinate(multiswipe_directions, translation_table) - return multiswipe_directions:gsub(multiswipe_directions, translation_table) + return multiswipe_directions:gsub("%S+", translation_table) end --[[-- @@ -755,6 +762,7 @@ function GestureDetector:adjustGesCoordinate(ges) end if ges.relative then ges.relative.x, ges.relative.y = -ges.relative.y, ges.relative.x + ges.relative_delayed.x, ges.relative_delayed.y = -ges.relative_delayed.y, ges.relative_delayed.x end elseif ges.ges == "pinch" or ges.ges == "spread" or ges.ges == "inward_pan" @@ -781,6 +789,7 @@ function GestureDetector:adjustGesCoordinate(ges) end if ges.relative then ges.relative.x, ges.relative.y = ges.relative.y, -ges.relative.x + ges.relative_delayed.x, ges.relative_delayed.y = ges.relative_delayed.y, -ges.relative_delayed.x end elseif ges.ges == "pinch" or ges.ges == "spread" or ges.ges == "inward_pan" @@ -807,6 +816,7 @@ function GestureDetector:adjustGesCoordinate(ges) end if ges.relative then ges.relative.x, ges.relative.y = -ges.relative.x, -ges.relative.y + ges.relative_delayed.x, ges.relative_delayed.y = -ges.relative_delayed.x, -ges.relative_delayed.y end elseif ges.ges == "pinch" or ges.ges == "spread" or ges.ges == "inward_pan" diff --git a/frontend/util.lua b/frontend/util.lua index c4e71131a..45af8f183 100644 --- a/frontend/util.lua +++ b/frontend/util.lua @@ -139,6 +139,33 @@ function util.tableEquals(o1, o2, ignore_mt) return true end +--[[-- +Makes a deep copy of a table. + +Source: https://stackoverflow.com/a/16077650/2470572 +]] +---- @param o Lua table +---- @treturn Lua table +function util.tableDeepCopy(o, seen) + seen = seen or {} + if o == nil then return nil end + if seen[o] then return seen[o] end + + local no + if type(o) == "table" then + no = {} + seen[o] = no + + for k, v in next, o, nil do + no[util.tableDeepCopy(k, seen)] = util.tableDeepCopy(v, seen) + end + setmetatable(no, util.tableDeepCopy(getmetatable(o), seen)) + else -- number, string, boolean, etc + no = o + end + return no +end + --- Returns number of keys in a table. ---- @param t Lua table ---- @treturn int number of keys in table t