From 8bcc3f2ce5da22e0e69ab7eb2da2e40962998d81 Mon Sep 17 00:00:00 2001 From: Even Oscar Andersen Date: Mon, 28 Apr 2025 14:59:27 +0200 Subject: [PATCH] wasm: Update input field geometry on window geometry change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The location of the input field was wrong leading to empty space inserted in the user interface. Fixes: QTBUG-136233 Pick-to: 6.8 Change-Id: Ic8c9faf5c4dbb8cec43a43c25c1cce8d7809f140 Reviewed-by: Piotr Wierciński (cherry picked from commit f016201b6d66408a4dd7427d2b9234909b8f1f92) Reviewed-by: Morten Johan Sørvig --- .../platforms/wasm/qwasminputcontext.cpp | 59 ++++++++++++------- .../platforms/wasm/qwasminputcontext.h | 2 + src/plugins/platforms/wasm/qwasmwindow.cpp | 5 ++ 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasminputcontext.cpp b/src/plugins/platforms/wasm/qwasminputcontext.cpp index 76328aa6db8..d01546faa91 100644 --- a/src/plugins/platforms/wasm/qwasminputcontext.cpp +++ b/src/plugins/platforms/wasm/qwasminputcontext.cpp @@ -259,6 +259,8 @@ QWasmInputContext::QWasmInputContext() m_inputElement["style"].set("opacity", 0); m_inputElement["style"].set("display", ""); m_inputElement["style"].set("z-index", -2); + m_inputElement["style"].set("width", "1px"); + m_inputElement["style"].set("height", "1px"); m_inputElement.set("data-qinputcontext", emscripten::val(quintptr(reinterpret_cast(this)))); @@ -312,18 +314,48 @@ void QWasmInputContext::showInputPanel() updateInputElement(); } +void QWasmInputContext::updateGeometry() +{ + const QWindow *focusWindow = QGuiApplication::focusWindow(); + if (!m_focusObject || !focusWindow || !m_visibleInputPanel || !m_inputMethodAccepted) { + m_inputElement["style"].set("left", "0px"); + m_inputElement["style"].set("top", "0px"); + } + else { + Q_ASSERT(focusWindow); + Q_ASSERT(m_focusObject); + Q_ASSERT(m_visibleInputPanel); + Q_ASSERT(m_inputMethodAccepted); + + // Set the geometry + QPoint globalPos; + const QRect cursorRectangle = QPlatformInputContext::cursorRectangle().toRect(); + 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); + } +} + void QWasmInputContext::updateInputElement() { // Mobile devices can dismiss keyboard/IME and focus is still on input. // Successive clicks on the same input should open the keyboard/IME. + updateGeometry(); // If there is no focus object, or no visible input panel, remove focus const QWindow *focusWindow = QGuiApplication::focusWindow(); - if (!m_focusObject || !focusWindow || !m_visibleInputPanel || !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"); + if (!m_focusObject || !focusWindow || !m_visibleInputPanel || !m_inputMethodAccepted) { m_inputElement.set("value", ""); m_inputElement.call("blur"); @@ -338,23 +370,6 @@ void QWasmInputContext::updateInputElement() Q_ASSERT(m_visibleInputPanel); Q_ASSERT(m_inputMethodAccepted); - // Set the geometry - QPoint globalPos; - const QRect cursorRectangle = QPlatformInputContext::cursorRectangle().toRect(); - 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 diff --git a/src/plugins/platforms/wasm/qwasminputcontext.h b/src/plugins/platforms/wasm/qwasminputcontext.h index 7e198fe6f3d..ba6f41cf8de 100644 --- a/src/plugins/platforms/wasm/qwasminputcontext.h +++ b/src/plugins/platforms/wasm/qwasminputcontext.h @@ -42,6 +42,8 @@ public: bool usingTextInput() const { return m_inputMethodAccepted; } void setFocusObject(QObject *object) override; + void updateGeometry(); + private: void updateInputElement(); diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index c9769302edd..8bd77ad55b5 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -298,6 +298,11 @@ void QWasmWindow::setGeometry(const QRect &rect) shouldInvalidate = m_normalGeometry.size() != clientAreaRect.size(); m_normalGeometry = clientAreaRect; } + + QWasmInputContext *wasmInput = QWasmIntegration::get()->wasmInputContext(); + if (wasmInput && (QGuiApplication::focusWindow() == window())) + wasmInput->updateGeometry(); + QWindowSystemInterface::handleGeometryChange(window(), clientAreaRect); if (shouldInvalidate) invalidate();