diff --git a/autotests/kmessagewidgetautotest.h b/autotests/kmessagewidgetautotest.h --- a/autotests/kmessagewidgetautotest.h +++ b/autotests/kmessagewidgetautotest.h @@ -39,6 +39,7 @@ void testOverlappingDoubleHide_data(); void testOverlappingDoubleHide(); void testHideWithNotYetShownParent(); + void testNonAnimatedShowAfterAnimatedHide(); }; #endif diff --git a/autotests/kmessagewidgetautotest.cpp b/autotests/kmessagewidgetautotest.cpp --- a/autotests/kmessagewidgetautotest.cpp +++ b/autotests/kmessagewidgetautotest.cpp @@ -29,6 +29,17 @@ // let's have 7 updates for now, should be save const int overlappingWaitingTime = 280; +#define CHECK_FULLY_VISIBLE \ + QVERIFY(w.isVisible()); \ + QCOMPARE(w.height(), w.sizeHint().height()); \ + QCOMPARE(w.findChild(QStringLiteral("contentWidget")) ->pos(), QPoint(0, 0)); + +#define CHECK_FULLY_NOT_VISIBLE \ + QCOMPARE(w.height(), 0); \ + QCOMPARE(w.findChild(QStringLiteral("contentWidget")) ->pos(), QPoint(0, -w.sizeHint().height())); \ + QVERIFY(!w.isVisible()); + + void KMessageWidgetTest::testAnimationSignals() { KMessageWidget w(QStringLiteral("Hello world")); @@ -44,63 +55,47 @@ // w.animatedShow(); - while (w.isShowAnimationRunning()) { - QCOMPARE(showSignalsSpy.count(), 0); - QTest::qWait(50); - } - - QVERIFY(! w.isShowAnimationRunning()); + QTRY_VERIFY(!w.isShowAnimationRunning()); QCOMPARE(showSignalsSpy.count(), 1); - QVERIFY(w.isVisible()); + CHECK_FULLY_VISIBLE // // test: hiding the message widget should emit hideAnimationFinished() // exactly once after the show animation is finished // w.animatedHide(); - while (w.isHideAnimationRunning()) { - QCOMPARE(hideSignalsSpy.count(), 0); - QTest::qWait(50); - } - + QTRY_VERIFY(!w.isHideAnimationRunning()); QCOMPARE(hideSignalsSpy.count(), 1); - QVERIFY(! w.isVisible()); + CHECK_FULLY_NOT_VISIBLE } void KMessageWidgetTest::testShowOnVisible() { KMessageWidget w(QStringLiteral("Hello world")); QSignalSpy showSignalsSpy(&w, &KMessageWidget::showAnimationFinished); w.show(); + CHECK_FULLY_VISIBLE // test: call show on visible w.animatedShow(); - while (w.isShowAnimationRunning()) { - QCOMPARE(showSignalsSpy.count(), 0); - QTest::qWait(50); - } - + QTRY_VERIFY(!w.isShowAnimationRunning()); QCOMPARE(showSignalsSpy.count(), 1); - QVERIFY(w.isVisible()); + CHECK_FULLY_VISIBLE } void KMessageWidgetTest::testHideOnInvisible() { KMessageWidget w(QStringLiteral("Hello world")); QSignalSpy hideSignalsSpy(&w, &KMessageWidget::hideAnimationFinished); - // test: call hide on visible + // test: call hide on invisible w.animatedHide(); - while (w.isHideAnimationRunning()) { - QCOMPARE(hideSignalsSpy.count(), 0); - QTest::qWait(50); - } - + QTRY_VERIFY(!w.isHideAnimationRunning()); QCOMPARE(hideSignalsSpy.count(), 1); - QVERIFY(! w.isVisible()); + QVERIFY(! w.isVisible()); // Not CHECK_FULLY_NOT_VISIBLE because since it was never shown height is not what it would be otherwise } void KMessageWidgetTest::testOverlappingShowAndHide_data() @@ -121,21 +116,18 @@ // test: call hide while show animation still running w.animatedShow(); + QVERIFY(w.isVisible()); // Not CHECK_FULLY_VISIBLE because we're not waiting for it to finish if (delay) { QTest::qWait(overlappingWaitingTime); } w.animatedHide(); QVERIFY(! w.isShowAnimationRunning()); QCOMPARE(showSignalsSpy.count(), 1); - while (w.isHideAnimationRunning()) { - QCOMPARE(hideSignalsSpy.count(), 0); - QTest::qWait(50); - } - + QTRY_VERIFY(!w.isHideAnimationRunning()); QCOMPARE(hideSignalsSpy.count(), 1); - QVERIFY(! w.isVisible()); + CHECK_FULLY_NOT_VISIBLE } void KMessageWidgetTest::testOverlappingHideAndShow_data() @@ -153,6 +145,7 @@ QSignalSpy showSignalsSpy(&w, &KMessageWidget::showAnimationFinished); QSignalSpy hideSignalsSpy(&w, &KMessageWidget::hideAnimationFinished); w.show(); + CHECK_FULLY_VISIBLE // test: call show while hide animation still running w.animatedHide(); @@ -164,13 +157,9 @@ QVERIFY(! w.isHideAnimationRunning()); QCOMPARE(hideSignalsSpy.count(), 1); - while (w.isShowAnimationRunning()) { - QCOMPARE(showSignalsSpy.count(), 0); - QTest::qWait(50); - } - + QTRY_VERIFY(!w.isShowAnimationRunning()); QCOMPARE(showSignalsSpy.count(), 1); - QVERIFY(w.isVisible()); + CHECK_FULLY_VISIBLE } void KMessageWidgetTest::testOverlappingDoubleShow_data() @@ -194,13 +183,9 @@ } w.animatedShow(); - while (w.isShowAnimationRunning()) { - QCOMPARE(showSignalsSpy.count(), 0); - QTest::qWait(50); - } - + QTRY_VERIFY(!w.isShowAnimationRunning()); QCOMPARE(showSignalsSpy.count(), 1); - QVERIFY(w.isVisible()); + CHECK_FULLY_VISIBLE } void KMessageWidgetTest::testOverlappingDoubleHide_data() @@ -225,13 +210,9 @@ } w.animatedHide(); - while (w.isHideAnimationRunning()) { - QCOMPARE(hideSignalsSpy.count(), 0); - QTest::qWait(50); - } - + QTRY_VERIFY(!w.isHideAnimationRunning()); QCOMPARE(hideSignalsSpy.count(), 1); - QVERIFY(! w.isVisible()); + CHECK_FULLY_NOT_VISIBLE } void KMessageWidgetTest::testHideWithNotYetShownParent() @@ -243,12 +224,28 @@ // test: call hide while not yet visible w.animatedHide(); - while (w.isHideAnimationRunning()) { - QCOMPARE(hideSignalsSpy.count(), 0); - QTest::qWait(50); - } + QTRY_VERIFY(!w.isHideAnimationRunning()); parent.show(); QCOMPARE(hideSignalsSpy.count(), 1); - QVERIFY(! w.isVisible()); + QVERIFY(! w.isVisible()); // Not CHECK_FULLY_NOT_VISIBLE because since it was never shown height is not what it would be otherwise +} + +void KMessageWidgetTest::testNonAnimatedShowAfterAnimatedHide() +{ + KMessageWidget w(QStringLiteral("Hello world")); + QSignalSpy hideSignalsSpy(&w, &KMessageWidget::hideAnimationFinished); + + w.show(); + CHECK_FULLY_VISIBLE + + w.animatedHide(); + + QTRY_VERIFY(!w.isHideAnimationRunning()); + + QCOMPARE(hideSignalsSpy.count(), 1); + CHECK_FULLY_NOT_VISIBLE + + w.show(); + CHECK_FULLY_VISIBLE } diff --git a/src/kmessagewidget.cpp b/src/kmessagewidget.cpp --- a/src/kmessagewidget.cpp +++ b/src/kmessagewidget.cpp @@ -47,6 +47,7 @@ QToolButton *closeButton = nullptr; QTimeLine *timeLine = nullptr; QIcon icon; + bool ignoreShowEventDoingAnimatedShow = false; KMessageWidget::MessageType messageType; bool wordWrap; @@ -75,6 +76,7 @@ QObject::connect(timeLine, SIGNAL(finished()), q, SLOT(slotTimeLineFinished())); content = new QFrame(q); + content->setObjectName(QStringLiteral("contentWidget")); content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); wordWrap = false; @@ -332,6 +334,11 @@ d->createLayout(); } else if (event->type() == QEvent::PaletteChange) { d->applyStyleSheet(); + } else if (event->type() == QEvent::Show && !d->ignoreShowEventDoingAnimatedShow) { + if ((height() != d->content->height()) || (d->content->pos().y() != 0)) { + d->content->move(0, 0); + setFixedHeight(d->content->height()); + } } return QFrame::event(event); } @@ -420,12 +427,14 @@ return; } - if (isVisible() && (d->timeLine->state() == QTimeLine::NotRunning)) { + if (isVisible() && (d->timeLine->state() == QTimeLine::NotRunning) && (height() == d->bestContentHeight()) && (d->content->pos().y() == 0)) { emit showAnimationFinished(); return; } - QFrame::show(); + d->ignoreShowEventDoingAnimatedShow = true; + show(); + d->ignoreShowEventDoingAnimatedShow = false; setFixedHeight(0); int wantedHeight = d->bestContentHeight(); d->content->setGeometry(0, -wantedHeight, width(), wantedHeight);