aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--dist/changes-5.12.1025
-rw-r--r--dist/changes-5.15.127
-rw-r--r--dist/changes-5.15.220
-rw-r--r--examples/virtualkeyboard/basic/basic-b2qt.qml2
-rw-r--r--src/plugin/plugin.cpp9
-rw-r--r--src/plugin/plugin.pro1
-rw-r--r--src/plugins/openwnn/plugin/openwnninputmethod.cpp7
-rw-r--r--src/plugins/pinyin/3rdparty/pinyin/share/splparser.cpp8
-rw-r--r--src/plugins/pinyin/plugin/pinyininputmethod.cpp8
-rw-r--r--src/virtualkeyboard/content/InputPanel.qml32
-rw-r--r--src/virtualkeyboard/content/components/ShadowInputControl.qml5
-rw-r--r--src/virtualkeyboard/desktopinputpanel.cpp49
-rw-r--r--src/virtualkeyboard/doc/src/deployment-guide.qdoc26
-rw-r--r--src/virtualkeyboard/doc/src/technical-guide.qdoc74
-rw-r--r--src/virtualkeyboard/platforminputcontext.cpp27
-rw-r--r--src/virtualkeyboard/platforminputcontext_p.h1
-rw-r--r--src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp39
-rw-r--r--src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h2
-rw-r--r--src/virtualkeyboard/qvirtualkeyboardinputengine.cpp6
-rw-r--r--src/virtualkeyboard/virtualkeyboard.pro4
-rw-r--r--src/virtualkeyboard/virtualkeyboardsettings.cpp1
-rw-r--r--tests/auto/inputpanel/BLACKLIST28
-rw-r--r--tests/auto/inputpanel/data/tst_inputpanel.qml48
24 files changed, 329 insertions, 122 deletions
diff --git a/.qmake.conf b/.qmake.conf
index b3c7403c..33171164 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,4 +2,4 @@ load(qt_build_config)
DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS QT_NO_LINKED_LIST
-MODULE_VERSION = 5.15.0
+MODULE_VERSION = 5.15.13
diff --git a/dist/changes-5.12.10 b/dist/changes-5.12.10
new file mode 100644
index 00000000..176de042
--- /dev/null
+++ b/dist/changes-5.12.10
@@ -0,0 +1,25 @@
+Qt 5.12.10 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.12.9.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+ https://doc.qt.io/qt-5.12/index.html
+
+The Qt version 5.12 series is binary compatible with the 5.11.x series.
+Applications compiled for 5.11 will continue to run with 5.12.
+
+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.
+
+****************************************************************************
+* Library *
+****************************************************************************
+
+ - [QTBUG-74664] Fixed cursor position for Japanese input when a suggestion
+ is selected.
diff --git a/dist/changes-5.15.1 b/dist/changes-5.15.1
new file mode 100644
index 00000000..ed49438e
--- /dev/null
+++ b/dist/changes-5.15.1
@@ -0,0 +1,27 @@
+Qt 5.15.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.15.0.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+ https://doc.qt.io/qt-5.15/index.html
+
+The Qt version 5.15 series is binary compatible with the 5.14.x series.
+Applications compiled for 5.14 will continue to run with 5.15.
+
+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.
+
+****************************************************************************
+* Library *
+****************************************************************************
+
+ - [QTBUG-83217] Fixed InputPanel position in b2qt example in portrait mode.
+ - [QTBUG-74664] Fixed cursor position in Japanese input.
+ - [QTBUG-83187] Fixed static build when using disable-layouts and
+ no-builtin-style.
diff --git a/dist/changes-5.15.2 b/dist/changes-5.15.2
new file mode 100644
index 00000000..c8cfa78e
--- /dev/null
+++ b/dist/changes-5.15.2
@@ -0,0 +1,20 @@
+Qt 5.15.2 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.15.1.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+ https://doc.qt.io/qt-5.15/index.html
+
+The Qt version 5.15 series is binary compatible with the 5.14.x series.
+Applications compiled for 5.14 will continue to run with 5.15.
+
+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.
+
+ - This release contains only minor code improvements.
diff --git a/examples/virtualkeyboard/basic/basic-b2qt.qml b/examples/virtualkeyboard/basic/basic-b2qt.qml
index 107e7a0c..1e5ed0bf 100644
--- a/examples/virtualkeyboard/basic/basic-b2qt.qml
+++ b/examples/virtualkeyboard/basic/basic-b2qt.qml
@@ -49,7 +49,7 @@ Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
- anchors.bottom: parent.bottom
+ anchors.bottom: inputPanel.top
handwritingInputPanelActive: handwritingInputPanel.available && handwritingInputPanel.active
}
diff --git a/src/plugin/plugin.cpp b/src/plugin/plugin.cpp
index 122a671d..d5762fe0 100644
--- a/src/plugin/plugin.cpp
+++ b/src/plugin/plugin.cpp
@@ -34,6 +34,9 @@
#include <QtVirtualKeyboard/private/qvirtualkeyboard_staticplugin_p.h>
#include <QLoggingCategory>
#include <QtQml>
+#if defined(Q_OS_WIN)
+#include <qt_windows.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -73,6 +76,12 @@ QPlatformInputContext *QVirtualKeyboardPlugin::create(const QString &system, con
if (system.compare(system, QLatin1String(pluginName), Qt::CaseInsensitive) != 0)
return Q_NULLPTR;
+
+#if defined(Q_OS_WIN)
+ // QTBUG-93042
+ ImmDisableIME(0);
+#endif
+
PlatformInputContext *platformInputContext = new PlatformInputContext();
QStringList inputMethodList;
diff --git a/src/plugin/plugin.pro b/src/plugin/plugin.pro
index defb3747..f974fe45 100644
--- a/src/plugin/plugin.pro
+++ b/src/plugin/plugin.pro
@@ -28,6 +28,7 @@ disable-layouts {
win32 {
QMAKE_TARGET_PRODUCT = "Qt Virtual Keyboard (Qt $$QT_VERSION)"
QMAKE_TARGET_DESCRIPTION = "Virtual Keyboard for Qt."
+ LIBS += -limm32
}
PLUGIN_TYPE = platforminputcontexts
diff --git a/src/plugins/openwnn/plugin/openwnninputmethod.cpp b/src/plugins/openwnn/plugin/openwnninputmethod.cpp
index efe68a1e..c54cecb7 100644
--- a/src/plugins/openwnn/plugin/openwnninputmethod.cpp
+++ b/src/plugins/openwnn/plugin/openwnninputmethod.cpp
@@ -805,6 +805,7 @@ void OpenWnnInputMethod::selectionListItemSelected(QVirtualKeyboardSelectionList
{
Q_UNUSED(type)
Q_D(OpenWnnInputMethod);
+ d->activeWordIndex = index;
// Set selected text as preeditText to place cursor at the end of selected text
inputContext()->setPreeditText(d->candidateList.at(index)->candidate);
d->commitText(*d->candidateList.at(index));
@@ -813,7 +814,7 @@ void OpenWnnInputMethod::selectionListItemSelected(QVirtualKeyboardSelectionList
void OpenWnnInputMethod::reset()
{
Q_D(OpenWnnInputMethod);
- d->commitAll();
+ d->composingText.clear();
d->initializeScreen();
d->fitInputType();
}
@@ -821,8 +822,10 @@ void OpenWnnInputMethod::reset()
void OpenWnnInputMethod::update()
{
Q_D(OpenWnnInputMethod);
- if (!d->disableUpdate)
+ if (!d->disableUpdate) {
+ d->commitAll();
reset();
+ }
}
} // namespace QtVirtualKeyboard
diff --git a/src/plugins/pinyin/3rdparty/pinyin/share/splparser.cpp b/src/plugins/pinyin/3rdparty/pinyin/share/splparser.cpp
index d75aec6a..96405d2e 100644
--- a/src/plugins/pinyin/3rdparty/pinyin/share/splparser.cpp
+++ b/src/plugins/pinyin/3rdparty/pinyin/share/splparser.cpp
@@ -133,9 +133,9 @@ uint16 SpellingParser::splstr_to_idxs(const char *splstr, uint16 str_len,
idx_num++;
if (NULL != start_pos)
start_pos[idx_num] = str_pos;
- }
- last_is_pre = !last_is_splitter;
+ last_is_pre = !last_is_splitter;
+ }
return idx_num;
}
@@ -262,9 +262,9 @@ uint16 SpellingParser::splstr16_to_idxs(const char16 *splstr, uint16 str_len,
idx_num++;
if (NULL != start_pos)
start_pos[idx_num] = str_pos;
- }
- last_is_pre = !last_is_splitter;
+ last_is_pre = !last_is_splitter;
+ }
return idx_num;
}
diff --git a/src/plugins/pinyin/plugin/pinyininputmethod.cpp b/src/plugins/pinyin/plugin/pinyininputmethod.cpp
index cdd7d218..98d8c513 100644
--- a/src/plugins/pinyin/plugin/pinyininputmethod.cpp
+++ b/src/plugins/pinyin/plugin/pinyininputmethod.cpp
@@ -73,7 +73,7 @@ public:
QVirtualKeyboardInputContext *inputContext = q->inputContext();
// Disable the user dictionary when entering sensitive data
- if (inputContext) {
+ if (inputContext && pinyinDecoderService) {
bool userDictionaryEnabled = !inputContext->inputMethodHints().testFlag(Qt::ImhSensitiveData);
if (userDictionaryEnabled != pinyinDecoderService->isUserDictionaryEnabled())
pinyinDecoderService->setUserDictionary(userDictionaryEnabled);
@@ -134,8 +134,8 @@ public:
if (composingStr.length() > 0) {
if ((candId >= 0 || finishSelection) && composingStr.length() == fixedLen) {
QString resultStr = getComposingStrActivePart();
- tryPredict();
q->inputContext()->commit(resultStr);
+ tryPredict();
} else if (state == Idle) {
state = Input;
}
@@ -229,12 +229,12 @@ public:
activeCmpsLen = activeCmpsLen - (surface.length() - surfaceDecodedLen);
composingStrDisplay = fullSent.mid(0, fixedLen);
for (int pos = fixedLen + 1; pos < splStart.size() - 1; pos++) {
- composingStrDisplay += surface.mid(splStart[pos], splStart[pos + 1] - splStart[pos]).toUpper();
+ composingStrDisplay += surface.mid(splStart[pos], splStart[pos + 1] - splStart[pos]);
if (splStart[pos + 1] < surfaceDecodedLen)
composingStrDisplay += QLatin1String(" ");
}
if (surfaceDecodedLen < surface.length())
- composingStrDisplay += surface.mid(surfaceDecodedLen).toLower();
+ composingStrDisplay += surface.mid(surfaceDecodedLen);
}
q->inputContext()->setPreeditText(composingStrDisplay);
diff --git a/src/virtualkeyboard/content/InputPanel.qml b/src/virtualkeyboard/content/InputPanel.qml
index f511eab2..dd14fca6 100644
--- a/src/virtualkeyboard/content/InputPanel.qml
+++ b/src/virtualkeyboard/content/InputPanel.qml
@@ -48,6 +48,17 @@ import QtQuick.VirtualKeyboard 2.1
the module, the \c QT_IM_MODULE environment variable must be set to
\c qtvirtualkeyboard before using InputPanel. For more information, see
\l {Loading the Plugin}.
+
+ \note You can have only one InputPanel instance in your application.
+
+ \section2 InputPanel and modal dialogs
+
+ Qt prevents modal popups from blocking the keyboard UI, as this would make it
+ impossible to use the keyboard to write into a text field within a modal popup.
+ When an input field receives focus during a modal session, the InputPanel item is
+ made a sibling of the Overlay, and given a z-value one above the Overlay's so that
+ it stays on top of the user interface. When the modal session ends, the item is
+ reparented back to the original parent, and the z-value is restored.
*/
Item {
@@ -126,6 +137,7 @@ Item {
implicitHeight: keyboard.height
Keyboard {
id: keyboard
+ readonly property real yOffset: keyboard.wordCandidateView.currentYOffset - (keyboard.shadowInputControl.visible ? keyboard.shadowInputControl.height : 0)
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
@@ -139,12 +151,22 @@ Item {
Binding {
target: InputContext.priv
property: "keyboardRectangle"
- value: mapToItem(null,
- desktopPanel ? keyboard.x : x,
- (desktopPanel ? keyboard.y : y) + keyboard.wordCandidateView.currentYOffset - (keyboard.shadowInputControl.visible ? keyboard.shadowInputControl.height : 0),
- keyboard.width,
- keyboard.height - keyboard.wordCandidateView.currentYOffset + (keyboard.shadowInputControl.visible ? keyboard.shadowInputControl.height : 0))
+ value: keyboardRectangle()
when: !InputContext.animating
restoreMode: Binding.RestoreBinding
}
+
+ /*! \internal */
+ function keyboardRectangle() {
+ var rect = Qt.rect(0, keyboard.yOffset, keyboard.width, keyboard.height - keyboard.yOffset)
+ if (desktopPanel) {
+ rect.x += keyboard.x
+ rect.y += keyboard.y
+ }
+ // Read the inputPanel position.
+ // This ensures that the Binding works.
+ var unusedX = inputPanel.x
+ var unusedY = inputPanel.y
+ return mapToItem(null, rect)
+ }
}
diff --git a/src/virtualkeyboard/content/components/ShadowInputControl.qml b/src/virtualkeyboard/content/components/ShadowInputControl.qml
index e3cde2e1..9faa1c01 100644
--- a/src/virtualkeyboard/content/components/ShadowInputControl.qml
+++ b/src/virtualkeyboard/content/components/ShadowInputControl.qml
@@ -94,7 +94,8 @@ Item {
onCursorPositionChanged: {
cursorSyncTimer.restart()
blinkStatus = true
- cursorTimer.restart()
+ if (cursorTimer.running)
+ cursorTimer.restart()
}
onSelectionStartChanged: cursorSyncTimer.restart()
onSelectionEndChanged: cursorSyncTimer.restart()
@@ -123,7 +124,7 @@ Item {
id: cursorTimer
interval: Qt.styleHints.cursorFlashTime / 2
repeat: true
- running: true
+ running: control.visible
onTriggered: shadowInput.blinkStatus = !shadowInput.blinkStatus
}
}
diff --git a/src/virtualkeyboard/desktopinputpanel.cpp b/src/virtualkeyboard/desktopinputpanel.cpp
index aee0f100..8484d181 100644
--- a/src/virtualkeyboard/desktopinputpanel.cpp
+++ b/src/virtualkeyboard/desktopinputpanel.cpp
@@ -37,10 +37,6 @@
#include <QQmlEngine>
#include <QScreen>
#include <QtVirtualKeyboard/private/virtualkeyboarddebug_p.h>
-#if defined(QT_VIRTUALKEYBOARD_HAVE_XCB)
-#include <xcb/xcb.h>
-#include <xcb/xfixes.h>
-#endif
#include <qpa/qplatformnativeinterface.h>
#include <QtCore/private/qobject_p.h>
#include <QtCore/QLibraryInfo>
@@ -225,18 +221,6 @@ void DesktopInputPanel::previewVisibleChanged()
updateInputRegion();
}
-#if defined(QT_VIRTUALKEYBOARD_HAVE_XCB)
-static inline xcb_rectangle_t qRectToXCBRectangle(const QRect &r)
-{
- xcb_rectangle_t result;
- result.x = qMax(SHRT_MIN, r.x());
- result.y = qMax(SHRT_MIN, r.y());
- result.width = qMin((int)USHRT_MAX, r.width());
- result.height = qMin((int)USHRT_MAX, r.height());
- return result;
-}
-#endif
-
void DesktopInputPanel::updateInputRegion()
{
Q_D(DesktopInputPanel);
@@ -248,36 +232,11 @@ void DesktopInputPanel::updateInputRegion()
if (!d->view->handle())
d->view->create();
- switch (d->windowingSystem) {
- case DesktopInputPanelPrivate::Xcb:
-#if defined(QT_VIRTUALKEYBOARD_HAVE_XCB)
- {
- QVector<xcb_rectangle_t> rects;
- rects.push_back(qRectToXCBRectangle(d->keyboardRect.toRect()));
- if (d->previewVisible && !d->previewRect.isEmpty())
- rects.push_back(qRectToXCBRectangle(d->previewRect.toRect()));
-
- QWindow *window = d->view.data();
- QPlatformNativeInterface *platformNativeInterface = QGuiApplication::platformNativeInterface();
- xcb_connection_t *xbcConnection = static_cast<xcb_connection_t *>(platformNativeInterface->nativeResourceForWindow("connection", window));
- xcb_xfixes_region_t xbcRegion = xcb_generate_id(xbcConnection);
- xcb_xfixes_create_region(xbcConnection, xbcRegion, rects.size(), rects.constData());
- xcb_xfixes_set_window_shape_region(xbcConnection, window->winId(), XCB_SHAPE_SK_INPUT, 0, 0, xbcRegion);
- xcb_xfixes_destroy_region(xbcConnection, xbcRegion);
- }
-#endif
- break;
+ QRegion inputRegion(d->keyboardRect.toRect());
+ if (d->previewVisible && !d->previewRect.isEmpty())
+ inputRegion += d->previewRect.toRect();
- default:
- {
- QRegion inputRegion(d->keyboardRect.toRect());
- if (d->previewVisible && !d->previewRect.isEmpty())
- inputRegion += d->previewRect.toRect();
-
- d->view->setMask(inputRegion);
- break;
- }
- }
+ d->view->setMask(inputRegion);
}
} // namespace QtVirtualKeyboard
diff --git a/src/virtualkeyboard/doc/src/deployment-guide.qdoc b/src/virtualkeyboard/doc/src/deployment-guide.qdoc
index d7ea786c..1437eb41 100644
--- a/src/virtualkeyboard/doc/src/deployment-guide.qdoc
+++ b/src/virtualkeyboard/doc/src/deployment-guide.qdoc
@@ -34,7 +34,7 @@
\section1 Overview
This document describes how to deploy and use the Qt Virtual Keyboard plugin
-with Qt 5 applications.
+with Qt applications.
\section1 Deployment
@@ -48,31 +48,41 @@ locations:
\li Boot2Qt install path
\row
\li qtvirtualkeyboardplugin
- \li \c $$[QT_INSTALL_PLUGINS]/platforminputcontexts
+ \li \c <QT_INSTALL_PLUGINS>/platforminputcontexts
\li \c /system/plugins/platforminputcontexts
\row
\li qtvirtualkeyboardextensionplugin
- \li \c $$[QT_INSTALL_PLUGINS]/virtualkeyboard
+ \li \c <QT_INSTALL_PLUGINS>/virtualkeyboard
\li \c /system/plugins/virtualkeyboard
\row
\li qtvirtualkeyboardplugin QML files
- \li \c $$[QT_INSTALL_QML]/QtQuick/VirtualKeyboard
+ \li \c <QT_INSTALL_QML>/QtQuick/VirtualKeyboard
\li \c /system/qml/QtQuick/VirtualKeyboard
\row
\li qtvirtualkeyboardstylesplugin
- \li \c $$[QT_INSTALL_QML]/QtQuick/VirtualKeyboard/Styles
+ \li \c <QT_INSTALL_QML>/QtQuick/VirtualKeyboard/Styles
\li \c /system/qml/QtQuick/VirtualKeyboard/Styles
\endtable
+\section2 Dependencies
+
+The Qt Virtual Keyboard plugin \e (qtvirtualkeyboardplugin) has a dependency
+to the \e {libQt\QtMajorVersion}\e{\VirtualKeyboard} library. In addition, the
+plugin depends on Qt Quick. Therefore, a stand-alone application based on
+\l [QtWidgets] {Qt Widgets} must deploy also the
+\e {libQt\QtMajorVersion}\e{Quick} library and its dependencies in order to
+use the virtual keyboard.
+
+Read more at \l {Deploying Qt's Libraries}.
+
\section1 Integration Method
Qt Virtual Keyboard currently supports two alternative integration methods
for using the plugin:
\list
- \li \c Desktop: requires no changes to existing applications.
- The virtual keyboard is available to all of the Qt 5 applications
- in the system.
+ \li \c Desktop: requires no changes to existing applications. The virtual
+ keyboard is available to all Qt applications in the system.
In this integration method, the keyboard is shown in a dedicated
top-level window.
diff --git a/src/virtualkeyboard/doc/src/technical-guide.qdoc b/src/virtualkeyboard/doc/src/technical-guide.qdoc
index 91711447..3762c59c 100644
--- a/src/virtualkeyboard/doc/src/technical-guide.qdoc
+++ b/src/virtualkeyboard/doc/src/technical-guide.qdoc
@@ -87,46 +87,68 @@ from the application. This information includes, but is not limited to:
\section2 Locale
-The list of supported locales is specified by the existence of a locale specific
-layout directory in "layouts/*". Each layout directory may contain one
-or more layouts, for example fi_FI/main.qml or symbols.qml. If the locale specific
-layout is not different from the fallback locale, then a place holder file \c
-<layout type>.fallback can be added for the layout. This will specify the virtual
-keyboard that a fallback layout can be used instead.
+The Virtual Keyboard Engine generates the list of supported locales from
+locale-specific layout directories in \c {layouts/}. Each layout directory
+must contain a definition or fallback for the following layout types:
+\e dialpad, \e digits, \e handwriting, \e main, \e numbers, and \e symbols.
+Definitions are implemented in \c {.qml}-files, fallbacks are defined by a
+placeholder file with the \c {.fallback} file extension. The \c {layouts/}
+directory must contain a \c {fallback/} sub-directory that contains definitions
+for each layout type.
+
+Each layout directory may contain the definition of one or more layout types.
+If the locale-specific layout is the same as that of the fallback locale, you
+can add a placeholder file for the layout called \c {<layout type>.fallback}.
+This instructs the virtual keyboard to use the fallback layout instead.
+
+For example: you may add a locale-specific layout for Finnish, that defines the
+main layout type in \c {main.qml}. For the other layout types, you opt for the
+fallback mechanism. Your \c {layouts/} tree will look like this:
-At minimum the layout directory must contain the files:
+\badcode
+.
+├── fallback
+│   ├── dialpad.qml
+│   ├── digits.qml
+│   ├── handwriting.qml
+│   ├── main.qml
+│   ├── numbers.qml
+│   └── symbols.qml
+└── fi_FI
+ ├── dialpad.fallback
+ ├── digits.fallback
+ ├── handwriting.fallback
+ ├── main.qml
+ ├── numbers.fallback
+ └── symbols.fallback
+\endcode
-\list
- \li \c dialpad.fallback
- \li \c digits.fallback
- \li \c main.fallback
- \li \c numbers.fallback
- \li \c symbols.fallback
-\endlist
+It's imperative that the \c {layouts/fallback} directory always contain a set
+of full implementation files.
The application can specify the initial layout by changing the default locale.
-However, this needs to be done before the application is initialized and the
-input method plugin is loaded. If no changes are made to the default locale, the
-current system locale is used.
+However, this must be done before the application initializes and loads the
+input method plugin. If there are no changes to the default locale, the current
+system locale is used.
-The keyboard locale matching is performed in the following sequence:
+Matching the keyboard locale follows this sequence:
\list
- \li layouts/<language>_<country>
- \li layouts/<language>_*
- \li layouts/en_GB
+ \li \c {layouts/<language>_<country>}
+ \li \c {layouts/<language>_*}
+ \li \c {layouts/fallback} -- the default layout here is \e en_GB.
\endlist
-The locale is first matched against the full locale name. If a full match is
-not found, then only the locale language is matched. If a partial match is
-not found, then the "en_GB" locale is used as a fallback.
+First, the locale is matched against the full locale name. If a there isn't a
+full match, then only the locale language is matched. Finally, the contents of
+\c {layouts/fallback} is used as a fallback when there's also no partial match.
After the locale selection is done, the keyboard updates the input locale and
input direction to match the current layout. The application can receive this
information through the QInputMethod interface.
-Internally, the current input locale is also updated to the QVirtualKeyboardInputEngine
-and the current input method instances.
+Internally, the current input locale is also updated to
+QVirtualKeyboardInputEngine and the current input method instances.
\section1 Input Engine
diff --git a/src/virtualkeyboard/platforminputcontext.cpp b/src/virtualkeyboard/platforminputcontext.cpp
index eef26574..c56e21ff 100644
--- a/src/virtualkeyboard/platforminputcontext.cpp
+++ b/src/virtualkeyboard/platforminputcontext.cpp
@@ -96,7 +96,7 @@ void PlatformInputContext::commit()
void PlatformInputContext::update(Qt::InputMethodQueries queries)
{
VIRTUALKEYBOARD_DEBUG() << "PlatformInputContext::update():" << queries;
- bool enabled = inputMethodQuery(Qt::ImEnabled).toBool();
+ const bool enabled = inputMethodAccepted();
#ifdef QT_VIRTUALKEYBOARD_DESKTOP
if (enabled && !m_inputPanel && !m_desktopModeDisabled) {
m_inputPanel = new DesktopInputPanel(this);
@@ -110,14 +110,10 @@ void PlatformInputContext::update(Qt::InputMethodQueries queries)
}
#endif
if (m_inputContext) {
- if (enabled) {
+ if (enabled)
m_inputContext->priv()->update(queries);
- if (m_visible)
- updateInputPanelVisible();
- } else {
- hideInputPanel();
- }
m_inputContext->priv()->setFocus(enabled);
+ updateInputPanelVisible();
}
}
@@ -285,6 +281,16 @@ void PlatformInputContext::setInputContext(QVirtualKeyboardInputContext *context
}
}
+bool PlatformInputContext::evaluateInputPanelVisible() const
+{
+ // Show input panel when input panel is requested by showInputPanel()
+ // and focus object is set to an input control with input method accepted (Qt::ImEnabled)
+ // or input events without focus are enabled.
+ return m_visible &&
+ ((m_focusObject && inputMethodAccepted()) ||
+ QT_VIRTUALKEYBOARD_FORCE_EVENTS_WITHOUT_FOCUS);
+}
+
void PlatformInputContext::keyboardRectangleChanged()
{
m_inputPanel->setInputRect(m_inputContext->priv()->keyboardRectangle().toRect());
@@ -295,13 +301,14 @@ void PlatformInputContext::updateInputPanelVisible()
if (!m_inputPanel)
return;
- if (m_visible != m_inputPanel->isVisible()) {
- if (m_visible)
+ const bool visible = evaluateInputPanelVisible();
+ if (visible != m_inputPanel->isVisible()) {
+ if (visible)
m_inputPanel->show();
else
m_inputPanel->hide();
if (m_selectionControl)
- m_selectionControl->setEnabled(m_visible);
+ m_selectionControl->setEnabled(visible);
emitInputPanelVisibleChanged();
}
}
diff --git a/src/virtualkeyboard/platforminputcontext_p.h b/src/virtualkeyboard/platforminputcontext_p.h
index e7d29405..efc3f08a 100644
--- a/src/virtualkeyboard/platforminputcontext_p.h
+++ b/src/virtualkeyboard/platforminputcontext_p.h
@@ -101,6 +101,7 @@ protected:
void sendKeyEvent(QKeyEvent *event);
QVariant inputMethodQuery(Qt::InputMethodQuery query);
void setInputContext(QVirtualKeyboardInputContext *context);
+ bool evaluateInputPanelVisible() const;
private slots:
void keyboardRectangleChanged();
diff --git a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp
index a7c0aad9..2069f64e 100644
--- a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp
+++ b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp
@@ -220,8 +220,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(std::numeric_limits<qreal>::max());
}
void QVirtualKeyboardInputContextPrivate::hideInputPanel()
@@ -278,8 +276,25 @@ void QVirtualKeyboardInputContextPrivate::onInputItemChanged()
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 (isDesktopPanel.isValid() && !isDesktopPanel.toBool())
- vkbPanel->setParentItem(quickItem->window()->contentItem());
+ if (isDesktopPanel.isValid() && !isDesktopPanel.toBool()) {
+ 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;
+ }
+ }
+ }
+ }
}
}
} else {
@@ -391,7 +406,7 @@ void QVirtualKeyboardInputContextPrivate::update(Qt::InputMethodQueries queries)
bool newCursorPosition = cursorPosition != this->cursorPosition;
bool newAnchorRectangle = anchorRectangle != this->anchorRectangle;
bool newCursorRectangle = cursorRectangle != this->cursorRectangle;
- bool selectionControlVisible = platformInputContext->isInputPanelVisible() && (cursorPosition != anchorPosition) && !inputMethodHints.testFlag(Qt::ImhNoTextHandles);
+ bool selectionControlVisible = platformInputContext->evaluateInputPanelVisible() && (cursorPosition != anchorPosition) && !inputMethodHints.testFlag(Qt::ImhNoTextHandles);
bool newSelectionControlVisible = selectionControlVisible != this->selectionControlVisible;
QRectF inputItemClipRect = imQueryEvent.value(Qt::ImInputItemClipRectangle).toRectF();
@@ -505,6 +520,7 @@ bool QVirtualKeyboardInputContextPrivate::filterEvent(const QEvent *event)
QEvent::Type type = event->type();
if (type == QEvent::KeyPress || type == QEvent::KeyRelease) {
const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
+ const int key = keyEvent->key();
// Keep track of pressed keys update key event state
if (type == QEvent::KeyPress)
@@ -518,7 +534,6 @@ bool QVirtualKeyboardInputContextPrivate::filterEvent(const QEvent *event)
setState(State::KeyEvent);
#ifdef QT_VIRTUALKEYBOARD_ARROW_KEY_NAVIGATION
- int key = keyEvent->key();
if ((key >= Qt::Key_Left && key <= Qt::Key_Down) || key == Qt::Key_Return) {
if (type == QEvent::KeyPress && platformInputContext->isInputPanelVisible()) {
activeNavigationKeys += key;
@@ -533,8 +548,16 @@ bool QVirtualKeyboardInputContextPrivate::filterEvent(const QEvent *event)
#endif
// Break composing text since the virtual keyboard does not support hard keyboard events
- if (!preeditText.isEmpty())
- commit();
+ if (!preeditText.isEmpty()) {
+ if (type == QEvent::KeyPress && (key == Qt::Key_Delete || key == Qt::Key_Backspace)) {
+ reset();
+ Q_Q(QVirtualKeyboardInputContext);
+ q->clear();
+ return true;
+ } else {
+ commit();
+ }
+ }
}
#ifdef QT_VIRTUALKEYBOARD_ARROW_KEY_NAVIGATION
else if (type == QEvent::ShortcutOverride) {
diff --git a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h
index 54491e76..e34681fc 100644
--- a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h
+++ b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.h
@@ -153,6 +153,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/src/virtualkeyboard/qvirtualkeyboardinputengine.cpp b/src/virtualkeyboard/qvirtualkeyboardinputengine.cpp
index e64ea4eb..5f74c2a7 100644
--- a/src/virtualkeyboard/qvirtualkeyboardinputengine.cpp
+++ b/src/virtualkeyboard/qvirtualkeyboardinputengine.cpp
@@ -716,9 +716,11 @@ void QVirtualKeyboardInputEngine::timerEvent(QTimerEvent *timerEvent)
{
Q_D(QVirtualKeyboardInputEngine);
if (timerEvent->timerId() == d->repeatTimer) {
- d->repeatTimer = 0;
d->virtualKeyClick(d->activeKey, d->activeKeyText, d->activeKeyModifiers, true);
- d->repeatTimer = startTimer(50);
+ if (!d->repeatCount) {
+ killTimer(d->repeatTimer);
+ d->repeatTimer = startTimer(50);
+ }
d->repeatCount++;
}
}
diff --git a/src/virtualkeyboard/virtualkeyboard.pro b/src/virtualkeyboard/virtualkeyboard.pro
index cb28d6a1..03ed74f4 100644
--- a/src/virtualkeyboard/virtualkeyboard.pro
+++ b/src/virtualkeyboard/virtualkeyboard.pro
@@ -405,10 +405,6 @@ OTHER_FILES += \
SOURCES += desktopinputpanel.cpp inputview.cpp
HEADERS += desktopinputpanel_p.h inputview_p.h
DEFINES += QT_VIRTUALKEYBOARD_DESKTOP
- !no-pkg-config:packagesExist(xcb) {
- PKGCONFIG += xcb xcb-xfixes
- DEFINES += QT_VIRTUALKEYBOARD_HAVE_XCB
- }
}
record-trace-input {
diff --git a/src/virtualkeyboard/virtualkeyboardsettings.cpp b/src/virtualkeyboard/virtualkeyboardsettings.cpp
index d415c36c..173ab858 100644
--- a/src/virtualkeyboard/virtualkeyboardsettings.cpp
+++ b/src/virtualkeyboard/virtualkeyboardsettings.cpp
@@ -352,6 +352,7 @@ void VirtualKeyboardSettings::resetStyle()
/*!
\qmlproperty list<string> VirtualKeyboardSettings::availableLocales
\since QtQuick.VirtualKeyboard.Settings 2.0
+ \readonly
This property contains a list of languages supported by the virtual keyboard.
diff --git a/tests/auto/inputpanel/BLACKLIST b/tests/auto/inputpanel/BLACKLIST
new file mode 100644
index 00000000..a7c14041
--- /dev/null
+++ b/tests/auto/inputpanel/BLACKLIST
@@ -0,0 +1,28 @@
+# See qtbase/src/testlib/qtestblacklist.cpp for format
+
+# QTBUG-97830
+[tst_plugin::test_fullScreenModeSelectionHandles:row 0]
+*
+[tst_plugin::test_fullScreenModeSelectionHandles:row 2]
+*
+[tst_plugin::test_fullScreenModeSelectionHandles:row 3]
+*
+
+# QTBUG-97830
+[tst_plugin::test_selection:row 0]
+*
+
+# QTBUG-97989
+[tst_plugin::test_fullScreenModeWordReselection]
+b2qt
+
+[tst_plugin::test_hangulInputMethod:row 25]
+# QTBUG-101622
+ubuntu-20
+b2qt
+
+[tst_plugin::test_hardKeyBackspaceClearsInput]
+b2qt
+
+[tst_plugin::test_spellCorrectionAutomaticSpaceInsertion:row 11]
+b2qt
diff --git a/tests/auto/inputpanel/data/tst_inputpanel.qml b/tests/auto/inputpanel/data/tst_inputpanel.qml
index ec1dbd97..2758c0a1 100644
--- a/tests/auto/inputpanel/data/tst_inputpanel.qml
+++ b/tests/auto/inputpanel/data/tst_inputpanel.qml
@@ -251,8 +251,14 @@ Rectangle {
Qt.inputMethod.hide()
verify(inputPanel.visible === false)
+ // Should not become visible because the active focus is set to container
Qt.inputMethod.show()
waitForRendering(inputPanel)
+ verify(inputPanel.visible === false)
+
+ // Should become visible because of previously called show() and focus set to input control
+ textInput.forceActiveFocus()
+ waitForRendering(inputPanel)
verify(inputPanel.visible === true)
Qt.inputMethod.hide()
@@ -321,6 +327,31 @@ Rectangle {
compare(textInput.text, "A")
}
+ function test_hardKeyBackspaceClearsInput_data() {
+ return [
+ { initLocale: "en_GB", initText: "12345", initCursorPosition: 1, inputSequence: "hello", outputText: "12345", expectedCursorPosition: 1 },
+ { initLocale: "ja_JP", initText: "12345", initCursorPosition: 1, inputSequence: "watashi", outputText: "12345", expectedCursorPosition: 1 },
+ ]
+ }
+
+ function test_hardKeyBackspaceClearsInput(data) {
+ prepareTest(data)
+
+ if (!inputPanel.wordCandidateListVisibleHint)
+ skip("Prediction/spell correction not enabled")
+
+ compare(Qt.inputMethod.locale.name, Qt.locale(data.initLocale).name)
+ for (var inputIndex in data.inputSequence) {
+ verify(inputPanel.virtualKeyClick(data.inputSequence[inputIndex]))
+ }
+
+ keyClick(Qt.Key_Backspace)
+ waitForRendering(textInput)
+
+ compare(textInput.text, data.outputText)
+ compare(textInput.cursorPosition, data.expectedCursorPosition)
+ }
+
function test_hardKeyInput() {
prepareTest()
@@ -915,9 +946,13 @@ Rectangle {
{ initInputMethodHints: Qt.ImhNone, initLocale: "zh_CN", inputSequence: "bailou", expectedCandidates: [ "\u5457", "\u5A04" ], outputText: "\u5457\u5A04" },
// Select phrase from the user dictinary
{ initInputMethodHints: Qt.ImhNone, initLocale: "zh_CN", inputSequence: "bailou", expectedCandidates: [ "\u5457\u5A04" ], outputText: "\u5457\u5A04" },
+ // Suggest phrases according to the last selected word
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_CN", inputSequence: "da", expectedCandidates: [ "\u5927", "\u5bb6", "\u5ead" ], outputText: "\u5927\u5bb6\u5ead" },
// Add an apostrophe before joined syllables in cases of ambiguity, disable the user dictionary (Qt.ImhSensitiveData) so it does not affect to the results
{ initInputMethodHints: Qt.ImhNone | Qt.ImhSensitiveData, initLocale: "zh_CN", inputSequence: "zhangang", expectedCandidates: [ "\u5360", "\u94A2" ], outputText: "\u5360\u94A2" },
{ initInputMethodHints: Qt.ImhNone | Qt.ImhSensitiveData, initLocale: "zh_CN", inputSequence: "zhang'ang", expectedCandidates: [ "\u7AE0", "\u6602" ], outputText: "\u7AE0\u6602" },
+ // Invalid pinyin sequence
+ { initInputMethodHints: Qt.ImhNone, initLocale: "zh_CN", inputSequence: "fi", expectedCandidates: [ "\u53D1", "i" ], outputText: "\u53D1i" },
]
}
@@ -1233,6 +1268,19 @@ Rectangle {
compare(textInput.cursorPosition, data.expectedCursorPosition)
}
+ function test_japaneseSelectCurrentItemResetsIndex() {
+ prepareTest({ initLocale: "ja_JP" }, true)
+
+ verify(inputPanel.virtualKeyClick("a"))
+ verify(inputPanel.virtualKeyClick("a"))
+ verify(inputPanel.virtualKeyClick("a"))
+
+ compare(inputPanel.wordCandidateView.currentIndex, -1)
+ inputPanel.wordCandidateView.currentIndex = 0
+ inputPanel.selectionListSelectCurrentItem()
+ compare(inputPanel.wordCandidateView.currentIndex, -1, "QTBUG-94560")
+ }
+
function test_baseKeyNoModifier() {
// The Japanese keyboard uses the BaseKey.noModifier flag for the arrow keys.
// Without this flag the arrow key + shift would extend the text selection.