From 49ddb4b28af24ac2a0d9c07a910443dece2550ec Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Tue, 4 Oct 2022 13:50:03 +1000 Subject: [PATCH] wasm: add support for input languages win32 mobile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit on Windows virtual keyboard sends characters through the textInput handler, we can use the same mechanism as Android to create an offscreen input element and send the characters from there. Fixes: QTBUG-107139 Pick-to: 6.5 Change-Id: I84a143aedf93d22521fcfa368532eed8c0e7d002 Reviewed-by: MikoĊ‚aj Boc --- .../platforms/wasm/qwasminputcontext.cpp | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasminputcontext.cpp b/src/plugins/platforms/wasm/qwasminputcontext.cpp index 28695cf6b6..157f96fe49 100644 --- a/src/plugins/platforms/wasm/qwasminputcontext.cpp +++ b/src/plugins/platforms/wasm/qwasminputcontext.cpp @@ -24,13 +24,12 @@ static void inputCallback(emscripten::val event) if (length <= 0) return; - // use only last character - emscripten::val _incomingCharVal = event["target"]["value"][length - 1]; + emscripten::val _incomingCharVal = event["data"]; if (_incomingCharVal != emscripten::val::undefined() && _incomingCharVal != emscripten::val::null()) { QString str = QString::fromStdString(_incomingCharVal.as()); QWasmInputContext *wasmInput = - reinterpret_cast(event["target"]["data-context"].as()); + reinterpret_cast(event["target"]["data-qinputcontext"].as()); wasmInput->inputStringChanged(str, wasmInput); } // this clears the input string, so backspaces do not send a character @@ -39,7 +38,7 @@ static void inputCallback(emscripten::val event) } EMSCRIPTEN_BINDINGS(clipboard_module) { - function("qt_InputContextCallback", &inputCallback); + function("qtInputContextCallback", &inputCallback); } QWasmInputContext::QWasmInputContext() @@ -50,23 +49,24 @@ QWasmInputContext::QWasmInputContext() m_inputElement.set("style", "position:absolute;left:-1000px;top:-1000px"); // offscreen m_inputElement.set("contenteditable","true"); - if (platform() == Platform::Android) { + if (platform() == Platform::Android || platform() == Platform::Windows) { + const std::string inputType = platform() == Platform::Windows ? "textInput" : "input"; + + document.call("addEventListener", inputType, + emscripten::val::module_property("qtInputContextCallback"), + emscripten::val(false)); + m_inputElement.set("data-qinputcontext", + emscripten::val(quintptr(reinterpret_cast(this)))); emscripten::val body = document["body"]; body.call("appendChild", m_inputElement); - m_inputElement.call("addEventListener", std::string("input"), - emscripten::val::module_property("qt_InputContextCallback"), - emscripten::val(false)); - m_inputElement.set("data-context", - emscripten::val(quintptr(reinterpret_cast(this)))); - - // android sends Enter through target window, let's just handle this here + // Enter is sent through target window, let's just handle this here emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, (void *)this, 1, &androidKeyboardCallback); } - if (platform() == Platform::MacOS || platform() == Platform::iPhone) - { + + if (platform() == Platform::MacOS || platform() == Platform::iPhone) { auto callback = [=](emscripten::val) { m_inputElement["parentElement"].call("removeChild", m_inputElement); inputPanelIsOpen = false; @@ -80,7 +80,7 @@ QWasmInputContext::QWasmInputContext() QWasmInputContext::~QWasmInputContext() { - if (platform() == Platform::Android) + if (platform() == Platform::Android || platform() == Platform::Windows) emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, 0, NULL); } @@ -104,8 +104,10 @@ void QWasmInputContext::update(Qt::InputMethodQueries queries) void QWasmInputContext::showInputPanel() { if (platform() == Platform::Windows - && inputPanelIsOpen) // call this only once for win32 - return; + && !inputPanelIsOpen) { // call this only once for win32 + m_inputElement.call("focus"); + return; + } // this is called each time the keyboard is touched // Add the input element as a child of the screen for the