diff options
author | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2018-10-10 12:36:17 +0200 |
---|---|---|
committer | Johan Helsing <johan.helsing@qt.io> | 2018-10-15 07:44:04 +0000 |
commit | 02a214442781bf112c1cc85d2470c6fcec8ed207 (patch) | |
tree | 1150e6a4f1b9fee7d1c29860faeddf3edbde852f | |
parent | f2f040ae1c4fe48bff68bb45b2e20308fa895c50 (diff) |
QToolTip: Don't crash if a tool tip is shown outside screen geometry
In some cases, a tool tip may be shown outside screen geometry, i.e. if:
- QToolTip::showText is invoked manually with a position outside.
- In tst_QToolTip::setPalette if there is no screen at (0, 0). This might
happen in a multi-monitor setups where one screen is taller than the other.
- On Wayland windows are (by design) not allowed to know their position on
the screen. This means that global positions can't be trusted.
This started crashing when QDesktopWidget::screenGeometry(pos) was replaced
with QGuiApplication::screenAt(pos)->geometry() because screenAt will return
null if no screen is found, while screenGeometry defaulted to the primary
screen.
This reverts to the old behavior of falling back to the primary screen.
This won't solve the issue completely for the Wayland case, but at least we
will stop crashing.
Change-Id: I42dd07cc21c2f9f0ea0d69f0c25bd46d8a2615a0
Reviewed-by: Filipe Azevedo <filipe.azevedo@kdab.com>
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
-rw-r--r-- | src/widgets/kernel/qtooltip.cpp | 17 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp | 7 |
2 files changed, 18 insertions, 6 deletions
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index 8c5573d3a3..2e6575c163 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -229,12 +229,17 @@ void QTipLabel::updateSize(const QPoint &pos) ++extra.rheight(); QSize sh = sizeHint(); if (wordWrap()) { - const QRect screenRect = QGuiApplication::screenAt(pos)->geometry(); - if (sh.width() > screenRect.width()) { - // Try to use widely accepted 75chars max length or 80% of the screen width else. - // See https://en.wikipedia.org/wiki/Line_length - sh.setWidth(qMin(fm.averageCharWidth() * 75, static_cast<int>(screenRect.width() * .8))); - sh.setHeight(heightForWidth(sh.width())); + QScreen *screen = QGuiApplication::screenAt(pos); + if (!screen) + screen = QGuiApplication::primaryScreen(); + if (screen) { + const qreal screenWidth = screen->geometry().width(); + if (sh.width() > screenWidth) { + // Try to use widely accepted 75chars max length or 80% of the screen width else. + // See https://en.wikipedia.org/wiki/Line_length + sh.setWidth(qMin(fm.averageCharWidth() * 75, static_cast<int>(screenWidth * .8))); + sh.setHeight(heightForWidth(sh.width())); + } } } resize(sh + extra); diff --git a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp index e02573f8e8..3d609d0b9c 100644 --- a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp +++ b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp @@ -46,6 +46,7 @@ private slots: void whatsThis(); void setPalette(); void qtbug64550_stylesheet(); + void dontCrashOutsideScreenGeometry(); }; void tst_QToolTip::init() @@ -218,5 +219,11 @@ void tst_QToolTip::qtbug64550_stylesheet() msgSizeTooSmall(toolTipSize, boundingRect.size()).constData()); } +void tst_QToolTip::dontCrashOutsideScreenGeometry() { + QToolTip::showText(QPoint(-10000, -10000), "tip outside monitor", nullptr); + QTRY_VERIFY(QToolTip::isVisible()); + QToolTip::hideText(); +} + QTEST_MAIN(tst_QToolTip) #include "tst_qtooltip.moc" |