wasm: call focus on window if not editable

We used to call focus on the input element even for things
like pushbuttons.

This will display a keyboard on android, instead call
focus on the focus window.

Fixes: QTBUG-133781
Pick-to: 6.9 6.8
Change-Id: Ide4d6ec21a14f17b40d3d3de077c0ab073682f19
Reviewed-by: Lorn Potter <lorn.potter@qt.io>
This commit is contained in:
Even Oscar Andersen 2025-02-17 12:26:05 +01:00
parent 8055a5c2db
commit 442e2f4aeb
4 changed files with 33 additions and 15 deletions

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qwasminputcontext.h" #include "qwasminputcontext.h"
#include "qwasmwindow.h"
#include <QRectF> #include <QRectF>
#include <QLoggingCategory> #include <QLoggingCategory>
@ -306,30 +307,35 @@ void QWasmInputContext::update(Qt::InputMethodQueries queries)
void QWasmInputContext::showInputPanel() void QWasmInputContext::showInputPanel()
{ {
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO; qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO;
m_visibleInputPanel = true;
updateInputElement();
} }
void QWasmInputContext::setInputText() void QWasmInputContext::updateInputElement()
{ {
// If there is no focus object, remove focus // Mobile devices can dismiss keyboard/IME and focus is still on input.
const QWindow *focusWindow = QGuiApplication::focusWindow(); // Successive clicks on the same input should open the keyboard/IME.
if (!m_focusObject || !focusWindow) {
m_inputElement.call<void>("blur");
return;
}
// We set the focus even if we do not have input method accepted // If there is no focus object, or no visible input panel, remove focus
if (!m_inputMethodAccepted) { const QWindow *focusWindow = QGuiApplication::focusWindow();
if (!m_focusObject || !focusWindow || !m_visibleInputPanel || !m_inputMethodAccepted) {
m_inputElement["style"].set("left", "0px"); m_inputElement["style"].set("left", "0px");
m_inputElement["style"].set("top", "0px"); m_inputElement["style"].set("top", "0px");
m_inputElement["style"].set("width", "1px"); m_inputElement["style"].set("width", "1px");
m_inputElement["style"].set("height", "1px"); m_inputElement["style"].set("height", "1px");
m_inputElement.set("value", ""); m_inputElement.set("value", "");
m_inputElement.call<void>("focus");
m_inputElement.call<void>("blur");
if (focusWindow && focusWindow->handle())
((QWasmWindow *)(focusWindow->handle()))->focus();
return; return;
} }
Q_ASSERT(focusWindow); Q_ASSERT(focusWindow);
Q_ASSERT(m_focusObject); Q_ASSERT(m_focusObject);
Q_ASSERT(m_visibleInputPanel);
Q_ASSERT(m_inputMethodAccepted); Q_ASSERT(m_inputMethodAccepted);
// Set the geometry // Set the geometry
@ -379,13 +385,18 @@ void QWasmInputContext::setFocusObject(QObject *object)
m_inputMethodAccepted = (object && inputMethodAccepted()); m_inputMethodAccepted = (object && inputMethodAccepted());
m_focusObject = object; m_focusObject = object;
setInputText(); updateInputElement();
QPlatformInputContext::setFocusObject(object); QPlatformInputContext::setFocusObject(object);
} }
void QWasmInputContext::hideInputPanel() void QWasmInputContext::hideInputPanel()
{ {
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO; qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO;
m_visibleInputPanel = false;
// hide only if m_focusObject does not exist
if (!m_focusObject)
updateInputElement();
} }
void QWasmInputContext::setPreeditString(QString preeditStr, int replaceSize) void QWasmInputContext::setPreeditString(QString preeditStr, int replaceSize)

View File

@ -43,12 +43,13 @@ public:
void setFocusObject(QObject *object) override; void setFocusObject(QObject *object) override;
private: private:
void setInputText(); void updateInputElement();
private: private:
QString m_preeditString; QString m_preeditString;
int m_replaceSize = 0; int m_replaceSize = 0;
bool m_visibleInputPanel = false;
bool m_inputMethodAccepted = false; bool m_inputMethodAccepted = false;
QObject *m_focusObject = nullptr; QObject *m_focusObject = nullptr;
}; };

View File

@ -379,7 +379,8 @@ void QWasmWindow::setVisible(bool visible)
m_compositor->requestUpdateWindow(this, QRect(QPoint(0, 0), geometry().size()), QWasmCompositor::ExposeEventDelivery); m_compositor->requestUpdateWindow(this, QRect(QPoint(0, 0), geometry().size()), QWasmCompositor::ExposeEventDelivery);
m_decoratedWindow["style"].set("display", visible ? "block" : "none"); m_decoratedWindow["style"].set("display", visible ? "block" : "none");
if (window() == QGuiApplication::focusWindow()) if (window() == QGuiApplication::focusWindow())
m_canvas.call<void>("focus"); focus();
if (visible) if (visible)
applyWindowState(); applyWindowState();
} }
@ -907,11 +908,15 @@ void QWasmWindow::requestActivateWindow()
setAsActiveNode(); setAsActiveNode();
if (!QWasmIntegration::get()->inputContext()) if (!QWasmIntegration::get()->inputContext())
m_canvas.call<void>("focus"); focus();
QPlatformWindow::requestActivateWindow(); QPlatformWindow::requestActivateWindow();
} }
void QWasmWindow::focus()
{
m_canvas.call<void>("focus");
}
bool QWasmWindow::setMouseGrabEnabled(bool grab) bool QWasmWindow::setMouseGrabEnabled(bool grab)
{ {
Q_UNUSED(grab); Q_UNUSED(grab);

View File

@ -86,6 +86,7 @@ public:
bool windowEvent(QEvent *event) final; bool windowEvent(QEvent *event) final;
void setMask(const QRegion &region) final; void setMask(const QRegion &region) final;
void setParent(const QPlatformWindow *window) final; void setParent(const QPlatformWindow *window) final;
void focus();
QWasmScreen *platformScreen() const; QWasmScreen *platformScreen() const;
void setBackingStore(QWasmBackingStore *store) { m_backingStore = store; } void setBackingStore(QWasmBackingStore *store) { m_backingStore = store; }