aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-10-16 10:37:13 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-10-18 13:37:34 +0000
commit6b0206ead18466a2eab48d24c7f08d0db1fdd061 (patch)
tree05aca3b411d6695c4aebc8938eb59c80a1b99b93
parent9ae30a48142c5df96048d3ca62fef9ed92f3f566 (diff)
Only reparent the InputPanel when necessary
The input panel needs to work also while a modal popup is open. Since the concept of modality does not exist in Qt Quick, and is implemented with an event-eating overlay, 4e8b3dd45ae4cc66a1b77cce901f80406b2a0f69 introduced the automatic reparenting of the integrated input panel so that it a sibling of the overlay, with a higher z-value. This effectively changed the parent item, and had negative side effects to mechanisms such as anchoring. This change only reparents the input panel if there is an overlay (using the mechanism also used by the Qt Quick Control class QQuickOverlay) that is visible when the input item changes, and sets the z-value to be one above the overlay's. The prevents modal blocking during the overlay session. When the input item changes again and the overlay is no longer visible, then the parent and z value get reset. This improves the situation, but is still not ideal, as during modal sessions the anchoring of the input panel will still not work as expected. Add a test case that verifies that clicks go through to the keyboard while a modal dialog is open. Fixes: QTBUG-97075 Task-number: QTBUG-56918 Task-number: QTBUG-92881 Change-Id: I7a5bcfebe7b69780234737a2311e08b2a6f60a4e Reviewed-by: Jarkko Koivikko <jarkko.koivikko@code-q.fi> (cherry picked from commit 5564f1c96322d7c3f884d2e6f9b3a95e3134fb9f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp21
-rw-r--r--src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h2
-rw-r--r--tests/auto/CMakeLists.txt1
-rw-r--r--tests/auto/inputpanelcontrols/CMakeLists.txt14
-rw-r--r--tests/auto/inputpanelcontrols/data/inputpanel/inputpanel.qml41
-rw-r--r--tests/auto/inputpanelcontrols/data/tst_inputpanelcontrols.qml124
-rw-r--r--tests/auto/inputpanelcontrols/tst_inputpanelcontrols.cpp50
7 files changed, 249 insertions, 4 deletions
diff --git a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp
index 646dd6f6..4324ffe7 100644
--- a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp
+++ b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp
@@ -224,8 +224,6 @@ void QVirtualKeyboardInputContextPrivate::registerInputPanel(QObject *inputPanel
VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputContextPrivate::registerInputPanel():" << inputPanel;
Q_ASSERT(!this->inputPanel);
this->inputPanel = inputPanel;
- if (QQuickItem *item = qobject_cast<QQuickItem *>(inputPanel))
- item->setZ(10000);
}
void QVirtualKeyboardInputContextPrivate::hideInputPanel()
@@ -284,8 +282,23 @@ void QVirtualKeyboardInputContextPrivate::onInputItemChanged()
high z-order will make sure it gets events also during a modal session.
*/
if (isDesktopPanel.isValid() && !isDesktopPanel.toBool()) {
- if (QQuickWindow *quickWindow = quickItem->window())
- vkbPanel->setParentItem(quickWindow->contentItem());
+ if (QQuickWindow *quickWindow = quickItem->window()) {
+ QQuickItem *overlay = quickWindow->property("_q_QQuickOverlay").value<QQuickItem*>();
+ if (overlay && overlay->isVisible()) {
+ if (vkbPanel->parentItem() != overlay->parentItem()) {
+ inputPanelParentItem = vkbPanel->parentItem();
+ inputPanelZ = vkbPanel->z();
+ vkbPanel->setParentItem(overlay->parentItem());
+ vkbPanel->setZ(overlay->z() + 1);
+ }
+ } else {
+ if (QQuickItem *oldParentItem = qobject_cast<QQuickItem *>(inputPanelParentItem.data())) {
+ vkbPanel->setParentItem(oldParentItem);
+ vkbPanel->setZ(inputPanelZ);
+ inputPanelParentItem = nullptr;
+ }
+ }
+ }
}
}
}
diff --git a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h
index 4d871f9b..ab2698d5 100644
--- a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h
+++ b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h
@@ -158,6 +158,8 @@ private:
QVirtualKeyboardInputEngine *inputEngine;
QtVirtualKeyboard::ShiftHandler *_shiftHandler;
QPointer<QObject> inputPanel;
+ QPointer<QObject> inputPanelParentItem;
+ qreal inputPanelZ = .0;
QRectF keyboardRect;
QRectF previewRect;
bool _previewVisible;
diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt
index 9aab75f9..34ee449d 100644
--- a/tests/auto/CMakeLists.txt
+++ b/tests/auto/CMakeLists.txt
@@ -1,6 +1,7 @@
# Generated from auto.pro.
add_subdirectory(inputpanel)
+add_subdirectory(inputpanelcontrols)
add_subdirectory(styles)
add_subdirectory(layoutfilesystem)
add_subdirectory(layoutresources)
diff --git a/tests/auto/inputpanelcontrols/CMakeLists.txt b/tests/auto/inputpanelcontrols/CMakeLists.txt
new file mode 100644
index 00000000..29fc0515
--- /dev/null
+++ b/tests/auto/inputpanelcontrols/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Collect test data
+file(GLOB_RECURSE test_data_glob
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/data/*)
+list(APPEND test_data ${test_data_glob})
+
+qt_internal_add_test(tst_inputpanelcontrols
+ QMLTEST
+ SOURCES
+ tst_inputpanelcontrols.cpp
+ PUBLIC_LIBRARIES
+ Qt::Gui
+ TESTDATA ${test_data}
+)
diff --git a/tests/auto/inputpanelcontrols/data/inputpanel/inputpanel.qml b/tests/auto/inputpanelcontrols/data/inputpanel/inputpanel.qml
new file mode 100644
index 00000000..8c37f291
--- /dev/null
+++ b/tests/auto/inputpanelcontrols/data/inputpanel/inputpanel.qml
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest
+import QtQuick
+import QtQuick.VirtualKeyboard
+
+InputPanel {
+ id: inputPanel
+ z: 99
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ visible: active
+}
diff --git a/tests/auto/inputpanelcontrols/data/tst_inputpanelcontrols.qml b/tests/auto/inputpanelcontrols/data/tst_inputpanelcontrols.qml
new file mode 100644
index 00000000..4820fe25
--- /dev/null
+++ b/tests/auto/inputpanelcontrols/data/tst_inputpanelcontrols.qml
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest
+import QtQuick
+import QtQuick.Window
+import QtQuick.Controls
+
+Rectangle {
+ id: container
+ width: 800
+ height: 640
+ color: "blue"
+
+ Component {
+ id: textInputComp
+ TextEdit {
+ anchors.fill: parent
+ visible: true
+ focus: true
+ color: "white"
+ }
+ }
+
+ TestCase {
+ id: testcase
+ name: "tst_inputpanelcontrols"
+ when: windowShown
+
+ property var inputPanel: null
+ property var textInput: null
+
+ function initTestCase() {
+ var inputPanelComp = Qt.createComponent("inputpanel/inputpanel.qml")
+ compare(inputPanelComp.status, Component.Ready, "Failed to create component: "+inputPanelComp.errorString())
+ inputPanel = inputPanelComp.createObject(container)
+
+ textInput = textInputComp.createObject(container)
+ }
+
+ function cleanupTestCase() {
+ if (inputPanel)
+ inputPanel.destroy()
+ }
+
+ function prepareTest() {
+ var window = container.Window.window
+ verify(window)
+ window.raise()
+ window.requestActivate()
+ tryCompare(window, "active", true)
+
+ container.forceActiveFocus()
+ waitForRendering(container)
+ textInput.forceActiveFocus()
+ waitForRendering(inputPanel)
+
+ textInput.text = ""
+ verify(inputPanel.visible === true)
+ verify(textInput.activeFocus === true)
+ }
+
+ Component {
+ id: modalDialogComp
+ Dialog {
+ id: dialog
+ modal: true
+ anchors.centerIn: parent
+ width: 200
+ height: 150
+ property alias textEdit: textEdit
+ TextEdit {
+ id: textEdit
+ visible: true
+ focus: true
+ color: "red"
+ }
+ }
+ }
+
+ function test_worksWithModal() {
+ prepareTest()
+ var modalDialog = modalDialogComp.createObject(container)
+ modalDialog.open()
+ modalDialog.forceActiveFocus()
+
+ verify(modalDialog.textEdit.activeFocus === true)
+ compare(modalDialog.textEdit.text, "")
+ verify(inputPanel.visible === true)
+ waitForRendering(inputPanel)
+
+ mousePress(inputPanel, 10, 10, Qt.LeftButton, Qt.NoModifier, 20)
+ verify(modalDialog.visible === true)
+ mouseRelease(inputPanel, 10, 10, Qt.LeftButton, Qt.NoModifier, 20)
+ compare(modalDialog.textEdit.text, "Q")
+ }
+ }
+}
diff --git a/tests/auto/inputpanelcontrols/tst_inputpanelcontrols.cpp b/tests/auto/inputpanelcontrols/tst_inputpanelcontrols.cpp
new file mode 100644
index 00000000..01f7dd1c
--- /dev/null
+++ b/tests/auto/inputpanelcontrols/tst_inputpanelcontrols.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtQuickTest/quicktest.h>
+#include <QByteArray>
+#include <QStandardPaths>
+#include <QFileInfo>
+#include <QDir>
+
+static bool s_configEnv = qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
+static bool initStandardPaths() {
+ QStandardPaths::setTestModeEnabled(true);
+ auto configLocations = QStringList()
+ << QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/qtvirtualkeyboard"
+ << QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/qtvirtualkeyboard";
+ for (const QString &configLocation : configLocations) {
+ if (configLocation != "/qtvirtualkeyboard")
+ QDir(configLocation).removeRecursively();
+ }
+ return true;
+}
+static bool s_initStandardPaths = initStandardPaths();
+
+QUICK_TEST_MAIN(inputpanelcontrols)