New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[fix] GestureDetector: add PANINTERVAL #4666
Conversation
This properly fixes the long-standing complaint that swiping to open the menu could unintentionally trigger some light panning. With the introduction of multiswipes, this problem has become more noticeable.
Thanks LuaCheck! :-D
I never witnessed that issue about pan & swipe for menu - mostly because I tap for menu, and i mostly read cre where there is no scroll/pan of content :) So, I just tested some bit I worked on that deal with pan: MovableContainer, which seems broken after this change. I can witness it with a QuickDictLookup or SkimTo widget. Giving you what I do and how it is supposed to work so you can reproduce it:
1 and 2 are ok after your change. But 3 doesn't move at all. MovableContainer is tricky, and use intermediate events, and some intermediate states for missing events.
Not sure what's missing (no real time to investigate Oh, TextEditor supports pan too. And it's also broken. Might be a lot easier to debug :) |
Thanks!
Feedback about it has been quite persistent. ;-)
Huh, I had no idea. That's interesting. I'm not really seeing much a difference though. It would seem you have to hold it for a split second at the start and end of your movement with or without this change. However, the timeout increases the initial delay by… 300 ms, I imagine.
I'm afraid I'm not following any of this. :-) I can't spot any difference between v2019.2 and current master or master + this commit. How about something like this: if (tv_diff.sec == 0) and (tv_diff.usec < self.PAN_INTERVAL) then
pan_ev.relative_delayed.x = tev.x - self.first_tevs[slot].x
pan_ev.relative_delayed.y = tev.y - self.first_tevs[slot].y
end And then ReaderPaging/ReaderRolling: function ReaderPaging:onPan(_, ges)
if self.bookmark_flipping_mode then
return true
elseif self.page_flipping_mode then
if self.view.zoom_mode == "page" then
self:pageFlipping(self.flipping_page, ges)
else
-- switch to delayed
self.view:PanningStart(-ges.relative.x, -ges.relative.y)
end
elseif ges.direction == "north" or ges.direction == "south" then
self:onPanningRel(self.last_pan_relative_y - ges.relative.y)
self.last_pan_relative_y = ges.relative.y
end
return true
end So that it's like a hidden second type of pan. |
Ah, didn't see that we would get:
which let a very small 200ms to get into pan so that may be the reason MovableContainer and TextEditor didn't work as expected.
I was talking about the feature that #4145 introduced (probably better described there :)
I'm not really familiar with this gesture code and workings. |
Not necessarily only ReaderPaging/Rolling, but indeed I don't think there are currently other contexts where pan and swipe interact problematically. |
@poire-z This minor adaptation makes the changes only apply in the reader context. |
Quickly tested that everything that didn't work with the previous version now works correctly with the latest. (If I had to have a go at it, I would probably have tried adding a handler for onPan in readermenu, or onSwipe in readerpaging, and put into some first one triggered a |
That could make sense. I approached this as a generic pan problem. The ReaderPaging/Rolling workaround idea came much later. On the flip side, ReaderPaging/Rolling only listens to onPan, which has no concept akin to |
That's for ReaderRolling. I wasn't going to make it distance_delayed etc. just yet because I at the very least need to sleep on this first anyway. :-) |
It's always negative until it reaches a second, after which TimeVal doesn't know how to deal with the concept of a negative timeval.
@@ -195,7 +196,7 @@ end | |||
|
|||
function GestureDetector:isSwipe(slot) | |||
if not self.first_tevs[slot] or not self.last_tevs[slot] then return end | |||
local tv_diff = self.first_tevs[slot].timev - self.last_tevs[slot].timev | |||
local tv_diff = self.last_tevs[slot].timev - self.first_tevs[slot].timev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@poire-z I suspect this was never noticed because 900 ms and 1000 ms is practically the same thing anyway. But I copied it without fully engaging my brain (seeing how it's properly functioning code that does what I want) and, well, the delay sure seemed awful long with no apparent difference between 100, 200, 300, etc…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a specific point to negative values? We could guard against it:
diff --git a/frontend/ui/timeval.lua b/frontend/ui/timeval.lua
index 1c4cb171..4394f6dd 100644
--- a/frontend/ui/timeval.lua
+++ b/frontend/ui/timeval.lua
@@ -13,6 +13,7 @@ A simple module to module to compare and do arithmetic with time values.
local tv_duration_seconds_float = tv_duration.sec + tv_duration.usec/1000000
]]
+local dbg = require("dbg")
local util = require("ffi/util")
--[[--
@@ -110,6 +111,12 @@ function TimeVal:__sub(time_b)
return diff
end
+dbg:guard(TimeVal, '__sub',
+ function(self, time_b)
+ assert(self.sec > time_b.sec or (self.sec == time_b.sec and self.usec >= time_b.usec),
+ "Subtract the first timeval from the latest, not vice versa.")
+ end)
+
function TimeVal:__add(time_b)
local sum = TimeVal:new{}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, ok (I read the other issue before this one). Well, so a bug there. Dunno if it's really worth imposing TimeVal to warn (surely not to error) when this kind of bug happen.
But I guess we'll quickly see if there a other cases that reularly or not do negative substractions with a warn.
@poire-z I think it's ready now. Could you take another look please? |
MovableContainer and TextEditor do work fine now. I quickly tested ReaderRolling in scroll mode - and it looks a bit less smooth, or slower -might be that initial delay. But I don't know much about how it should behave. What I usually do for testing (mostly on Android) is hold and swipe north and south and north while still holding, and it does some kind of continuous scrolling... (bug or feature, I don't know). Also, after I had reverted 4666.diff, with the above hold-swipe-up-down-up-down-release, when releasing that hold, I get this crash:
So, good if that's what you had been fixing with the TimeVal fix. |
Right, that's the intent. Without the delay you get a lot of at best distracting panning going on. There are other ways to avoid that problem that could be investigated (e.g., designate a pan area and a multiswipe area). I'll merge it then. :-)
Definitely a bug I'd say. It might be a feature if it limited itself to half a second or at most a second. |
Avoids a crash otherwise caused by koreader#4666.
Not actually delayed. Avoids a crash otherwise caused by #4666.
When multiswipes are enabled, this fixes the long-standing complaint that swiping to open the menu could unintentionally trigger some light panning. With the introduction of multiswipes, this problem has become more noticeable.
Not actually delayed. Avoids a crash otherwise caused by koreader#4666.
Related to one of my comment above: https://www.mobileread.com/forums/showthread.php?t=337727
I think the user is talking about what I wrote above:
I do think this scrolling behaviour is really different from other Android apps - but I kinda appreciate it a lot (not that I really use it, but it's quite a powerful way to scroll/skim the whole document). It feels like some old feature of Synaptics/Elan touchpads: chiramotion/circular scrolling, allowing one to scroll large distances without having to lift your finger(s) to reposition and scroll again in the same direction. I guess this user's issue is that, he scrolls, stops scrolling while still hold'ing - then start scrolling again. There, he would like to scroll by the new distance/velocity from the stop position. I think we will start scrolling again, but with a velocity/acceleration computed from the distance from the initial hold. If this would be fixed to behave in a normal way, I'd like the current behaviour to still be available as an option, because it's super efficient ! |
I have absolutely no interest in touching it in any case. ;-) |
This properly fixes the long-standing complaint that swiping to open
the menu could unintentionally trigger some light panning. With the
introduction of multiswipes, this problem has become more noticeable.