diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2020-03-02 13:19:38 +0100 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2020-03-03 12:38:16 +0100 |
commit | 4e8b3dd45ae4cc66a1b77cce901f80406b2a0f69 (patch) | |
tree | 4378b1eaa35948a95cf2224470280d4aae79663b | |
parent | 39a3c50f6f3d3aff52853510543388638a2524d5 (diff) |
Make sure that the input panel receives events during modal sessions
Parent the input panel to the focus items' window's contentItem, with
highest z order. This makes the input panel a sibling of the popup's
overlay and dimmer items, but thanks to the highest z-order, the input
panel gets all events.
This requires that we store the input panel in the InputContext, which
again assumes that there is only one input panel. Making this assumption
explicit with a Q_ASSERT.
Also, since __isRootItem is now true, we need to override the reliance
on this property alone to avoid that SelectionControl becomes disabled.
Introduce a second internal property. This should be followed up by a
change that makes the disabling of the SelectionControl in the desktop
integration case an explicit step.
Fixes: QTBUG-56918
Done-with: Jarkko Koivikko <jarkko.koivikko@code-q.fi>
Change-Id: I58bbbb0adf145c9cfc30a7dd0acb2a0e1231481b
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r-- | src/virtualkeyboard/content/InputPanel.qml | 5 | ||||
-rw-r--r-- | src/virtualkeyboard/content/components/Keyboard.qml | 2 | ||||
-rw-r--r-- | src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp | 35 | ||||
-rw-r--r-- | src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h | 2 | ||||
-rw-r--r-- | tests/manual/manual.pro | 4 | ||||
-rw-r--r-- | tests/manual/quickcontrols2/main.cpp | 44 | ||||
-rw-r--r-- | tests/manual/quickcontrols2/main.qml | 129 | ||||
-rw-r--r-- | tests/manual/quickcontrols2/main.qrc | 5 | ||||
-rw-r--r-- | tests/manual/quickcontrols2/quickcontrols2.pro | 6 |
9 files changed, 225 insertions, 7 deletions
diff --git a/src/virtualkeyboard/content/InputPanel.qml b/src/virtualkeyboard/content/InputPanel.qml index b10fef21..ea3ab23f 100644 --- a/src/virtualkeyboard/content/InputPanel.qml +++ b/src/virtualkeyboard/content/InputPanel.qml @@ -116,11 +116,14 @@ Item { /*! \internal */ readonly property bool __isRootItem: inputPanel.parent != null && inputPanel.parent.parent == null + /*! \internal */ + property bool __reparented: false + SelectionControl { objectName: "selectionControl" x: -parent.x y: -parent.y - enabled: active && !keyboard.fullScreenMode && !__isRootItem + enabled: active && !keyboard.fullScreenMode && (!__isRootItem || __reparented) } implicitHeight: keyboard.height diff --git a/src/virtualkeyboard/content/components/Keyboard.qml b/src/virtualkeyboard/content/components/Keyboard.qml index 954c6f2f..d6073d4e 100644 --- a/src/virtualkeyboard/content/components/Keyboard.qml +++ b/src/virtualkeyboard/content/components/Keyboard.qml @@ -90,6 +90,8 @@ Item { return plainInputMethod } + Component.onCompleted: InputContext.priv.registerInputPanel(parent) + width: keyboardBackground.width height: keyboardBackground.height + (VirtualKeyboardSettings.wordCandidateList.alwaysVisible ? wordCandidateView.height : 0) onActiveChanged: { diff --git a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp index b99b7147..2c945356 100644 --- a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp +++ b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp @@ -36,6 +36,8 @@ #include <QtVirtualKeyboard/qvirtualkeyboardinputengine.h> #include <QGuiApplication> +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickwindow.h> #include <QtGui/qpa/qplatformintegration.h> #include <QtGui/private/qguiapplication_p.h> @@ -213,6 +215,15 @@ bool QVirtualKeyboardInputContextPrivate::hasEnterKeyAction(QObject *item) const return item != nullptr && qmlAttachedPropertiesObject<EnterKeyAction>(item, false); } +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(std::numeric_limits<qreal>::max()); +} + void QVirtualKeyboardInputContextPrivate::hideInputPanel() { platformInputContext->hideInputPanel(); @@ -259,10 +270,26 @@ void QVirtualKeyboardInputContextPrivate::forceCursorPosition(int anchorPosition void QVirtualKeyboardInputContextPrivate::onInputItemChanged() { - if (!inputItem() && !activeKeys.isEmpty()) { - // After losing keyboard focus it is impossible to track pressed keys - activeKeys.clear(); - clearState(State::KeyEvent); + if (QObject *item = inputItem()) { + if (QQuickItem *vkbPanel = qobject_cast<QQuickItem*>(inputPanel)) { + if (QQuickItem *quickItem = qobject_cast<QQuickItem*>(item)) { + const QVariant isRootItem = vkbPanel->property("__isRootItem"); + /* + For integrated keyboards, make sure it's a sibling to the overlay. The + high z-order will make sure it gets events also during a modal session. + */ + if (isRootItem.isValid() && !isRootItem.toBool()) { + vkbPanel->setParentItem(quickItem->window()->contentItem()); + vkbPanel->setProperty("__reparented", true); + } + } + } + } else { + if (!activeKeys.isEmpty()) { + // After losing keyboard focus it is impossible to track pressed keys + activeKeys.clear(); + clearState(State::KeyEvent); + } } clearState(State::InputMethodClick); } diff --git a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h index 4075c95f..54491e76 100644 --- a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h +++ b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h @@ -111,6 +111,7 @@ public: // Helper functions Q_INVOKABLE bool fileExists(const QUrl &fileUrl); Q_INVOKABLE bool hasEnterKeyAction(QObject *item) const; + Q_INVOKABLE void registerInputPanel(QObject *inputPanel); Q_SIGNALS: void focusChanged(); @@ -151,6 +152,7 @@ private: QtVirtualKeyboard::PlatformInputContext *platformInputContext; QVirtualKeyboardInputEngine *inputEngine; QtVirtualKeyboard::ShiftHandler *_shiftHandler; + QPointer<QObject> inputPanel; QRectF keyboardRect; QRectF previewRect; bool _previewVisible; diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 671e7a13..3f9a58c3 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs SUBDIRS += \ x11vkbwrapper \ - x11vkbtest - + x11vkbtest \ + quickcontrols2 diff --git a/tests/manual/quickcontrols2/main.cpp b/tests/manual/quickcontrols2/main.cpp new file mode 100644 index 00000000..2da79e6e --- /dev/null +++ b/tests/manual/quickcontrols2/main.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); + + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QLatin1String("qrc:/main.qml"))); + + return app.exec(); +} diff --git a/tests/manual/quickcontrols2/main.qml b/tests/manual/quickcontrols2/main.qml new file mode 100644 index 00000000..cfd4c0f5 --- /dev/null +++ b/tests/manual/quickcontrols2/main.qml @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.VirtualKeyboard 2.15 + +ApplicationWindow { + visible: true + width: 640 + height: 480 + title: qsTr("Modal Popup Test") + id: root + + Page { + Button { + id: popupButton + Layout.fillWidth: true + font.pixelSize: 20 + text: qsTr("Popup") + onClicked: { + passwordsuspendInput.focus = true + suspendPopup.open() + } + } + + TextField { + placeholderText: qsTr("Test") + implicitWidth: 200 + focus: true + font.pixelSize: 24 + x: popupButton.width + } + + } + + Popup { + id: suspendPopup + x: root.width /2 - suspendPopup.width /2 + y: root.height /8 + modal: true + focus: true + closePolicy: Popup.NoAutoClose + + contentItem: GridLayout { + rows: 2 + columns: 1 + columnSpacing: 20 + rowSpacing: 20 + + TextField { + id: passwordsuspendInput + placeholderText: qsTr("Password") + implicitWidth: 200 + focus: true + font.pixelSize: 24 + + onAccepted: loginsuspendButton.clicked() + } + + Button { + id: loginsuspendButton + text: "Done" + flat: true + implicitWidth: 200 + font.pixelSize: 24 + onClicked: { + passwordsuspendInput.text ="" + suspendPopup.close() + } + } + } + } + + InputPanel { + id: inputPanel + x: 0 + y: root.height + width: root.width + + states: State { + name: "visible" + when: inputPanel.active + PropertyChanges { + target: inputPanel + y: root.height - inputPanel.height + } + } + transitions: Transition { + from: "" + to: "visible" + reversible: true + ParallelAnimation { + NumberAnimation { + properties: "y" + duration: 250 + easing.type: Easing.InOutQuad + } + } + } + } +} diff --git a/tests/manual/quickcontrols2/main.qrc b/tests/manual/quickcontrols2/main.qrc new file mode 100644 index 00000000..5f6483ac --- /dev/null +++ b/tests/manual/quickcontrols2/main.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/quickcontrols2/quickcontrols2.pro b/tests/manual/quickcontrols2/quickcontrols2.pro new file mode 100644 index 00000000..95d9f765 --- /dev/null +++ b/tests/manual/quickcontrols2/quickcontrols2.pro @@ -0,0 +1,6 @@ +QT += qml quick +SOURCES += main.cpp +RESOURCES += main.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = |