From 43eb0dbd38e74158e7eb36a28cb416b357445d6b Mon Sep 17 00:00:00 2001 From: Even Oscar Andersen Date: Mon, 3 Feb 2025 11:50:03 +0100 Subject: [PATCH] wasm: Truncate input field length to 1px, fix object selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having the input field length too wide causes the view to scroll to contain it. Since it is not visible, setting it to 1px width and height should work. Further, input field contents where set on the showInputPanel call. At this point in time we do not necessarily have an updated focus object. Hence the input contents is now set on the setFocusObject call. Ignore input on showInputPanel/hideInputPanel. This reflects the current design where showInputPanel do not act unless inputMethodAccepted(), and hideInputPanel do not act if m_focusObject. Still hideInputPanel used to set m_usingTextInput to false, this behavior is not kept. Fixes: QTBUG-132057 Pick-to: 6.8 Change-Id: I2d7088def8060df267c5da9e045824decd913faa Reviewed-by: Morten Johan Sørvig (cherry picked from commit 7dd94d74e4497647ff62c85460643487baf372bc) Reviewed-by: Qt Cherry-pick Bot --- .../platforms/wasm/qwasminputcontext.cpp | 65 +++++++++++-------- .../platforms/wasm/qwasminputcontext.h | 8 ++- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasminputcontext.cpp b/src/plugins/platforms/wasm/qwasminputcontext.cpp index 5ce24588973..81d698ce1a5 100644 --- a/src/plugins/platforms/wasm/qwasminputcontext.cpp +++ b/src/plugins/platforms/wasm/qwasminputcontext.cpp @@ -306,29 +306,52 @@ void QWasmInputContext::update(Qt::InputMethodQueries queries) void QWasmInputContext::showInputPanel() { qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO; +} - if (!inputMethodAccepted()) +void QWasmInputContext::setInputText() +{ + // If there is no focus object, remove focus + const QWindow *focusWindow = QGuiApplication::focusWindow(); + if (!m_focusObject || !focusWindow) { + m_inputElement.call("blur"); return; + } - m_inputElement.call("focus"); - m_usingTextInput = true; - - QWindow *window = QGuiApplication::focusWindow(); - if (!window || !m_focusObject) + // We set the focus even if we do not have input method accepted + if (!m_inputMethodAccepted) { + m_inputElement["style"].set("left", "0px"); + m_inputElement["style"].set("top", "0px"); + m_inputElement["style"].set("width", "1px"); + m_inputElement["style"].set("height", "1px"); + m_inputElement.set("value", ""); + m_inputElement.call("focus"); return; + } + Q_ASSERT(focusWindow); + Q_ASSERT(m_focusObject); + Q_ASSERT(m_inputMethodAccepted); + + // Set the geometry + QPoint globalPos; const QRect cursorRectangle = QPlatformInputContext::cursorRectangle().toRect(); - if (!cursorRectangle.isValid()) - return; - qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "cursorRectangle: " << cursorRectangle; - const QPoint &globalPos = window->mapToGlobal(cursorRectangle.topLeft()); + if (cursorRectangle.isValid()) { + qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "cursorRectangle: " << cursorRectangle; + globalPos = focusWindow->mapToGlobal(cursorRectangle.topLeft()); + if (globalPos.x() > 0) globalPos.setX(globalPos.x() - 1); + if (globalPos.y() > 0) globalPos.setY(globalPos.y() - 1); + } + const auto styleLeft = std::to_string(globalPos.x()) + "px"; const auto styleTop = std::to_string(globalPos.y()) + "px"; m_inputElement["style"].set("left", styleLeft); m_inputElement["style"].set("top", styleTop); + m_inputElement["style"].set("width", "1px"); + m_inputElement["style"].set("height", "1px"); qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << QRectF::fromDOMRect(m_inputElement.call("getBoundingClientRect")); + // Set the text input QInputMethodQueryEvent queryEvent(Qt::ImQueryAll); QCoreApplication::sendEvent(m_focusObject, &queryEvent); qCDebug(qLcQpaWasmInputContext) << "Qt surrounding text: " << queryEvent.value(Qt::ImSurroundingText).toString(); @@ -342,6 +365,8 @@ void QWasmInputContext::showInputPanel() m_inputElement.set("selectionStart", queryEvent.value(Qt::ImAnchorPosition).toUInt()); m_inputElement.set("selectionEnd", queryEvent.value(Qt::ImCursorPosition).toUInt()); + + m_inputElement.call("focus"); } void QWasmInputContext::setFocusObject(QObject *object) @@ -352,29 +377,15 @@ void QWasmInputContext::setFocusObject(QObject *object) if (m_focusObject && !m_preeditString.isEmpty()) commitPreeditAndClear(); - if (object) { - m_inputElement.call("focus"); - m_usingTextInput = inputMethodAccepted(); - m_focusObject = object; - } else if (m_focusObject) { - m_inputElement.call("blur"); - m_usingTextInput = false; - m_focusObject = nullptr; - } else { - m_usingTextInput = false; - } + m_inputMethodAccepted = (object && inputMethodAccepted()); + m_focusObject = object; + setInputText(); QPlatformInputContext::setFocusObject(object); } void QWasmInputContext::hideInputPanel() { qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO; - - // hide only if m_focusObject does not exist - if (!m_focusObject) { - m_inputElement.call("blur"); - m_usingTextInput = false; - } } void QWasmInputContext::setPreeditString(QString preeditStr, int replaceSize) diff --git a/src/plugins/platforms/wasm/qwasminputcontext.h b/src/plugins/platforms/wasm/qwasminputcontext.h index 681fd4e38d9..b93b5589747 100644 --- a/src/plugins/platforms/wasm/qwasminputcontext.h +++ b/src/plugins/platforms/wasm/qwasminputcontext.h @@ -39,15 +39,17 @@ public: void insertText(QString inputStr, bool replace = false); - bool usingTextInput() { return m_usingTextInput; } - void setUsingTextInput(bool enable) { m_usingTextInput = enable; } + bool usingTextInput() const { return m_inputMethodAccepted; } void setFocusObject(QObject *object) override; +private: + void setInputText(); + private: QString m_preeditString; int m_replaceSize = 0; - bool m_usingTextInput = false; + bool m_inputMethodAccepted = false; QObject *m_focusObject = nullptr; };