wasm: Update input field geometry on window geometry change

The location of the input field was wrong leading to empty space
inserted in the user interface.

Fixes: QTBUG-136233
Pick-to: 6.9 6.8
Change-Id: Ic8c9faf5c4dbb8cec43a43c25c1cce8d7809f140
Reviewed-by: Piotr Wierciński <piotr.wiercinski@qt.io>
This commit is contained in:
Even Oscar Andersen 2025-04-28 14:59:27 +02:00
parent 81f8eee6a1
commit f016201b6d
3 changed files with 45 additions and 22 deletions

View File

@ -254,6 +254,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<void *>(this))));
@ -292,18 +294,48 @@ void QWasmInputContext::showInputPanel()
updateInputElement();
}
void QWasmInputContext::updateInputElement()
void QWasmInputContext::updateGeometry()
{
// Mobile devices can dismiss keyboard/IME and focus is still on input.
// Successive clicks on the same input should open the keyboard/IME.
// 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");
}
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.set("value", "");
if (QWasmWindow *wasmwindow = QWasmWindow::fromWindow(focusWindow))
@ -319,23 +351,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<emscripten::val>("getBoundingClientRect"));
// Set the text input

View File

@ -51,6 +51,9 @@ public:
static void compositionEndCallback(emscripten::val event);
static void compositionStartCallback(emscripten::val event);
static void compositionUpdateCallback(emscripten::val event);
void updateGeometry();
private:
void updateInputElement();

View File

@ -381,6 +381,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();