From c6a3275151ffa5c9045c8186b64e45e4b2c3ccbf Mon Sep 17 00:00:00 2001 From: David Hurka Date: Sun, 8 Nov 2020 13:14:22 +0100 Subject: [PATCH] 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;