diff options
author | Mitch Curtis <mitch.curtis@qt.io> | 2016-05-10 12:44:15 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2016-05-11 20:34:14 +0000 |
commit | eb6e122c68333382309843ad96e7d04d2c5a3595 (patch) | |
tree | e0bcabf84ae8822382d17b802445f5b456580ad5 | |
parent | 25ef915acd941f0c8db3f7102a2deeaab17e6d14 (diff) |
Popup: restore focus to contentItem of ApplicationWindow when closing
In Controls2, Popup and normal content are in same window, then we
should maintain the focus restore work.
Task-number: QTBUG-53275
Change-Id: I57f5aaf3febf1b7d2071c1734d8561932f95c699
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
-rw-r--r-- | src/quicktemplates2/qquickapplicationwindow.cpp | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 6 | ||||
-rw-r--r-- | tests/auto/applicationwindow/data/focusAfterPopupClosed.qml | 86 | ||||
-rw-r--r-- | tests/auto/applicationwindow/tst_applicationwindow.cpp | 45 | ||||
-rw-r--r-- | tests/auto/focus/tst_focus.cpp | 2 |
5 files changed, 140 insertions, 1 deletions
diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp index 401313d8..940e5eeb 100644 --- a/src/quicktemplates2/qquickapplicationwindow.cpp +++ b/src/quicktemplates2/qquickapplicationwindow.cpp @@ -424,6 +424,8 @@ QQuickItem *QQuickApplicationWindow::contentItem() const QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func()); if (!d->contentItem) { d->contentItem = new QQuickItem(QQuickWindow::contentItem()); + d->contentItem->setFlag(QQuickItem::ItemIsFocusScope); + d->contentItem->setFocus(true); d->relayout(); } return d->contentItem; diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 0f2e8378..baa4bd8a 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -232,6 +232,12 @@ void QQuickPopupPrivate::finalizeExitTransition(bool hide) popupItem->setVisible(false); } + QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow*>(window); + if (applicationWindow) + applicationWindow->contentItem()->setFocus(true); + else if (window) + window->contentItem()->setFocus(true); + visible = false; emit q->visibleChanged(); emit q->closed(); diff --git a/tests/auto/applicationwindow/data/focusAfterPopupClosed.qml b/tests/auto/applicationwindow/data/focusAfterPopupClosed.qml new file mode 100644 index 00000000..629e0cf9 --- /dev/null +++ b/tests/auto/applicationwindow/data/focusAfterPopupClosed.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Controls 2.0 + +ApplicationWindow { + width: 200 + height: 200 + visible: true + + signal focusScopeKeyPressed + + property alias toolButton: toolButton + property alias focusScope: focusScope + + header: ToolBar { + ToolButton { + id: toolButton + text: qsTr("File") + onClicked: fileMenu.open() + focusPolicy: Qt.TabFocus + + Menu { + id: fileMenu + y: parent.height + + MenuItem { + text: qsTr("New") + } + MenuItem { + text: qsTr("Open") + } + MenuItem { + text: qsTr("Close") + } + } + } + } + + FocusScope { + id: focusScope + focus: true + anchors.fill: parent + + Keys.onSpacePressed: focusScopeKeyPressed() + } +} + diff --git a/tests/auto/applicationwindow/tst_applicationwindow.cpp b/tests/auto/applicationwindow/tst_applicationwindow.cpp index 954f80d8..bec8aa81 100644 --- a/tests/auto/applicationwindow/tst_applicationwindow.cpp +++ b/tests/auto/applicationwindow/tst_applicationwindow.cpp @@ -71,6 +71,7 @@ private slots: void locale(); void activeFocusControl_data(); void activeFocusControl(); + void focusAfterPopupClosed(); }; void tst_applicationwindow::qmlCreation() @@ -639,6 +640,50 @@ void tst_applicationwindow::activeFocusControl() QCOMPARE(window->activeFocusControl(), activeFocusControl); } +void tst_applicationwindow::focusAfterPopupClosed() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("focusAfterPopupClosed.qml")); + QScopedPointer<QQuickWindow> window(qobject_cast<QQuickWindow*>(component.create())); + QVERIFY(window); + + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QVERIFY(QGuiApplication::focusWindow() == window.data()); + + QQuickItem* contentItem = window->contentItem(); + QVERIFY(contentItem); + QVERIFY(contentItem->hasActiveFocus()); + + QQuickItem* focusScope = window->property("focusScope").value<QQuickItem*>(); + QVERIFY(focusScope); + QVERIFY(focusScope->hasActiveFocus()); + + QSignalSpy spy(window.data(), SIGNAL(focusScopeKeyPressed())); + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(spy.count(), 1); + + // Open the menu. + QQuickItem* toolButton = window->property("toolButton").value<QQuickItem*>(); + QVERIFY(toolButton); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, + toolButton->mapFromScene(QPointF(toolButton->width() / 2, toolButton->height() / 2)).toPoint()); + QVERIFY(!focusScope->hasActiveFocus()); + + // The FocusScope shouldn't receive any key events while the menu is open. + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(spy.count(), 1); + + // Close the menu. The FocusScope should regain focus. + QTest::keyClick(window.data(), Qt::Key_Escape); + QVERIFY(focusScope->hasActiveFocus()); + + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(spy.count(), 2); +} + QTEST_MAIN(tst_applicationwindow) #include "tst_applicationwindow.moc" diff --git a/tests/auto/focus/tst_focus.cpp b/tests/auto/focus/tst_focus.cpp index 6c184851..2c9573c6 100644 --- a/tests/auto/focus/tst_focus.cpp +++ b/tests/auto/focus/tst_focus.cpp @@ -228,7 +228,7 @@ void tst_focus::reason() QEXPECT_FAIL("TextField", "TODO: TextField::visualFocus?", Continue); QCOMPARE(control->property("visualFocus"), QVariant(false)); - window->contentItem()->forceActiveFocus(Qt::TabFocusReason); + window->contentItem()->setFocus(false, Qt::TabFocusReason); QVERIFY(!control->hasActiveFocus()); QCOMPARE(control->property("focusReason").toInt(), int(Qt::TabFocusReason)); |