aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-03-02 13:19:38 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-03-03 12:38:16 +0100
commit4e8b3dd45ae4cc66a1b77cce901f80406b2a0f69 (patch)
tree4378b1eaa35948a95cf2224470280d4aae79663b
parent39a3c50f6f3d3aff52853510543388638a2524d5 (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.qml5
-rw-r--r--src/virtualkeyboard/content/components/Keyboard.qml2
-rw-r--r--src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp35
-rw-r--r--src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h2
-rw-r--r--tests/manual/manual.pro4
-rw-r--r--tests/manual/quickcontrols2/main.cpp44
-rw-r--r--tests/manual/quickcontrols2/main.qml129
-rw-r--r--tests/manual/quickcontrols2/main.qrc5
-rw-r--r--tests/manual/quickcontrols2/quickcontrols2.pro6
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 =