diff options
author | Jarkko Koivikko <jarkko.koivikko@code-q.fi> | 2020-10-02 12:04:07 +0300 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-03-16 11:06:34 +0000 |
commit | 84c0466a5385220af0cf6da0468d8a05f45a6f9a (patch) | |
tree | 0faaa626059f429c1aa7e786a141add0f793aa74 | |
parent | b8ffe33eb095fca858d6441ff7db8c7b8ab7cf96 (diff) |
Fix activation of input panel when initial active focus is set
Never change m_visible state internally. Instead, m_visible is merely
a parameter which affects to actual visible state.
The m_visible state should correspond to latest showInputPanel() or
hideInputPanel() call. The actual visible state is evaluated in the
evaluateInputPanelVisible() method, which factors in other parameters,
such as input focus and Qt::ImEnabled.
Speaking of Qt::ImEnabled, this change also optimizes out one input
method query during frequently called update() method by using
QPlatformInputContext::inputMethodAccepted() instead.
[ChangeLog] It is now possible to open the input panel implicitly when
activating the window. Before, this failed because the "visible" state
was reset (due to a bug) during activation.
Fixes: QTBUG-86190
Change-Id: I31b73f8a29c5e51de60836ea1ccab70547bad0a0
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Jarkko Koivikko <jarkko.koivikko@code-q.fi>
(cherry picked from commit 90d64dea7d0370abcb5b787bcc77dc4770f491ed)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/virtualkeyboard/platforminputcontext.cpp | 27 | ||||
-rw-r--r-- | src/virtualkeyboard/platforminputcontext_p.h | 1 | ||||
-rw-r--r-- | src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp | 2 | ||||
-rw-r--r-- | tests/auto/inputpanel/data/tst_inputpanel.qml | 6 |
4 files changed, 25 insertions, 11 deletions
diff --git a/src/virtualkeyboard/platforminputcontext.cpp b/src/virtualkeyboard/platforminputcontext.cpp index 4b86629a..5cceefb3 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 dbd32e93..665fcb6b 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 645a6310..b0eb2a3c 100644 --- a/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp +++ b/src/virtualkeyboard/qvirtualkeyboardinputcontext_p.cpp @@ -406,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(); diff --git a/tests/auto/inputpanel/data/tst_inputpanel.qml b/tests/auto/inputpanel/data/tst_inputpanel.qml index fee9fb03..701e640d 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() |