9#include <QtGui/qguiapplication.h>
10#include <QtGui/qtextformat.h>
11#include <QtGui/private/qguiapplication_p.h>
19QWaylandTextInputMethod::QWaylandTextInputMethod(QWaylandDisplay *display,
struct ::qt_text_input_method_v1 *textInputMethod)
20 : QtWayland::qt_text_input_method_v1(textInputMethod)
27 qt_text_input_method_v1_destroy(object());
32 if (m_isVisible != visible) {
33 m_isVisible = visible;
34 QGuiApplicationPrivate::platformIntegration()->inputContext()->emitInputPanelVisibleChanged();
40 m_locale = QLocale(localeName);
45 m_layoutDirection = Qt::LayoutDirection(inputDirection);
50 const QRectF keyboardRectangle(wl_fixed_to_double(x),
51 wl_fixed_to_double(y),
52 wl_fixed_to_double(width),
53 wl_fixed_to_double(height));
54 if (m_keyboardRect != keyboardRectangle) {
55 m_keyboardRect = keyboardRectangle;
56 QGuiApplicationPrivate::platformIntegration()->inputContext()->emitKeyboardRectChanged();
62 if (m_pendingInputMethodEvents.contains(serial)) {
63 qCWarning(qLcQpaInputMethods) <<
"Input method event with serial" << serial <<
"already started";
67 m_pendingInputMethodEvents[serial] = QList<QInputMethodEvent::Attribute>{};
68 m_offsetFromCompositor[serial] = surrounding_text_offset;
75 int size = text.size();
79 if (cursorPos > size - halfSize)
81 return cursorPos - halfSize;
101 if (!m_pendingInputMethodEvents.contains(serial)) {
102 qCWarning(qLcQpaInputMethods) <<
"Input method event with serial" << serial <<
"does not exist";
106 int startMapped = mapPositionFromCompositor(start, m_offsetFromCompositor[serial]);
107 QList<QInputMethodEvent::Attribute> &attributes = m_pendingInputMethodEvents[serial];
109 case QInputMethodEvent::Selection:
110 attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::AttributeType(type), startMapped, length));
112 case QInputMethodEvent::Cursor:
113 attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::AttributeType(type), start, length, QColor::fromString(value)));
115 case QInputMethodEvent::TextFormat:
117 QTextCharFormat textFormat;
118 textFormat.setProperty(QTextFormat::FontUnderline,
true);
119 textFormat.setProperty(QTextFormat::TextUnderlineStyle, QTextCharFormat::SingleUnderline);
120 attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::AttributeType(type), start, length, textFormat));
123 case QInputMethodEvent::Language:
124 case QInputMethodEvent::Ruby:
125 attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::AttributeType(type), start, length, value));
132 int cursorPosition = event->value(Qt::ImCursorPosition).toInt();
133 int anchorPosition = event->value(Qt::ImAnchorPosition).toInt();
134 QString surroundingText = event->value(Qt::ImSurroundingText).toString();
135 int offset = calculateOffset(surroundingText, cursorPosition);
137 if (queries & Qt::ImCursorPosition)
139 if (queries & Qt::ImSurroundingText)
140 update_surrounding_text(mapSurroundingTextToCompositor(surroundingText, offset), offset);
141 if (queries & Qt::ImAnchorPosition)
143 if (queries & Qt::ImAbsolutePosition)
144 update_absolute_position(event->value(Qt::ImAbsolutePosition).toInt());
150 if (!m_pendingInputMethodEvents.contains(serial)) {
151 qCWarning(qLcQpaInputMethods) <<
"Input method event with serial" << serial <<
"does not exist";
155 QList<QInputMethodEvent::Attribute> attributes = m_pendingInputMethodEvents.take(serial);
156 m_offsetFromCompositor.remove(serial);
157 if (QGuiApplication::focusObject() !=
nullptr) {
158 QInputMethodEvent event(preeditString, attributes);
159 event.setCommitString(commitString, replacementStart, replacementLength);
160 QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event);
164 if (QGuiApplication::focusObject() !=
nullptr) {
165 QInputMethodQueryEvent event(Qt::ImCursorPosition | Qt::ImSurroundingText | Qt::ImAnchorPosition | Qt::ImAbsolutePosition);
166 QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event);
167 sendInputState(&event);
170 acknowledge_input_method();
178 int32_t nativeScanCode,
179 int32_t nativeVirtualKey,
180 int32_t nativeModifiers,
183 if (QGuiApplication::focusObject() !=
nullptr) {
184 QKeyEvent event(QKeyEvent::Type(type),
186 Qt::KeyboardModifiers(modifiers),
193 QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event);
204 if (surface != m_surface) {
205 qCWarning(qLcQpaInputMethods) <<
"Got leave event for surface without corresponding enter";
222 return m_display->textInputMethodManager() !=
nullptr;
228 if (inputMethod !=
nullptr)
229 inputMethod->reset();
235 if (inputMethod !=
nullptr)
236 inputMethod->commit();
238 m_display->forceRoundTrip();
243 wl_surface *currentSurface = m_currentWindow !=
nullptr && m_currentWindow->handle() !=
nullptr
244 ?
static_cast<QWaylandWindow *>(m_currentWindow->handle())->wlSurface()
246 if (currentSurface !=
nullptr && !inputMethodAccepted()) {
247 textInputMethod()->disable(currentSurface);
248 m_currentWindow.clear();
249 }
else if (currentSurface ==
nullptr && inputMethodAccepted()) {
250 QWindow *window = QGuiApplication::focusWindow();
251 currentSurface = window !=
nullptr && window->handle() !=
nullptr
252 ?
static_cast<QWaylandWindow *>(window->handle())->wlSurface()
254 if (currentSurface !=
nullptr) {
255 textInputMethod()->disable(currentSurface);
256 m_currentWindow = window;
260 queries &= (Qt::ImEnabled
262 | Qt::ImCursorRectangle
263 | Qt::ImCursorPosition
264 | Qt::ImSurroundingText
265 | Qt::ImCurrentSelection
266 | Qt::ImAnchorPosition
267 | Qt::ImTextAfterCursor
268 | Qt::ImTextBeforeCursor
269 | Qt::ImPreferredLanguage);
271 const Qt::InputMethodQueries queriesNeedingOffset = Qt::ImCursorPosition | Qt::ImSurroundingText | Qt::ImAnchorPosition;
272 if (queries & queriesNeedingOffset)
273 queries |= queriesNeedingOffset;
276 if (inputMethod !=
nullptr && QGuiApplication::focusObject() !=
nullptr) {
277 QInputMethodQueryEvent event(queries);
278 QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event);
280 inputMethod->start_update(
int(queries));
282 if (queries & Qt::ImHints)
283 inputMethod->update_hints(event.value(Qt::ImHints).toInt());
285 if (queries & Qt::ImCursorRectangle) {
286 QRect rect = event.value(Qt::ImCursorRectangle).toRect();
287 inputMethod->update_cursor_rectangle(rect.x(), rect.y(), rect.width(), rect.height());
290 inputMethod->sendInputState(&event, queries);
292 if (queries & Qt::ImPreferredLanguage)
293 inputMethod->update_preferred_language(event.value(Qt::ImPreferredLanguage).toString());
295 inputMethod->end_update();
304 if (inputMethod !=
nullptr)
305 inputMethod->invoke_action(
int(action), cursorPosition);
311 if (inputMethod !=
nullptr)
312 inputMethod->show_input_panel();
318 if (inputMethod !=
nullptr)
319 inputMethod->hide_input_panel();
325 if (inputMethod !=
nullptr)
334 if (inputMethod !=
nullptr)
335 return inputMethod->keyboardRect();
343 if (inputMethod !=
nullptr)
344 return inputMethod->locale();
352 if (inputMethod !=
nullptr)
353 return inputMethod->inputDirection();
355 return Qt::LeftToRight;
361 if (inputMethod ==
nullptr)
365 inputMethod->hide_input_panel();
367 QWindow *window = QGuiApplication::focusWindow();
369 if (m_currentWindow !=
nullptr && m_currentWindow->handle() !=
nullptr) {
370 if (m_currentWindow.data() != window || !inputMethodAccepted()) {
371 auto *surface =
static_cast<QWaylandWindow *>(m_currentWindow->handle())->wlSurface();
373 inputMethod->disable(surface);
374 m_currentWindow.clear();
378 if (window !=
nullptr && window->handle() !=
nullptr && inputMethodAccepted()) {
379 if (m_currentWindow.data() != window) {
380 auto *surface =
static_cast<QWaylandWindow *>(window->handle())->wlSurface();
381 if (surface !=
nullptr) {
382 inputMethod->enable(surface);
383 m_currentWindow = window;
387 update(Qt::ImQueryAll);
393 return m_display->defaultInputDevice() ? m_display->defaultInputDevice()->textInputMethod() :
nullptr;
400#include "moc_qwaylandinputmethodcontext_p.cpp"
void update(Qt::InputMethodQueries) override
Notification on editor updates.
Qt::LayoutDirection inputDirection() const override
bool isInputPanelVisible() const override
Returns input panel visibility status.
void reset() override
Method to be called when input method needs to be reset.
void setFocusObject(QObject *object) override
This virtual method gets called to notify updated focus to object.
void hideInputPanel() override
Request to hide input panel.
QRectF keyboardRect() const override
This function can be reimplemented to return virtual keyboard rectangle in currently active window co...
~QWaylandInputMethodContext() override
void showInputPanel() override
Request to show input panel.
bool isValid() const override
Returns input context validity.
void invokeAction(QInputMethod::Action, int cursorPosition) override
Called when the word currently being composed in the input item is tapped by the user.
QLocale locale() const override
void text_input_method_v1_start_input_method_event(uint32_t serial, int32_t surrounding_text_offset) override
void text_input_method_v1_key(int32_t type, int32_t key, int32_t modifiers, int32_t autoRepeat, int32_t count, int32_t nativeScanCode, int32_t nativeVirtualKey, int32_t nativeModifiers, const QString &text) override
void text_input_method_v1_input_method_event_attribute(uint32_t serial, int32_t type, int32_t start, int32_t length, const QString &value) override
~QWaylandTextInputMethod() override
void text_input_method_v1_end_input_method_event(uint32_t serial, const QString &commitString, const QString &preeditString, int32_t replacementStart, int32_t replacementLength) override
void sendInputState(QInputMethodQueryEvent *state, Qt::InputMethodQueries queries=Qt::ImQueryInput)
void text_input_method_v1_keyboard_rectangle_changed(wl_fixed_t x, wl_fixed_t y, wl_fixed_t width, wl_fixed_t height) override
void text_input_method_v1_input_direction_changed(int32_t inputDirection) override
void text_input_method_v1_locale_changed(const QString &localeName) override
void text_input_method_v1_visible_changed(int32_t visible) override
Combined button and popup list for selecting options.
static int mapPositionFromCompositor(int pos, int offset)
static int calculateOffset(const QString &text, int cursorPos)
static constexpr int maxStringSize
static QString mapSurroundingTextToCompositor(const QString &s, int offset)
static int mapPositionToCompositor(int pos, int offset)