From 8ae95b29c8ce5511cc8368e0fd891ea5a2605eee Mon Sep 17 00:00:00 2001 From: Alex Rosca Date: Fri, 20 Nov 2020 17:54:07 +0000 Subject: [PATCH 1/2] Avoid unintentional accelerating flicks by reducing maximum flick time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When making a flick using the mouse or the touchscreen and then slowly dragging the pages in the same direction with the flick, it unintentionally reenters the flicking state after a mouse button release and it's quite annoying. The commit reduces the maximum time before the next flick. Steps to reproduce: 1) Flick in direction A. 2) While the view is coasting, decide that you want to stop close to the current position. 3) Grab the view (still coasting), and drag it slowly in direction A. 4) When you reached the desired point, stop your movement, and release the view. 5) QScroller interprets this release as “accelerating flick”, and makes the view coast faster in direction A. Upstream bug is QTBUG-88249; QScroller ignores MinimumVelocity for accelerating flicks. --- part/pageview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/part/pageview.cpp b/part/pageview.cpp index 91754558b..0e5a860ac 100644 --- a/part/pageview.cpp +++ b/part/pageview.cpp @@ -429,6 +429,7 @@ PageView::PageView(QWidget *parent, Okular::Document *document) QScrollerProperties prop; prop.setScrollMetric(QScrollerProperties::DecelerationFactor, 0.3); prop.setScrollMetric(QScrollerProperties::MaximumVelocity, 1); + prop.setScrollMetric(QScrollerProperties::AcceleratingFlickMaximumTime, 0.2); // Workaround for QTBUG-88249 (non-flick gestures recognized as accelerating flick) prop.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); prop.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); prop.setScrollMetric(QScrollerProperties::DragStartDistance, 0.0); From c6a3275151ffa5c9045c8186b64e45e4b2c3ccbf Mon Sep 17 00:00:00 2001 From: David Hurka Date: Sun, 8 Nov 2020 13:14:22 +0100 Subject: [PATCH 2/2] Fix QScroller crash on Qt < 5.14 and certain screen arrangements QScrollerPrivate::setDpiFromWidget() before Qt 5.14 crashes when the target widget does not intersect a physical screen, because QDesktopWidget returns screen index `-1` in this case, which leads to an out-of-range read from QApplication::screens(), which leads to a segfault when reading from an invalid QScreen* pointer. This adds a workaround that checks for the `-1` situation, and then tries to resize PageView temporarily to intersect at least some screen. BUG: 425188 FIXED-IN: 20.12 --- part/pageview.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/part/pageview.cpp b/part/pageview.cpp index 0e5a860ac..a33ef47b2 100644 --- a/part/pageview.cpp +++ b/part/pageview.cpp @@ -4041,6 +4041,21 @@ void PageView::center(int cx, int cy, bool smoothMove) void PageView::scrollTo(int x, int y, bool smoothMove) { +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + // Workaround for QTBUG-88288, (KDE bug 425188): To avoid a crash in QScroller, + // we need to make sure the target widget intersects a physical screen. + // QScroller queries QDesktopWidget::screenNumber(). + + // If we are not on a physical screen, we try to make our widget big enough. + // The geometry will be restored to a sensible value once the Part is shown. + + // It should be enough to add this workaround ony in PageView::scrollTo(), + // because we don’t expect other QScroller::scrollTo() calls before PageView is shown. + if (QApplication::desktop()->screenNumber(this) < 0) { + setGeometry(QRect(-1000, -1000, 5000, 5000).united(QApplication::desktop()->availableGeometry())); + } +#endif + bool prevState = d->blockPixmapsRequest; int newValue = -1;