Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qwasminputcontext.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <emscripten/bind.h>
5
6#include "qwasminputcontext.h"
7#include "qwasmintegration.h"
8#include "qwasmplatform.h"
9#include <QRectF>
10#include <qpa/qplatforminputcontext.h>
11#include "qwasmscreen.h"
12#include <qguiapplication.h>
13#include <qwindow.h>
14#include <QKeySequence>
15#include <qpa/qwindowsysteminterface.h>
16
18using namespace qstdweb;
19
20static void inputCallback(emscripten::val event)
21{
22 // android sends all the characters typed since the user started typing in this element
23 int length = event["target"]["value"]["length"].as<int>();
24 if (length <= 0)
25 return;
26
27 emscripten::val _incomingCharVal = event["data"];
28 if (_incomingCharVal != emscripten::val::undefined() && _incomingCharVal != emscripten::val::null()) {
29
30 QString str = QString::fromStdString(_incomingCharVal.as<std::string>());
31 QWasmInputContext *wasmInput =
32 reinterpret_cast<QWasmInputContext*>(event["target"]["data-qinputcontext"].as<quintptr>());
33 wasmInput->inputStringChanged(str, wasmInput);
34 }
35 // this clears the input string, so backspaces do not send a character
36 // but stops suggestions
37 event["target"].set("value", "");
38}
39
40EMSCRIPTEN_BINDINGS(clipboard_module) {
41 function("qtInputContextCallback", &inputCallback);
42}
43
45{
46 emscripten::val document = emscripten::val::global("document");
47 m_inputElement = document.call<emscripten::val>("createElement", std::string("input"));
48 m_inputElement.set("type", "text");
49 m_inputElement.set("style", "position:absolute;left:-1000px;top:-1000px"); // offscreen
50 m_inputElement.set("contenteditable","true");
51
53 const std::string inputType = platform() == Platform::Windows ? "textInput" : "input";
54
55 document.call<void>("addEventListener", inputType,
56 emscripten::val::module_property("qtInputContextCallback"),
57 emscripten::val(false));
58 m_inputElement.set("data-qinputcontext",
59 emscripten::val(quintptr(reinterpret_cast<void *>(this))));
60 emscripten::val body = document["body"];
61 body.call<void>("appendChild", m_inputElement);
62
63 // Enter is sent through target window, let's just handle this here
64 emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, (void *)this, 1,
65 &androidKeyboardCallback);
66
67 }
68
70 auto callback = [=](emscripten::val) {
71 m_inputElement["parentElement"].call<void>("removeChild", m_inputElement);
72 inputPanelIsOpen = false;
73 };
74 m_blurEventHandler.reset(new EventCallback(m_inputElement, "blur", callback));
75 }
76
79}
80
82{
84 emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, 0, NULL);
85}
86
88{
89 m_focusWindow = focusWindow;
90}
91
92emscripten::val QWasmInputContext::inputHandlerElementForFocusedWindow()
93{
94 if (!m_focusWindow)
95 return emscripten::val::undefined();
96 return static_cast<QWasmWindow *>(m_focusWindow->handle())->inputHandlerElement();
97}
98
99void QWasmInputContext::update(Qt::InputMethodQueries queries)
100{
102}
103
105{
107 && !inputPanelIsOpen) { // call this only once for win32
108 m_inputElement.call<void>("focus");
109 return;
110 }
111 // this is called each time the keyboard is touched
112
113 // Add the input element as a child of the screen for the
114 // currently focused window and give it focus. The browser
115 // will not display the input element, but mobile browsers
116 // should display the virtual keyboard. Key events will be
117 // captured by the keyboard event handler installed on the
118 // screen element.
119
120 if (platform() == Platform::MacOS // keep for compatibility
121 || platform() == Platform::iOS
122 || platform() == Platform::Windows) {
123 emscripten::val inputWrapper = inputHandlerElementForFocusedWindow();
124 if (inputWrapper.isUndefined())
125 return;
126 inputWrapper.call<void>("appendChild", m_inputElement);
127 }
128
129 m_inputElement.call<void>("focus");
130 inputPanelIsOpen = true;
131}
132
134{
135 if (QWasmIntegration::get()->touchPoints < 1)
136 return;
137 m_inputElement.call<void>("blur");
138 inputPanelIsOpen = false;
139}
140
142{
145 // synthesize this keyevent as android is not normal
147 0, QEvent::KeyPress,keys[0].key(), keys[0].keyboardModifiers(), inputString);
148}
149
150int QWasmInputContext::androidKeyboardCallback(int eventType,
151 const EmscriptenKeyboardEvent *keyEvent,
152 void *userData)
153{
154 // we get Enter, Backspace and function keys via emscripten on target window
155 Q_UNUSED(eventType)
156 QString strKey(keyEvent->key);
157 if (strKey == "Unidentified" || strKey == "Process")
158 return false;
159
160 QWasmInputContext *wasmInput = reinterpret_cast<QWasmInputContext*>(userData);
161 wasmInput->inputStringChanged(strKey, wasmInput);
162
163 return true;
164}
165
@ KeyPress
Definition qcoreevent.h:64
void focusWindowChanged(QWindow *focusWindow)
This signal is emitted when the focused window changes.
The QKeySequence class encapsulates a key sequence as used by shortcuts.
static QKeySequence fromString(const QString &str, SequenceFormat format=PortableText)
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
virtual void update(Qt::InputMethodQueries)
Notification on editor updates.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromStdString(const std::string &s)
Definition qstring.h:1322
void showInputPanel() override
Request to show input panel.
void hideInputPanel() override
Request to hide input panel.
void update(Qt::InputMethodQueries) override
Notification on editor updates.
void focusWindowChanged(QWindow *focusWindow)
void inputStringChanged(QString &, QWasmInputContext *context)
static QWasmIntegration * get()
static bool handleKeyEvent(QWindow *window, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString &text=QString(), bool autorep=false, ushort count=1)
\inmodule QtGui
Definition qwindow.h:63
QString str
[2]
Combined button and popup list for selecting options.
static void * context
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
#define qGuiApp
GLuint64 key
GLenum GLuint GLenum GLsizei length
struct _cl_event * event
#define Q_UNUSED(x)
size_t quintptr
Definition qtypes.h:72
static void inputCallback(emscripten::val event)
EMSCRIPTEN_BINDINGS(clipboard_module)
QT_BEGIN_NAMESPACE Platform platform()
QStringList keys