From 1f064bf6de8412af2644c2ca14d146b17ffc695b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pekka=20Geh=C3=B6r?= Date: Tue, 12 Nov 2019 11:52:31 +0200 Subject: Fix for a special character issue Some of a characters need change of keyboard mapping, that they appear correctly. In the previous implementation there was no change of keyboard mapping, which caused the wrong character to appear or no character at all. Change-Id: I5670d37efba5b1a3aa4dd93e5309efea14fa0f53 Reviewed-by: Mitch Curtis (cherry picked from commit 4b9a5746581494ebf9e9847b829d2810e4469a53) Reviewed-by: Jani Heikkinen --- tests/manual/x11vkbwrapper/handlekeyevents.cpp | 171 ++++++++++++++++++--- tests/manual/x11vkbwrapper/handlekeyevents.h | 13 +- .../manual/x11vkbwrapper/keysymmapsforfakeinput.h | 40 ++--- 3 files changed, 182 insertions(+), 42 deletions(-) diff --git a/tests/manual/x11vkbwrapper/handlekeyevents.cpp b/tests/manual/x11vkbwrapper/handlekeyevents.cpp index 0c3c85a4..c6b5c9f3 100644 --- a/tests/manual/x11vkbwrapper/handlekeyevents.cpp +++ b/tests/manual/x11vkbwrapper/handlekeyevents.cpp @@ -39,11 +39,13 @@ extern "C" { #include #include +#include "atspi/atspi.h" } namespace { const bool KKeyPress = true; const bool KKeyRelease = false; +const int NoKeySymFound = 63; // Undefine define KeyRelease from X.h. // Enables using QEvent::KeyRelease type in eventFilter. @@ -104,6 +106,7 @@ HandleKeyEvents::~HandleKeyEvents() bool HandleKeyEvents::init() { + m_temporaryKeyCodes = QHash(); m_xdo = xdo_new(nullptr); return m_xdo != nullptr; } @@ -117,7 +120,7 @@ bool HandleKeyEvents::init() */ bool HandleKeyEvents::eventFilter(QObject *watched, QEvent *event) { - Q_UNUSED( watched ); + Q_UNUSED( watched ) const auto type = event->type(); if (type == QEvent::MouseButtonRelease && !QGuiApplication::inputMethod()->isVisible()) { @@ -153,12 +156,12 @@ bool HandleKeyEvents::eventFilter(QObject *watched, QEvent *event) 2000); /** a Key strings as Emojis ":-), <3". */ } else if (str.length() > 1) { - xdo_enter_text_window(m_xdo, CURRENTWINDOW, - str.toLatin1(), - 2000); + for (auto sKey : str) { + sendKeyWithAtspi(nullptr, sKey); + } /** a Normal Keys. */ - } else if (!str.isEmpty()) { - keyTap(str); + } else if (key != Qt::Key_Shift) { + sendKeyWithAtspi(keyEvent, QString("")); } } return false; @@ -166,24 +169,67 @@ bool HandleKeyEvents::eventFilter(QObject *watched, QEvent *event) /** * @brief HandleKeyEvents::keyTap + * @param keyEvent a QKeyEvent pointer * @param key a Key as a string */ -void HandleKeyEvents::keyTap(const QString &key) const +void HandleKeyEvents::keyTap(const QKeyEvent *keyEvent, const QString &key) +{ + qCDebug(lcHandleKeyEvents) << Q_FUNC_INFO; + + /** Scratch space for temporary keycode bindings */ + int scratchKeyCode = 0; + KeyCode keyCode = 0x0; + + if (keyEvent) { + auto qtKey = static_cast(keyEvent->key()); + if (m_temporaryKeyCodes.contains(qtKey)) { + scratchKeyCode = m_temporaryKeyCodes.value(qtKey); + } else { + scratchKeyCode = getTemporaryKeyCode(); + m_temporaryKeyCodes.insert(qtKey, scratchKeyCode); + } + + /** find the keysym for the given unicode char */ + const QString str = qtKeyCodes2.indexOf(qtKey) >= 0 ? "U"+ QString::number(keyEvent->key(), 16 ) : + "U"+ keyEvent->text().toLatin1().toHex(); + const KeySym sym = XStringToKeysym(str.toUtf8().data()); + if (sym && sym != NoKeySymFound) { + remapScratchKeyCode(sym, scratchKeyCode); + keyCode = static_cast(scratchKeyCode); + } else { + keyCode = getUnicodeKeyCode(keyEvent->text(), scratchKeyCode); + } + keyClick(keyCode, keyEvent->text()); + } else { + keyCode = getUnicodeKeyCode(key, getTemporaryKeyCode()); + keyClick(keyCode, key); + } + + /** Revert Keymapping */ + remapScratchKeyCode(NoSymbol, scratchKeyCode); +} + +/** + * @brief HandleKeyEvents::keyClick + * @param key + * @param keyText Key as a string + */ +void HandleKeyEvents::keyClick(const KeyCode key, const QString &keyText) const { qCDebug(lcHandleKeyEvents) << Q_FUNC_INFO; - bool shiftDown = false; - KeyCode keyCode = getUnicodeKeycode(key); KeyCode shift = XKeysymToKeycode(m_xdo->xdpy, XK_Shift_L); + bool shiftDown = false; + /** Press a Shift button down if capital letter. */ - if (key.length() == 1 && (key.toLower() != key || xUpKeyCodes.count(key))) { + if (keyText.length() == 1 && (keyText.toLower() != keyText || xUpKeyCodes.count(keyText))) { keyPressRelease(shift, KKeyPress); shiftDown = true; } /** A Key press */ - keyPressRelease(keyCode, KKeyPress); + keyPressRelease(key, KKeyPress); /** A Key release */ - keyPressRelease(keyCode, KKeyRelease); + keyPressRelease(key, KKeyRelease); /** Release a Shift button if capital letter. */ if (shiftDown) { @@ -205,12 +251,12 @@ void HandleKeyEvents::keyPressRelease(const KeyCode key, const bool eventType) c } /** - * @brief HandleKeyEvents::getUnicodeKeycode + * @brief HandleKeyEvents::getUnicodeKeyCode * Get a correct key mapping for a key. * @param key a Key as a string * @return Keycode */ -KeyCode HandleKeyEvents::getUnicodeKeycode(const QString &key) const +KeyCode HandleKeyEvents::getUnicodeKeyCode(const QString &key, int scratchKeyCode) const { qCDebug(lcHandleKeyEvents) << Q_FUNC_INFO; KeyCode code = 0; @@ -221,12 +267,99 @@ KeyCode HandleKeyEvents::getUnicodeKeycode(const QString &key) const auto xUpKeyIter = xKeyCodes.find(key); code = XKeysymToKeycode(m_xdo->xdpy, xUpKeyIter->second); } else { - auto unicodeIter = unicodeKeySymbols.find(key); - quint32 unicodeKey = unicodeIter != unicodeKeySymbols.end() ? unicodeIter->second : 0; - KeySym keysyms[] = {unicodeKey}; - XChangeKeyboardMapping(m_xdo->xdpy, 999, 1, static_cast(keysyms), 1); - code = static_cast(999); + const KeySym sym = unicodeKeySymbols.find(key)->second; + remapScratchKeyCode(sym, scratchKeyCode); + code = static_cast(scratchKeyCode); } return code; } +/** + * @brief HandleKeyEvents::remapScratchKeyCode + * Remap the requested KeySym + * @param sym KeySymbol + * @param scratchKeyCode unused keycode to use for remapping + */ +void HandleKeyEvents::remapScratchKeyCode(const KeySym sym, int scratchKeyCode) const +{ + qCDebug(lcHandleKeyEvents) << Q_FUNC_INFO; + KeySym keysyms[] = {sym, sym}; + /** Remap */ + XChangeKeyboardMapping(m_xdo->xdpy, scratchKeyCode, 2, keysyms, 1); +} + +/** + * @brief HandleKeyEvents::sendKeyWithAtspi + * To send a ordinary keys via atspi(D-Bus). It is faster than a XTestFakeKeyEvent + * @param keyEvent KeyEvent + * @param key Key as string + */ +void HandleKeyEvents::sendKeyWithAtspi(const QKeyEvent *keyEvent, const QString key) +{ + qCDebug(lcHandleKeyEvents) << Q_FUNC_INFO; + const QString str = keyEvent != nullptr ? keyEvent->text() : key; + if (str.isEmpty()) { + return; + } + + const KeySym sym = unicodeKeySymbolsForAtspi.find(str)->second; + if (sym == 0) { + keyTap(keyEvent, QString("")); + } else { + GError *error = nullptr; + if (!atspi_generate_keyboard_event(static_cast(sym), nullptr, ATSPI_KEY_SYM, &error)) { + qCDebug(lcHandleKeyEvents) << "Error message: " << error->message; + } + } +} + +/** + * @brief HandleKeyEvents::getTemporaryKeyCode + * @return + */ +int HandleKeyEvents::getTemporaryKeyCode() +{ + qCDebug(lcHandleKeyEvents) << Q_FUNC_INFO; + KeySym *keySyms = nullptr; + int keySymsPerKeyCode = 0; + + /** Scratch space for temporary keycode bindings */ + int scratchKeyCode = 0; + int keyCodeLow = 0; + int keyCodeHigh = 0; + + /** get the range of keycodes usually from 8 - 255 */ + XDisplayKeycodes(m_xdo->xdpy, &keyCodeLow, &keyCodeHigh); + /** get all the mapped keysyms availabl */ + const KeyCode keyCodeL = static_cast(keyCodeLow); + keySyms = XGetKeyboardMapping( + m_xdo->xdpy, + keyCodeL, + keyCodeHigh - keyCodeLow, + &keySymsPerKeyCode); + + /** find unused keycode for unmapped keysyms so we can + hook up our own keycode and map every keysym on it + so we just need to 'click' our once unmapped keycode */ + int i; + for (i = keyCodeLow; i <= keyCodeHigh; i++) { + int keyIsEmpty = 1; + for (int j = 0; j < keySymsPerKeyCode; j++) { + const int symindex = (i - keyCodeLow) * keySymsPerKeyCode + j; + if (keySyms[symindex] != 0) { + keyIsEmpty = 0; + } else { + break; + } + } + if (keyIsEmpty) { + scratchKeyCode = i; + break; + } + } + XFree(keySyms); + XFlush(m_xdo->xdpy); + + return scratchKeyCode; +} + diff --git a/tests/manual/x11vkbwrapper/handlekeyevents.h b/tests/manual/x11vkbwrapper/handlekeyevents.h index 760ba757..72fc44f2 100644 --- a/tests/manual/x11vkbwrapper/handlekeyevents.h +++ b/tests/manual/x11vkbwrapper/handlekeyevents.h @@ -31,9 +31,9 @@ #define HANDLEKEYEVENTS_H #include +#include class QKeyEvent; - extern "C" { #include } @@ -52,9 +52,14 @@ public: bool init(); private: - void keyTap(const QString &key) const; + void keyTap(const QKeyEvent *keyEvent, const QString &key); + void keyClick(const KeyCode key, const QString &keyText) const; void keyPressRelease(const KeyCode key, const bool eventType) const; - KeyCode getUnicodeKeycode(const QString &key) const; + KeyCode getUnicodeKeyCode(const QString &key, int scratchKeyCode) const; + void remapScratchKeyCode(const KeySym sym, int scratchKeyCode) const; + void sendKeyWithAtspi(const QKeyEvent *keyEvent, const QString key); + int getTemporaryKeyCode(); + protected: /** Deliver events from a another object(s). */ @@ -63,6 +68,8 @@ protected: private: /** Libxdo context. */ xdo_t *m_xdo; + /** Store temporary keycodes. */ + QHash m_temporaryKeyCodes; }; #endif // HANDLEKEYEVENTS_H diff --git a/tests/manual/x11vkbwrapper/keysymmapsforfakeinput.h b/tests/manual/x11vkbwrapper/keysymmapsforfakeinput.h index 7dc404ba..b36a4221 100644 --- a/tests/manual/x11vkbwrapper/keysymmapsforfakeinput.h +++ b/tests/manual/x11vkbwrapper/keysymmapsforfakeinput.h @@ -39,25 +39,24 @@ extern "C" { #include } +static const std::map unicodeKeySymbolsForAtspi { + {"!",0x0021}, {"#",0x0023}, {"%",0x0025}, {"&",0x0026}, {"'",0x0027}, + {"(",0x0028}, {")",0x0029}, {"*",0x002A}, {"+",0x002B}, {",",0x002C}, {"-",0x002D}, {".",0x002E}, + {"0",0x0030}, {"1",0x0031}, {"2",0x0032}, {"3",0x0033}, {"4",0x0034}, {"5",0x0035}, {"6",0x0036}, + {"7",0x0037}, {"8",0x0038}, {"9",0x0039}, {":",0x003A}, {";",0x003B}, {"<",0x003C}, {"/",0x002F}, + {"=",0x003D}, {">",0x003E}, {"?",0x003F}, {"A",0x0041}, {"B",0x0042}, {"C",0x0043}, + {"D",0x0044}, {"E",0x0045}, {"F",0x0046}, {"G",0x0047}, {"H",0x0048}, {"I",0x0049}, {"J",0x004A}, + {"K",0x004B}, {"L",0x004C}, {"M",0x004D}, {"N",0x004E}, {"O",0x004F}, {"P",0x0050}, {"Q",0x0051}, + {"R",0x0052}, {"S",0x0053}, {"T",0x0054}, {"U",0x0055}, {"V",0x0056}, {"W",0x0057}, {"X",0x0058}, + {"Y",0x0059}, {"Z",0x005A}, {"_",0x005F}, + {"a",0x0061}, {"b",0x0062}, {"c",0x0063}, {"d",0x0064}, {"e",0x0065}, {"f",0x0066}, + {"g",0x0067}, {"h",0x0068}, {"i",0x0069}, {"j",0x006A}, {"k",0x006B}, {"l",0x006C}, {"m",0x006D}, + {"n",0x006E}, {"o",0x006F}, {"p",0x0070}, {"q",0x0071}, {"r",0x0072}, {"s",0x0073}, {"t",0x0074}, + {"u",0x0075}, {"v",0x0076}, {"w",0x0077}, {"x",0x0078}, {"y",0x0079}, {"z",0x007A}, +}; + static const std::map unicodeKeySymbols { - {"!",0x0021}, {"\"",0x0022}, {"#",0x0023}, {"$",0x0024}, {"%",0x0025}, {"&",0x0026}, {"'",0x0027}, - {"(",0x0028}, {")",0x0029}, {"*",0x002A}, {"+",0x002B}, {",",0x002C}, {"-",0x002D}, {".",0x002E}, - {"/",0x002F}, - {"0",0x0030}, {"1",0x0031}, {"2",0x0032}, {"3",0x0033}, {"4",0x0034}, {"5",0x0035}, - {"6",0x0036}, {"7",0x0037}, {"8",0x0038}, {"9",0x0039}, - {":",0x003A}, {";",0x003B}, {"<",0x003C}, - {"=",0x003D}, {">",0x003E}, {"?",0x003F}, {"@",0x0040}, - {"A",0x0041}, {"B",0x0042}, {"C",0x0043}, - {"D",0x0044}, {"E",0x0045}, {"F",0x0046}, {"G",0x0047}, {"H",0x0048}, {"I",0x0049}, {"J",0x004A}, - {"K",0x004B}, {"L",0x004C}, {"M",0x004D}, {"N",0x004E}, {"O",0x004F}, {"P",0x0050}, {"Q",0x0051}, - {"R",0x0052}, {"S",0x0053}, {"T",0x0054}, {"U",0x0055}, {"V",0x0056}, {"W",0x0057}, {"X",0x0058}, - {"Y",0x0059}, {"Z",0x005A}, - {"[",0x005B}, {"\\",0x005C}, {"]",0x005D}, {"^",0x005E}, {"_",0x005F}, - {"`",0x0060}, - {"a",0x0061}, {"b",0x0062}, {"c",0x0063}, {"d",0x0064}, {"e",0x0065}, {"f",0x0066}, - {"g",0x0067}, {"h",0x0068}, {"i",0x0069}, {"j",0x006A}, {"k",0x006B}, {"l",0x006C}, {"m",0x006D}, - {"n",0x006E}, {"o",0x006F}, {"p",0x0070}, {"q",0x0071}, {"r",0x0072}, {"s",0x0073}, {"t",0x0074}, - {"u",0x0075}, {"v",0x0076}, {"w",0x0077}, {"x",0x0078}, {"y",0x0079}, {"z",0x007A}, {"{",0x007B}, + {"=",0x003D}, {">",0x003E}, {"?",0x003F}, {"@",0x0040}, {"^",0x005E}, {"|",0x007C}, {"}",0x007D}, {"~",0x007E}, {" ",0x00A0}, {"¡",0x00A1}, {"¢",0x00A2}, {"£",0x00A3}, {"¤",0x00A4}, {"¥",0x00A5}, {"¦",0x00A6}, {"§",0x00A7}, {"¨",0x00A8}, {"©",0x00A9}, {"ª",0x00AA}, {"«",0x00AB}, {"¬",0x00AC}, {"­",0x00AD}, {"®",0x00AE}, {"¯",0x00AF}, {"°",0x00B0}, {"±",0x00B1}, @@ -279,15 +278,16 @@ static const std::map xUpKeyCodes { {"%", XK_percent}, {"&", XK_ampersand}, {"(", XK_parenleft}, {")", XK_parenright}, {"*", XK_asterisk}, {"+", XK_plus}, {":", XK_colon}, {">", XK_greater}, {"~", XK_asciitilde}, - {"?", XK_question}, {"@", XK_at}, {"^", XK_asciicircum}, {"_", XK_underscore}, + {"?", XK_question}, {"@", XK_at}, {"_", XK_underscore}, {":-D", 0}, }; static const QList qtKeyCodes { {Qt::Key_Backspace, Qt:: Key_Enter, Qt::Key_Return, Qt::Key_Plus, - Qt::Key_Slash, Qt::Key_AsciiCircum, Qt::Key_AsciiTilde, Qt::Key_Equal + Qt::Key_Slash, Qt::Key_Equal } }; + static const QList qtKeyCodes2 { // √ € ™ “ {Qt::Key(8730), Qt::Key(8364), Qt::Key(8482), Qt::Key(8220), -- cgit v1.2.3 From 8e65d5beb9b2494fa853d291f7f57f9754ca0a2c Mon Sep 17 00:00:00 2001 From: Michael Winkelmann Date: Thu, 10 Oct 2019 13:37:27 +0200 Subject: x11vkbwrapper test: Make keyboard movable This test makes the keyboard item moveable via DragHandler. The DragHandler implements a signal handler onTranslationChanged that moves the keyboardWindow accordingly. Change-Id: I2ef6761886ac318b46d6ba2fe422d520a40795e3 Reviewed-by: Mitch Curtis (cherry picked from commit 91a7cabbef952a0f44ac63ec3d5b4cf668288563) Reviewed-by: Jani Heikkinen --- tests/manual/x11vkbwrapper/Keyboard.qml | 91 ++++++++++++++++++++++++++++ tests/manual/x11vkbwrapper/keyboard.qml | 77 ----------------------- tests/manual/x11vkbwrapper/main.cpp | 16 ----- tests/manual/x11vkbwrapper/main.qml | 13 ++-- tests/manual/x11vkbwrapper/qml.qrc | 2 +- tests/manual/x11vkbwrapper/x11vkbwrapper.pro | 2 - 6 files changed, 99 insertions(+), 102 deletions(-) create mode 100644 tests/manual/x11vkbwrapper/Keyboard.qml delete mode 100644 tests/manual/x11vkbwrapper/keyboard.qml diff --git a/tests/manual/x11vkbwrapper/Keyboard.qml b/tests/manual/x11vkbwrapper/Keyboard.qml new file mode 100644 index 00000000..f58e1dca --- /dev/null +++ b/tests/manual/x11vkbwrapper/Keyboard.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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.12 +import QtQuick.Window 2.2 +import QtQuick.VirtualKeyboard 2.2 + +Window { + id: keyboardWindow + width: Screen.width / 2 + height: width / 3.2 + y: Screen.height - height + color: "transparent" + visible: Qt.inputMethod.visible + flags: Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.FramelessWindowHint + + readonly property double scaleFactor: 1.5 + signal languageChangedSignal(string msg) + + Loader { + id: testLoader + sourceComponent: { + if (typeof(QT_TESTING_RUN) !== undefined) { + lang + } + } + } + + Component { + id: lang + Text { + id: langText + visible: false + text: qsTr(Qt.locale(InputContext.locale).nativeLanguageName) + onTextChanged: { + keyboardWindow.languageChangedSignal(langText.text) + } + } + } + + InputPanel { + id: inputPanel + z: 99 + anchors.fill: parent + + DragHandler { + target: null + onTranslationChanged: { + var dx = translation.x + var dy = translation.y + if (keyboardWindow.x < 0) + dx = 0 + if (keyboardWindow.x + keyboardWindow.width > Screen.width) + dx = 0 + if (keyboardWindow.y < 0) + dy = 0 + if (keyboardWindow.y + keyboardWindow.height > Screen.height) + dy = 0 + + keyboardWindow.x += dx + keyboardWindow.y += dy + } + } + } +} diff --git a/tests/manual/x11vkbwrapper/keyboard.qml b/tests/manual/x11vkbwrapper/keyboard.qml deleted file mode 100644 index 02d93769..00000000 --- a/tests/manual/x11vkbwrapper/keyboard.qml +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 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.9 -import QtQuick.Window 2.2 -import QtQuick.VirtualKeyboard 2.2 - -Window { - id: keyboardWindow - width: Screen.width / scaleFactor - height: inputPanel.height + d.alternativeKeySpaceHeight - color: "transparent" - visible: Qt.inputMethod.visible - flags: Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.FramelessWindowHint - - readonly property double scaleFactor: 1.5 - signal languageChangedSignal(string msg) - - QtObject { - id: d - property double alternativeKeySpaceHeight: inputPanel.height / 4.5 - } - - Loader { - id: testLoader - sourceComponent: { - if (typeof(QT_TESTING_RUN) !== undefined) { - lang - } - } - } - - Component { - id: lang - Text { - id: langText - visible: false - text: qsTr(Qt.locale(InputContext.locale).nativeLanguageName) - onTextChanged: { - keyboardWindow.languageChangedSignal(langText.text) - } - } - } - - InputPanel { - id: inputPanel - z: 99 - width: keyboardWindow.width - anchors.bottom: parent.bottom - } -} diff --git a/tests/manual/x11vkbwrapper/main.cpp b/tests/manual/x11vkbwrapper/main.cpp index cb8a25dc..6a914792 100644 --- a/tests/manual/x11vkbwrapper/main.cpp +++ b/tests/manual/x11vkbwrapper/main.cpp @@ -72,7 +72,6 @@ int main(int argc, char *argv[]) /** Setup DBus ends */ QQmlApplicationEngine engine(QStringLiteral("qrc:/main.qml")); - engine.load(QStringLiteral("qrc:/keyboard.qml")); QQmlContext* ctx = engine.rootContext(); @@ -95,21 +94,6 @@ int main(int argc, char *argv[]) } ctx->setContextProperty("atspiFocus", &handleATSPIEvents); - QObject *switchObject = engine.rootObjects().first(); - QObject *keyboardObject = engine.rootObjects().last(); - QScreen *screen = app.primaryScreen(); - QRect screenRect = screen->geometry(); - int x1 = 0; - int y1 = 0; - int x2 = 0; - int y2 = 0; - screenRect.getCoords(&x1, &y1, &x2, &y2); - - switchObject->setProperty("x", x2 - switchObject->property("width").toInt()); - switchObject->setProperty("y", y2 - switchObject->property("height").toInt()); - keyboardObject->setProperty("x", x2 - static_cast(screen->size().rwidth()/keyboardObject->property("scaleFactor").toFloat())); - keyboardObject->setProperty("y", y2 - switchObject->property("height").toInt()); - QObject::connect(extensionHandler, &HandleDbusForChrome::showKeyboard, &handleATSPIEvents, &HandleATSPIEvents::setKeyboardVisible); /** Only for testing purpose*/ diff --git a/tests/manual/x11vkbwrapper/main.qml b/tests/manual/x11vkbwrapper/main.qml index fb5e4dc8..b5a0221f 100644 --- a/tests/manual/x11vkbwrapper/main.qml +++ b/tests/manual/x11vkbwrapper/main.qml @@ -27,16 +27,17 @@ ** ****************************************************************************/ -import QtQuick 2.9 +import QtQuick 2.12 import QtQuick.Window 2.2 - Window { id: window width: d.vkbSwitchSize height: d.vkbSwitchSize + x: Screen.width - width + y: Screen.height - height color: "transparent" - visible: !Qt.inputMethod.visible + visible: true flags: Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.FramelessWindowHint QtObject { @@ -51,10 +52,10 @@ Window { MouseArea { anchors.fill: parent - onClicked: { - atspiFocus.setKeyboardVisible(!Qt.inputMethod.visible) - } + onClicked: atspiFocus.setKeyboardVisible(!Qt.inputMethod.visible) } } + + Keyboard {} } diff --git a/tests/manual/x11vkbwrapper/qml.qrc b/tests/manual/x11vkbwrapper/qml.qrc index 519156ab..b8ccf60e 100644 --- a/tests/manual/x11vkbwrapper/qml.qrc +++ b/tests/manual/x11vkbwrapper/qml.qrc @@ -2,6 +2,6 @@ main.qml graphics/Qt_logo.png - keyboard.qml + Keyboard.qml diff --git a/tests/manual/x11vkbwrapper/x11vkbwrapper.pro b/tests/manual/x11vkbwrapper/x11vkbwrapper.pro index bb954c80..6dc7226f 100644 --- a/tests/manual/x11vkbwrapper/x11vkbwrapper.pro +++ b/tests/manual/x11vkbwrapper/x11vkbwrapper.pro @@ -42,8 +42,6 @@ HEADERS += \ RESOURCES += qml.qrc -OTHER_FILES += main.qml - INCLUDEPATH += /usr/include/X11 INCLUDEPATH += /usr/include/at-spi-2.0 INCLUDEPATH += /usr/lib/x86_64-linux-gnu/glib-2.0/include -- cgit v1.2.3 From 9ce2ec6f6d5516173cfa97d2dd51df2136524470 Mon Sep 17 00:00:00 2001 From: Risto Avila Date: Tue, 12 Nov 2019 09:19:25 +0200 Subject: Fix keyboard being stuck on the sides on OpenBox environment Fixes keyboard being stuck on the sides in OpenBox environment. Change-Id: I70d4cbbe5f49b1851f9010b22a3d89f9e0f04c11 Reviewed-by: Mitch Curtis (cherry picked from commit 32721b77eeaf7645f752a4669c30680a11694fab) Reviewed-by: Jani Heikkinen --- tests/manual/x11vkbwrapper/Keyboard.qml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/manual/x11vkbwrapper/Keyboard.qml b/tests/manual/x11vkbwrapper/Keyboard.qml index f58e1dca..1c2fb046 100644 --- a/tests/manual/x11vkbwrapper/Keyboard.qml +++ b/tests/manual/x11vkbwrapper/Keyboard.qml @@ -74,13 +74,15 @@ Window { onTranslationChanged: { var dx = translation.x var dy = translation.y - if (keyboardWindow.x < 0) + var ksx = keyboardWindow.x + keyboardWindow.width + var ksy = keyboardWindow.y + keyboardWindow.height + if (keyboardWindow.x < 0 && (keyboardWindow.x + dx) < 0) dx = 0 - if (keyboardWindow.x + keyboardWindow.width > Screen.width) + if (ksx > Screen.width && (ksx + dx) > Screen.width) dx = 0 - if (keyboardWindow.y < 0) + if (keyboardWindow.y < 0 && (keyboardWindow.y + dy) < 0) dy = 0 - if (keyboardWindow.y + keyboardWindow.height > Screen.height) + if (ksy > Screen.height && (ksy + dy) > Screen.height) dy = 0 keyboardWindow.x += dx -- cgit v1.2.3 From 565e0c0277c6fe1085f47fea69c0961df8fa75ff Mon Sep 17 00:00:00 2001 From: Michael Winkelmann Date: Thu, 31 Oct 2019 17:47:15 +0100 Subject: Add SystemTrayIcon to X11 manual test Also adds widget dependency because it is required on some platoforms. Change-Id: If699c34bc1b954906fa4a0304387e4f4cab521e8 Reviewed-by: Mitch Curtis (cherry picked from commit e5312d19b5579250f0b79a77f7383504d592685d) Reviewed-by: Jani Heikkinen --- tests/manual/x11vkbwrapper/Keyboard.qml | 12 ++++++++++++ tests/manual/x11vkbwrapper/main.cpp | 6 +++--- tests/manual/x11vkbwrapper/x11vkbwrapper.pro | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/manual/x11vkbwrapper/Keyboard.qml b/tests/manual/x11vkbwrapper/Keyboard.qml index 1c2fb046..4ead6daf 100644 --- a/tests/manual/x11vkbwrapper/Keyboard.qml +++ b/tests/manual/x11vkbwrapper/Keyboard.qml @@ -30,6 +30,7 @@ import QtQuick 2.12 import QtQuick.Window 2.2 import QtQuick.VirtualKeyboard 2.2 +import Qt.labs.platform 1.1 Window { id: keyboardWindow @@ -64,6 +65,17 @@ Window { } } + SystemTrayIcon { + id: qtLogo + icon { + mask: true + source: "graphics/Qt_logo.png" + } + visible: !Qt.inputMethod.visible + onActivated: atspiFocus.setKeyboardVisible(!Qt.inputMethod.visible) + Component.onCompleted: console.log("Found system tray?:",qtLogo.available) + } + InputPanel { id: inputPanel z: 99 diff --git a/tests/manual/x11vkbwrapper/main.cpp b/tests/manual/x11vkbwrapper/main.cpp index 6a914792..1bc5408c 100644 --- a/tests/manual/x11vkbwrapper/main.cpp +++ b/tests/manual/x11vkbwrapper/main.cpp @@ -27,7 +27,7 @@ ** ****************************************************************************/ -#include +#include #include #include #include @@ -52,9 +52,9 @@ int main(int argc, char *argv[]) qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); bool error = false; - QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QGuiApplication app(argc, argv); + QApplication app(argc, argv); /** Setup DBus starts */ auto *extensionHandler = new HandleDbusForChrome(&app); diff --git a/tests/manual/x11vkbwrapper/x11vkbwrapper.pro b/tests/manual/x11vkbwrapper/x11vkbwrapper.pro index 6dc7226f..04978156 100644 --- a/tests/manual/x11vkbwrapper/x11vkbwrapper.pro +++ b/tests/manual/x11vkbwrapper/x11vkbwrapper.pro @@ -1,7 +1,7 @@ TEMPLATE = app TARGET = x11vkbwrapper -QT += qml quick dbus virtualkeyboard svg +QT += qml quick dbus virtualkeyboard svg widgets CONFIG += c++11 static { -- cgit v1.2.3 From 012e4197a6e55fca2e7d69194cac962fa62b56e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pekka=20Geh=C3=B6r?= Date: Wed, 13 Nov 2019 09:31:36 +0200 Subject: Workaround for a alternative characters issue When you use DragHandler all over the InputPanel, it block use a alternative characters. Now you can only use DragHandler at the top of the Window. Change-Id: I4b648ee56af42a7fff136f1961981dd7ef594337 Reviewed-by: Mitch Curtis (cherry picked from commit 851b902b7165b0d43d1327ae53f48c66309f14bb) Reviewed-by: Jukka Jokiniva --- tests/manual/x11vkbwrapper/Keyboard.qml | 40 +++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/tests/manual/x11vkbwrapper/Keyboard.qml b/tests/manual/x11vkbwrapper/Keyboard.qml index 4ead6daf..152bdb98 100644 --- a/tests/manual/x11vkbwrapper/Keyboard.qml +++ b/tests/manual/x11vkbwrapper/Keyboard.qml @@ -35,7 +35,7 @@ import Qt.labs.platform 1.1 Window { id: keyboardWindow width: Screen.width / 2 - height: width / 3.2 + height: width / 2.65 y: Screen.height - height color: "transparent" visible: Qt.inputMethod.visible @@ -44,6 +44,11 @@ Window { readonly property double scaleFactor: 1.5 signal languageChangedSignal(string msg) + QtObject { + id: d + property double alternativeKeySpaceHeight: inputPanel.height / 4.7 + } + Loader { id: testLoader sourceComponent: { @@ -54,13 +59,13 @@ Window { } Component { - id: lang + id: lang Text { id: langText visible: false text: qsTr(Qt.locale(InputContext.locale).nativeLanguageName) onTextChanged: { - keyboardWindow.languageChangedSignal(langText.text) + keyboardWindow.languageChangedSignal(langText.text) } } } @@ -76,11 +81,12 @@ Window { Component.onCompleted: console.log("Found system tray?:",qtLogo.available) } - InputPanel { - id: inputPanel - z: 99 + Rectangle { + id: dragArea anchors.fill: parent - + anchors.bottomMargin: keyboardWindow.height - d.alternativeKeySpaceHeight + color: "#aa444444" + opacity: hoverHandler.hovered ? 1 : 0 DragHandler { target: null onTranslationChanged: { @@ -101,5 +107,25 @@ Window { keyboardWindow.y += dy } } + + HoverHandler { + id: hoverHandler + } + + Behavior on opacity { + NumberAnimation {} + } + Text { + text: "Click here and then drag to move the keyboard" + color: "white" + anchors.horizontalCenter: parent.horizontalCenter + y: (d.alternativeKeySpaceHeight - height) / 2 + } + } + + InputPanel { + id: inputPanel + z: 99 + anchors.fill: parent } } -- cgit v1.2.3 From e34d4ed13c7778a403e4d7c08b84e220deb119af Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Mon, 18 Nov 2019 13:01:22 +0200 Subject: Add changes file for Qt 5.14.0 Change-Id: Ided45d405a65bc3c774ac9855c23e763ea57635b Reviewed-by: Mitch Curtis --- dist/changes-5.14.0 | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 dist/changes-5.14.0 diff --git a/dist/changes-5.14.0 b/dist/changes-5.14.0 new file mode 100644 index 00000000..1a1afa65 --- /dev/null +++ b/dist/changes-5.14.0 @@ -0,0 +1,24 @@ +Qt 5.14 introduces many new features and improvements as well as bugfixes +over the 5.13.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.14 series is binary compatible with the 5.13.x series. +Applications compiled for 5.13 will continue to run with 5.14. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* New Features * +**************************************************************************** + + - Added QT_VIRTUAL_KEYBOARD_FORCE_EVENTS_WITHOUT_FOCUS + environment variable to allow Qt Virtual Keyboard to send key + events and enable the Shift key without a focused input object. -- cgit v1.2.3 From 459ec87b0abdd476d415946ed07c8490c10b97f0 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 4 Dec 2019 12:15:27 +0100 Subject: Fix warnings about Binding's new restoreMode property The warning is: QML Binding: Not restoring previous value because restoreMode has not been set. This behavior is deprecated. In Qt < 6.0 the default is Binding.RestoreBinding. In Qt >= 6.0 the default is Binding.RestoreBindingOrValue. Fixes: QTBUG-80523 Change-Id: I18721419c2822aa80373d16f7e142e42bafe317c Reviewed-by: Fabian Kosmale --- examples/virtualkeyboard/basic/basic-b2qt.qml | 5 +++++ src/virtualkeyboard/content/HandwritingInputPanel.qml | 4 ++++ src/virtualkeyboard/content/InputPanel.qml | 3 +++ src/virtualkeyboard/content/components/Keyboard.qml | 7 +++++++ src/virtualkeyboard/content/components/ShadowInputControl.qml | 3 +++ src/virtualkeyboard/content/components/WordCandidatePopupList.qml | 4 ++++ 6 files changed, 26 insertions(+) diff --git a/examples/virtualkeyboard/basic/basic-b2qt.qml b/examples/virtualkeyboard/basic/basic-b2qt.qml index 59c64b86..9d7a0dd3 100644 --- a/examples/virtualkeyboard/basic/basic-b2qt.qml +++ b/examples/virtualkeyboard/basic/basic-b2qt.qml @@ -28,6 +28,8 @@ ****************************************************************************/ import QtQuick 2.0 +// Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6. +import QtQml 2.14 import QtQuick.Window 2.2 import QtQuick.VirtualKeyboard 2.2 import QtQuick.VirtualKeyboard.Settings 2.2 @@ -141,6 +143,8 @@ Item { target: InputContext property: "animating" value: inputPanelTransition.running + restoreMode: Binding.RestoreBinding + } AutoScroller {} } @@ -149,6 +153,7 @@ Item { target: VirtualKeyboardSettings property: "fullScreenMode" value: appContainer.height > 0 && (appContainer.width / appContainer.height) > (16.0 / 9.0) + restoreMode: Binding.RestoreBinding } } } diff --git a/src/virtualkeyboard/content/HandwritingInputPanel.qml b/src/virtualkeyboard/content/HandwritingInputPanel.qml index 940fe915..4fe4fbc3 100644 --- a/src/virtualkeyboard/content/HandwritingInputPanel.qml +++ b/src/virtualkeyboard/content/HandwritingInputPanel.qml @@ -28,6 +28,8 @@ ****************************************************************************/ import QtQuick 2.0 +// Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6. +import QtQml 2.14 import QtQuick.Window 2.2 import QtQuick.VirtualKeyboard 2.1 @@ -117,6 +119,7 @@ Item { property: "keyboardRectangle" value: Qt.rect(hwrInputArea.x, hwrInputArea.y, hwrInputArea.width, hwrInputArea.height) when: handwritingInputPanel.enabled && handwritingInputPanel.available && handwritingInputPanel.active + restoreMode: Binding.RestoreBinding } Binding { @@ -124,6 +127,7 @@ Item { property: "active" value: false when: handwritingInputPanel.enabled && handwritingInputPanel.available + restoreMode: Binding.RestoreBinding } WordCandidatePopupList { diff --git a/src/virtualkeyboard/content/InputPanel.qml b/src/virtualkeyboard/content/InputPanel.qml index 45e0c372..b10fef21 100644 --- a/src/virtualkeyboard/content/InputPanel.qml +++ b/src/virtualkeyboard/content/InputPanel.qml @@ -28,6 +28,8 @@ ****************************************************************************/ import QtQuick 2.0 +// Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6. +import QtQml 2.14 import QtQuick.VirtualKeyboard 2.1 /*! @@ -143,5 +145,6 @@ Item { keyboard.width, keyboard.height - keyboard.wordCandidateView.currentYOffset + (keyboard.shadowInputControl.visible ? keyboard.shadowInputControl.height : 0)) when: !InputContext.animating + restoreMode: Binding.RestoreBinding } } diff --git a/src/virtualkeyboard/content/components/Keyboard.qml b/src/virtualkeyboard/content/components/Keyboard.qml index da064820..1c6f174f 100644 --- a/src/virtualkeyboard/content/components/Keyboard.qml +++ b/src/virtualkeyboard/content/components/Keyboard.qml @@ -28,6 +28,8 @@ ****************************************************************************/ import QtQuick 2.0 +// Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6. +import QtQml 2.14 import QtQuick.Layouts 1.0 import QtQuick.Window 2.2 import QtQuick.VirtualKeyboard 2.3 @@ -542,17 +544,20 @@ Item { property: "previewRectangle" value: characterPreview.previewRect when: characterPreview.visible + restoreMode: Binding.RestoreBinding } Binding { target: InputContext.priv property: "previewRectangle" value: languagePopupList.previewRect when: languagePopupListActive + restoreMode: Binding.RestoreBinding } Binding { target: InputContext.priv property: "previewVisible" value: characterPreview.visible || languagePopupListActive + restoreMode: Binding.RestoreBinding } Loader { id: styleLoader @@ -561,6 +566,7 @@ Item { target: styleLoader.item property: "keyboardHeight" value: keyboardInnerContainer.height + restoreMode: Binding.RestoreBinding } } Loader { @@ -820,6 +826,7 @@ Item { property: "source" value: keyboard.layout when: keyboard.layout.length > 0 + restoreMode: Binding.RestoreBinding } onItemChanged: { diff --git a/src/virtualkeyboard/content/components/ShadowInputControl.qml b/src/virtualkeyboard/content/components/ShadowInputControl.qml index a059c40e..caa835ea 100644 --- a/src/virtualkeyboard/content/components/ShadowInputControl.qml +++ b/src/virtualkeyboard/content/components/ShadowInputControl.qml @@ -28,6 +28,8 @@ ****************************************************************************/ import QtQuick 2.7 +// Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6. +import QtQml 2.14 import QtQuick.VirtualKeyboard 2.2 import QtQuick.VirtualKeyboard.Settings 2.2 @@ -134,5 +136,6 @@ Item { property: "inputItem" value: shadowInput when: VirtualKeyboardSettings.fullScreenMode + restoreMode: Binding.RestoreBinding } } diff --git a/src/virtualkeyboard/content/components/WordCandidatePopupList.qml b/src/virtualkeyboard/content/components/WordCandidatePopupList.qml index e255142a..5790bc74 100644 --- a/src/virtualkeyboard/content/components/WordCandidatePopupList.qml +++ b/src/virtualkeyboard/content/components/WordCandidatePopupList.qml @@ -28,6 +28,8 @@ ****************************************************************************/ import QtQuick 2.0 +// Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6. +import QtQml 2.14 import QtQuick.VirtualKeyboard 2.3 PopupList { @@ -55,12 +57,14 @@ PopupList { (wordCandidatePopupList.currentItem.hasOwnProperty("cursorAnchor") ? wordCandidatePopupList.currentItem.cursorAnchor : wordCandidatePopupList.currentItem.width) : 0)) when: wordCandidatePopupList.visible + restoreMode: Binding.RestoreBinding } Binding { target: wordCandidatePopupList property: "y" value: Math.round(wordCandidatePopupList.flipVertical ? Qt.inputMethod.cursorRectangle.y - wordCandidatePopupList.height : Qt.inputMethod.cursorRectangle.y + Qt.inputMethod.cursorRectangle.height) when: wordCandidatePopupList.visible + restoreMode: Binding.RestoreBinding } model: enabled ? InputContext.inputEngine.wordCandidateListModel : null -- cgit v1.2.3