From daa39f84996700d2459d8e570ac1b3f2f2cdffd0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 26 Feb 2018 16:34:48 +0100 Subject: ToolTip/Windows: Fix wrong size when font is modified by widget stylesheet Factor out a function to calculate the size and update the size when a style sheet parent is set. Task-number: QTBUG-64550 Change-Id: I3afe997085eae3cd48b7fe0a4c98582a8f572260 Reviewed-by: Gabriel de Dietrich --- src/widgets/kernel/qtooltip.cpp | 12 ++++- .../auto/widgets/kernel/qtooltip/tst_qtooltip.cpp | 62 ++++++++++++++++++---- 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index 69b62ff7d7..baf717d715 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -127,6 +127,8 @@ public: ~QTipLabel(); static QTipLabel *instance; + void updateSize(); + bool eventFilter(QObject *, QEvent *) override; QBasicTimer hideTimer, expireTimer; @@ -214,13 +216,18 @@ void QTipLabel::reuseTip(const QString &text, int msecDisplayTime) setWordWrap(Qt::mightBeRichText(text)); setText(text); + updateSize(); + restartExpireTimer(msecDisplayTime); +} + +void QTipLabel::updateSize() +{ QFontMetrics fm(font()); QSize extra(1, 0); // Make it look good with the default ToolTip font on Mac, which has a small descent. if (fm.descent() == 2 && fm.ascent() >= 11) ++extra.rheight(); resize(sizeHint() + extra); - restartExpireTimer(msecDisplayTime); } void QTipLabel::paintEvent(QPaintEvent *ev) @@ -387,6 +394,9 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w) if (w) { connect(w, SIGNAL(destroyed()), QTipLabel::instance, SLOT(styleSheetParentDestroyed())); + // QTBUG-64550: A font inherited by the style sheet might change the size, + // particular on Windows, where the tip is not parented on a window. + QTipLabel::instance->updateSize(); } } #endif //QT_NO_STYLE_STYLESHEET diff --git a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp index 86736bb082..e02573f8e8 100644 --- a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp +++ b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp @@ -28,6 +28,8 @@ #include +#include +#include #include #include #include @@ -43,6 +45,7 @@ private slots: void task183679(); void whatsThis(); void setPalette(); + void qtbug64550_stylesheet(); }; void tst_QToolTip::init() @@ -53,6 +56,7 @@ void tst_QToolTip::init() void tst_QToolTip::cleanup() { QTRY_VERIFY(QApplication::topLevelWidgets().isEmpty()); + qApp->setStyleSheet(QString()); } class Widget_task183679 : public QWidget @@ -66,10 +70,12 @@ public: QTimer::singleShot(msecs, this, SLOT(showToolTip())); } + static inline QString toolTipText() { return QStringLiteral("tool tip text"); } + private slots: void showToolTip() { - QToolTip::showText(mapToGlobal(QPoint(0, 0)), "tool tip text", this); + QToolTip::showText(mapToGlobal(QPoint(0, 0)), Widget_task183679::toolTipText(), this); } }; @@ -146,6 +152,15 @@ void tst_QToolTip::whatsThis() QVERIFY2(whatsThisHeight > 100, QByteArray::number(whatsThisHeight)); // Test QTBUG-2416 } +static QWidget *findToolTip() +{ + const QWidgetList &topLevelWidgets = QApplication::topLevelWidgets(); + for (QWidget *widget : topLevelWidgets) { + if (widget->windowType() == Qt::ToolTip && widget->objectName() == QLatin1String("qtooltip_label")) + return widget; + } + return nullptr; +} void tst_QToolTip::setPalette() { @@ -156,16 +171,7 @@ void tst_QToolTip::setPalette() QTRY_VERIFY(QToolTip::isVisible()); - QWidget *toolTip = 0; - foreach (QWidget *widget, QApplication::topLevelWidgets()) { - if (widget->windowType() == Qt::ToolTip - && widget->objectName() == QLatin1String("qtooltip_label")) - { - toolTip = widget; - break; - } - } - + QWidget *toolTip = findToolTip(); QVERIFY(toolTip); QTRY_VERIFY(toolTip->isVisible()); @@ -178,5 +184,39 @@ void tst_QToolTip::setPalette() QToolTip::hideText(); } +static QByteArray msgSizeTooSmall(const QSize &actual, const QSize &expected) +{ + return QByteArray::number(actual.width()) + 'x' + + QByteArray::number(actual.height()) + " < " + + QByteArray::number(expected.width()) + 'x' + + QByteArray::number(expected.height()); +} + +// QTBUG-4550: When setting a style sheet specifying a font size on the tooltip's +// parent widget (as opposed to setting on QApplication), the tooltip should +// resize accordingly. This is an issue on Windows since the ToolTip widget is +// not directly parented on the widget itself. +// Set a large font size and verify that the tool tip is big enough. +void tst_QToolTip::qtbug64550_stylesheet() +{ + Widget_task183679 widget; + widget.setStyleSheet(QStringLiteral("* { font-size: 48pt; }\n")); + widget.show(); + QApplication::setActiveWindow(&widget); + QVERIFY(QTest::qWaitForWindowActive(&widget)); + + widget.showDelayedToolTip(100); + QTRY_VERIFY(QToolTip::isVisible()); + QWidget *toolTip = findToolTip(); + QVERIFY(toolTip); + QTRY_VERIFY(toolTip->isVisible()); + + const QRect boundingRect = QFontMetrics(widget.font()).boundingRect(Widget_task183679::toolTipText()); + const QSize toolTipSize = toolTip->size(); + QVERIFY2(toolTipSize.width() >= boundingRect.width() + && toolTipSize.height() >= boundingRect.height(), + msgSizeTooSmall(toolTipSize, boundingRect.size()).constData()); +} + QTEST_MAIN(tst_QToolTip) #include "tst_qtooltip.moc" -- cgit v1.2.3