ToolTip: fix timeout not activating if opened during exit transition

When a tooltip with an exit transition and a timeout is made visible
during its exit transition, it would end up not timing out. This is
because the change in the tooltip's visibility is what usually
kicks off the timeout timer, but if there is no change in visibility
(because the exit transition hadn't finished, so the tooltip was
still visible), this won't happen.

Fix the issue by calling startTimeout() in
QQuickToolTip::setVisible().

Change-Id: I5f95a698e48f376c7597558572ac91625a276e53
Fixes: QTBUG-81935
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
Mitch Curtis 2020-02-19 12:56:20 +01:00
parent e7a9691481
commit c1420ee542
2 changed files with 37 additions and 4 deletions

View File

@ -252,9 +252,18 @@ void QQuickToolTip::setVisible(bool visible)
{
Q_D(QQuickToolTip);
if (visible) {
if (!d->visible && d->delay > 0) {
d->startDelay();
return;
if (!d->visible) {
// We are being made visible, and we weren't before.
if (d->delay > 0) {
d->startDelay();
return;
}
} else {
// We are being made visible, even though we already were.
// We've probably been re-opened before our exit transition could finish.
// In that case, we need to manually start the timeout, as that is usually
// done in itemChange(), which won't be called in this situation.
d->startTimeout();
}
} else {
d->stopDelay();

View File

@ -227,15 +227,39 @@ TestCase {
id: toolTipWithExitTransition
ToolTip {
Component.onCompleted: contentItem.objectName = "contentItem"
enter: Transition {
NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 100 }
}
exit: Transition {
NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 1000 }
NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 500 }
}
}
}
function test_openDuringExitTransitionWithTimeout() {
let control = createTemporaryObject(toolTipWithExitTransition, testCase, { timeout: 250 })
verify(control)
control.open()
verify(control.visible)
// Can't be fully open yet because the enter transition has only just started.
compare(control.opened, false)
compare(control.enter.running, true)
tryCompare(control, "opened", true)
// Let it timeout and begin the exit transition.
tryCompare(control, "opened", false)
verify(control.visible)
tryCompare(control.exit, "running", true)
verify(control.visible)
// Quickly open it again; it should still timeout eventually.
control.open()
tryCompare(control, "opened", true)
tryCompare(control.exit, "running", true)
}
function test_makeVisibleWhileExitTransitionRunning_data() {
return [
{ tag: "imperative", imperative: true },