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>
This commit is contained in:
Johan Klokkhammer Helsing 2018-10-10 12:36:17 +02:00 committed by Johan Helsing
parent f2f040ae1c
commit 02a2144427
2 changed files with 18 additions and 6 deletions

View File

@ -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);

View File

@ -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"