Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwaylandtextinput.cpp
Go to the documentation of this file.
1// Copyright (C) 2017-2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:critical reason:network-protocol
4
7
8#include <QtWaylandCompositor/QWaylandCompositor>
9#include <QtWaylandCompositor/private/qwaylandseat_p.h>
10
12#include "qwaylandview.h"
13#include "qwaylandinputmethodeventbuilder_p.h"
15
16#include <QGuiApplication>
17#include <QInputMethodEvent>
18
19#if QT_CONFIG(xkbcommon)
20#include <QtGui/private/qxkbcommon_p.h>
21#endif
22
24
25QWaylandTextInputClientState::QWaylandTextInputClientState()
26{
27}
28
30{
31 Qt::InputMethodQueries queries;
32
33 if (hints != other.hints)
34 queries |= Qt::ImHints;
35 if (cursorRectangle != other.cursorRectangle)
36 queries |= Qt::ImCursorRectangle;
37 if (surroundingText != other.surroundingText)
38 queries |= Qt::ImSurroundingText | Qt::ImCurrentSelection;
39 if (cursorPosition != other.cursorPosition)
40 queries |= Qt::ImCursorPosition | Qt::ImCurrentSelection;
41 if (anchorPosition != other.anchorPosition)
42 queries |= Qt::ImAnchorPosition | Qt::ImCurrentSelection;
43 if (preferredLanguage != other.preferredLanguage)
44 queries |= Qt::ImPreferredLanguage;
45
46 return queries;
47}
48
50 Qt::InputMethodQueries queries;
51
52 if ((other.changedState & Qt::ImHints) && hints != other.hints) {
53 hints = other.hints;
54 queries |= Qt::ImHints;
55 }
56
57 if ((other.changedState & Qt::ImCursorRectangle) && cursorRectangle != other.cursorRectangle) {
58 cursorRectangle = other.cursorRectangle;
59 queries |= Qt::ImCursorRectangle;
60 }
61
62 if ((other.changedState & Qt::ImSurroundingText) && surroundingText != other.surroundingText) {
63 surroundingText = other.surroundingText;
64 queries |= Qt::ImSurroundingText | Qt::ImCurrentSelection;
65 }
66
67 if ((other.changedState & Qt::ImCursorPosition) && cursorPosition != other.cursorPosition) {
69 queries |= Qt::ImCursorPosition | Qt::ImCurrentSelection;
70 }
71
72 if ((other.changedState & Qt::ImAnchorPosition) && anchorPosition != other.anchorPosition) {
74 queries |= Qt::ImAnchorPosition | Qt::ImCurrentSelection;
75 }
76
77 if ((other.changedState & Qt::ImPreferredLanguage) && preferredLanguage != other.preferredLanguage) {
78 preferredLanguage = other.preferredLanguage;
79 queries |= Qt::ImPreferredLanguage;
80 }
81
82 return queries;
83}
84
85QWaylandTextInputPrivate::QWaylandTextInputPrivate(QWaylandCompositor *compositor)
86 : compositor(compositor)
87 , currentState(new QWaylandTextInputClientState)
88 , pendingState(new QWaylandTextInputClientState)
89{
90}
91
92void QWaylandTextInputPrivate::sendInputMethodEvent(QInputMethodEvent *event)
93{
94 Q_Q(QWaylandTextInput);
95
96 if (!focusResource || !focusResource->handle)
97 return;
98
99 QWaylandTextInputClientState afterCommit;
100
101 afterCommit.surroundingText = currentState->surroundingText;
102 afterCommit.cursorPosition = qMin(currentState->cursorPosition, currentState->anchorPosition);
103
104 // Remove selection
105 afterCommit.surroundingText.remove(afterCommit.cursorPosition, qAbs(currentState->cursorPosition - currentState->anchorPosition));
106
107 if (event->replacementLength() > 0 || event->replacementStart() != 0) {
108 // Remove replacement
109 afterCommit.cursorPosition = qBound(0, afterCommit.cursorPosition + event->replacementStart(), afterCommit.surroundingText.size());
110 afterCommit.surroundingText.remove(afterCommit.cursorPosition,
111 qMin(event->replacementLength(),
112 afterCommit.surroundingText.size() - afterCommit.cursorPosition));
113
114 if (event->replacementStart() <= 0 && (event->replacementLength() >= -event->replacementStart())) {
115 const int selectionStart = qMin(currentState->cursorPosition, currentState->anchorPosition);
116 const int selectionEnd = qMax(currentState->cursorPosition, currentState->anchorPosition);
117 const int before = QWaylandInputMethodEventBuilder::indexToWayland(currentState->surroundingText, -event->replacementStart(), selectionStart + event->replacementStart());
118 const int after = QWaylandInputMethodEventBuilder::indexToWayland(currentState->surroundingText, event->replacementLength() + event->replacementStart(), selectionEnd);
119 send_delete_surrounding_text(focusResource->handle, before, after);
120 } else {
121 // TODO: Implement this case
122 qWarning() << "Not yet supported case of replacement. Start:" << event->replacementStart() << "length:" << event->replacementLength();
123 }
124 }
125
126 // Insert commit string
127 afterCommit.surroundingText.insert(afterCommit.cursorPosition, event->commitString());
128 afterCommit.cursorPosition += event->commitString().size();
129 afterCommit.anchorPosition = afterCommit.cursorPosition;
130
131 for (const QInputMethodEvent::Attribute &attribute : event->attributes()) {
132 if (attribute.type == QInputMethodEvent::Selection) {
133 afterCommit.cursorPosition = attribute.start;
134 afterCommit.anchorPosition = attribute.length;
135 int cursor = QWaylandInputMethodEventBuilder::indexToWayland(afterCommit.surroundingText, qAbs(attribute.start - afterCommit.cursorPosition), qMin(attribute.start, afterCommit.cursorPosition));
136 int anchor = QWaylandInputMethodEventBuilder::indexToWayland(afterCommit.surroundingText, qAbs(attribute.length - afterCommit.cursorPosition), qMin(attribute.length, afterCommit.cursorPosition));
137 send_cursor_position(focusResource->handle,
138 attribute.start < afterCommit.cursorPosition ? -cursor : cursor,
139 attribute.length < afterCommit.cursorPosition ? -anchor : anchor);
140 }
141 }
142 send_commit_string(focusResource->handle, event->commitString());
143 for (const QInputMethodEvent::Attribute &attribute : event->attributes()) {
144 if (attribute.type == QInputMethodEvent::Cursor) {
145 int index = QWaylandInputMethodEventBuilder::indexToWayland(event->preeditString(), attribute.start);
146 send_preedit_cursor(focusResource->handle, index);
147 } else if (attribute.type == QInputMethodEvent::TextFormat) {
148 int start = QWaylandInputMethodEventBuilder::indexToWayland(event->preeditString(), attribute.start);
149 int length = QWaylandInputMethodEventBuilder::indexToWayland(event->preeditString(), attribute.length, attribute.start);
150 // TODO add support for different stylesQWaylandTextInput
151 send_preedit_styling(focusResource->handle, start, length, preedit_style_default);
152 }
153 }
154 send_preedit_string(focusResource->handle, event->preeditString(), event->preeditString());
155
156 Qt::InputMethodQueries queries = currentState->updatedQueries(afterCommit);
157 currentState->surroundingText = afterCommit.surroundingText;
158 currentState->cursorPosition = afterCommit.cursorPosition;
159 currentState->anchorPosition = afterCommit.anchorPosition;
160
161 if (queries) {
162 qCDebug(qLcWaylandCompositorInputMethods) << "QInputMethod::update() after QInputMethodEvent" << queries;
163
164 emit q->updateInputMethod(queries);
165 }
166}
167
168void QWaylandTextInputPrivate::sendKeyEvent(QKeyEvent *event)
169{
170 if (!focusResource || !focusResource->handle)
171 return;
172
173 uint mods = 0;
174 const auto &qtMods = event->modifiers();
175 if (qtMods & Qt::ShiftModifier)
176 mods |= shiftModifierMask;
177 if (qtMods & Qt::ControlModifier)
178 mods |= controlModifierMask;
179 if (qtMods & Qt::AltModifier)
180 mods |= altModifierMask;
181 if (qtMods & Qt::MetaModifier)
182 mods |= metaModifierMask;
183
184#if QT_CONFIG(xkbcommon)
185 const auto keysyms = QXkbCommon::toKeysym(event);
186 for (xkb_keysym_t keysym : keysyms) {
187 send_keysym(focusResource->handle, event->timestamp(), keysym,
188 event->type() == QEvent::KeyPress ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED,
189 mods);
190 }
191#else
192 Q_UNUSED(event);
193#endif
194}
195
196void QWaylandTextInputPrivate::sendInputPanelState()
197{
198 if (!focusResource || !focusResource->handle)
199 return;
200
201 QInputMethod *inputMethod = qApp->inputMethod();
202 const QRectF& keyboardRect = inputMethod->keyboardRectangle();
203 const QRectF& sceneInputRect = inputMethod->inputItemTransform().mapRect(inputMethod->inputItemRectangle());
204 const QRectF& localRect = sceneInputRect.intersected(keyboardRect).translated(-sceneInputRect.topLeft());
205
206 send_input_panel_state(focusResource->handle,
207 inputMethod->isVisible() ? input_panel_visibility_visible : input_panel_visibility_hidden,
208 localRect.x(), localRect.y(), localRect.width(), localRect.height());
209}
210
211void QWaylandTextInputPrivate::sendTextDirection()
212{
213 if (!focusResource || !focusResource->handle)
214 return;
215
216 const Qt::LayoutDirection direction = qApp->inputMethod()->inputDirection();
217 send_text_direction(focusResource->handle,
218 (direction == Qt::LeftToRight) ? text_direction_ltr :
219 (direction == Qt::RightToLeft) ? text_direction_rtl : text_direction_auto);
220}
221
222void QWaylandTextInputPrivate::sendLocale()
223{
224 if (!focusResource || !focusResource->handle)
225 return;
226
227 const QLocale locale = qApp->inputMethod()->locale();
228 send_language(focusResource->handle, locale.bcp47Name());
229}
230
231QVariant QWaylandTextInputPrivate::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
232{
233 switch (property) {
234 case Qt::ImHints:
235 return QVariant(static_cast<int>(currentState->hints));
236 case Qt::ImCursorRectangle:
237 return currentState->cursorRectangle;
238 case Qt::ImFont:
239 // Not supported
240 return QVariant();
241 case Qt::ImCursorPosition:
242 return currentState->cursorPosition;
243 case Qt::ImSurroundingText:
244 return currentState->surroundingText;
245 case Qt::ImCurrentSelection:
246 return currentState->surroundingText.mid(qMin(currentState->cursorPosition, currentState->anchorPosition),
247 qAbs(currentState->anchorPosition - currentState->cursorPosition));
248 case Qt::ImMaximumTextLength:
249 // Not supported
250 return QVariant();
251 case Qt::ImAnchorPosition:
252 return currentState->anchorPosition;
253 case Qt::ImAbsolutePosition:
254 // We assume the surrounding text is our whole document for now
255 return currentState->cursorPosition;
256 case Qt::ImTextAfterCursor:
257 if (argument.isValid())
258 return currentState->surroundingText.mid(currentState->cursorPosition, argument.toInt());
259 return currentState->surroundingText.mid(currentState->cursorPosition);
260 case Qt::ImTextBeforeCursor:
261 if (argument.isValid())
262 return currentState->surroundingText.left(currentState->cursorPosition).right(argument.toInt());
263 return currentState->surroundingText.left(currentState->cursorPosition);
264 case Qt::ImPreferredLanguage:
265 return currentState->preferredLanguage;
266
267 default:
268 return QVariant();
269 }
270}
271
272void QWaylandTextInputPrivate::setFocus(QWaylandSurface *surface)
273{
274 Q_Q(QWaylandTextInput);
275
276 if (focusResource && focus != surface) {
277 uint32_t serial = compositor->nextSerial();
278 send_leave(focusResource->handle, serial, focus->resource());
279 focusDestroyListener.reset();
280 }
281
282 Resource *resource = surface ? resourceMap().value(surface->waylandClient()) : 0;
283
284 if (resource && (focus != surface || focusResource != resource)) {
285 uint32_t serial = compositor->nextSerial();
286 currentState.reset(new QWaylandTextInputClientState);
287 pendingState.reset(new QWaylandTextInputClientState);
288 send_enter(resource->handle, serial, surface->resource());
289 focusResource = resource;
290 sendInputPanelState();
291 sendLocale();
292 sendTextDirection();
293 focusDestroyListener.listenForDestruction(surface->resource());
294 if (inputPanelVisible && q->isSurfaceEnabled(surface))
295 qApp->inputMethod()->show();
296 }
297
298 focusResource = resource;
299 focus = surface;
300}
301
302void QWaylandTextInputPrivate::sendModifiersMap(const QByteArray &modifiersMap)
303{
304 send_modifiers_map(focusResource->handle, modifiersMap);
305}
306
307#if !QT_CONFIG(xkbcommon)
308#define XKB_MOD_NAME_SHIFT "Shift"
309#define XKB_MOD_NAME_CTRL "Control"
310#define XKB_MOD_NAME_ALT "Mod1"
311#define XKB_MOD_NAME_LOGO "Mod4"
312#endif
313void QWaylandTextInputPrivate::zwp_text_input_v2_bind_resource(Resource *resource)
314{
315 QByteArray modifiers = XKB_MOD_NAME_SHIFT + QByteArray(1, '\0');
316 modifiers += XKB_MOD_NAME_CTRL + QByteArray(1, '\0');
317 modifiers += XKB_MOD_NAME_ALT + QByteArray(1, '\0');
318 modifiers += XKB_MOD_NAME_LOGO + QByteArray(1, '\0');
319 send_modifiers_map(resource->handle, modifiers);
320}
321
322void QWaylandTextInputPrivate::zwp_text_input_v2_destroy_resource(Resource *resource)
323{
324 if (focusResource == resource)
325 focusResource = nullptr;
326}
327
328void QWaylandTextInputPrivate::zwp_text_input_v2_destroy(Resource *resource)
329{
330 wl_resource_destroy(resource->handle);
331}
332
333void QWaylandTextInputPrivate::zwp_text_input_v2_enable(Resource *resource, wl_resource *surface)
334{
335 Q_Q(QWaylandTextInput);
336
337 QWaylandSurface *s = QWaylandSurface::fromResource(surface);
338 enabledSurfaces.insert(resource, s);
339
340#if QT_CONFIG(im)
341 QWaylandInputMethodControl *control = s->inputMethodControl();
342 if (control)
343 control->updateTextInput();
344#endif
345
346 emit q->surfaceEnabled(s);
347}
348
349void QWaylandTextInputPrivate::zwp_text_input_v2_disable(QtWaylandServer::zwp_text_input_v2::Resource *resource, wl_resource *)
350{
351 Q_Q(QWaylandTextInput);
352
353 QWaylandSurface *s = enabledSurfaces.take(resource);
354 emit q->surfaceDisabled(s);
355}
356
357void QWaylandTextInputPrivate::zwp_text_input_v2_show_input_panel(Resource *)
358{
359 inputPanelVisible = true;
360
361 qApp->inputMethod()->show();
362}
363
364void QWaylandTextInputPrivate::zwp_text_input_v2_hide_input_panel(Resource *)
365{
366 inputPanelVisible = false;
367
368 qApp->inputMethod()->hide();
369}
370
371void QWaylandTextInputPrivate::zwp_text_input_v2_set_cursor_rectangle(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height)
372{
373 if (resource != focusResource)
374 return;
375
376 pendingState->cursorRectangle = QRect(x, y, width, height);
377
378 pendingState->changedState |= Qt::ImCursorRectangle;
379}
380
381void QWaylandTextInputPrivate::zwp_text_input_v2_update_state(Resource *resource, uint32_t serial, uint32_t flags)
382{
383 Q_Q(QWaylandTextInput);
384
385 qCDebug(qLcWaylandCompositorInputMethods) << "update_state" << serial << flags;
386
387 if (resource != focusResource)
388 return;
389
390 if (flags == update_state_reset || flags == update_state_enter) {
391 qCDebug(qLcWaylandCompositorInputMethods) << "QInputMethod::reset()";
392 qApp->inputMethod()->reset();
393 }
394
395 this->serial = serial;
396
397 Qt::InputMethodQueries queries;
398 if (flags == update_state_change) {
399 queries = currentState->mergeChanged(*pendingState);
400 } else {
401 queries = pendingState->updatedQueries(*currentState);
402 currentState.swap(pendingState);
403 }
404
405 pendingState.reset(new QWaylandTextInputClientState);
406
407 if (queries) {
408 qCDebug(qLcWaylandCompositorInputMethods) << "QInputMethod::update()" << queries;
409
410 emit q->updateInputMethod(queries);
411 }
412}
413
414void QWaylandTextInputPrivate::zwp_text_input_v2_set_content_type(Resource *resource, uint32_t hint, uint32_t purpose)
415{
416 if (resource != focusResource)
417 return;
418
419 pendingState->hints = Qt::ImhNone;
420
421 if ((hint & content_hint_auto_completion) == 0
422 && (hint & content_hint_auto_correction) == 0)
423 pendingState->hints |= Qt::ImhNoPredictiveText;
424 if ((hint & content_hint_auto_capitalization) == 0)
425 pendingState->hints |= Qt::ImhNoAutoUppercase;
426 if ((hint & content_hint_lowercase) != 0)
427 pendingState->hints |= Qt::ImhPreferLowercase;
428 if ((hint & content_hint_uppercase) != 0)
429 pendingState->hints |= Qt::ImhPreferUppercase;
430 if ((hint & content_hint_hidden_text) != 0)
431 pendingState->hints |= Qt::ImhHiddenText;
432 if ((hint & content_hint_sensitive_data) != 0)
433 pendingState->hints |= Qt::ImhSensitiveData;
434 if ((hint & content_hint_latin) != 0)
435 pendingState->hints |= Qt::ImhLatinOnly;
436 if ((hint & content_hint_multiline) != 0)
437 pendingState->hints |= Qt::ImhMultiLine;
438
439 switch (purpose) {
440 case content_purpose_normal:
441 break;
442 case content_purpose_alpha:
443 pendingState->hints |= Qt::ImhUppercaseOnly | Qt::ImhLowercaseOnly;
444 break;
445 case content_purpose_digits:
446 pendingState->hints |= Qt::ImhDigitsOnly;
447 break;
448 case content_purpose_number:
449 pendingState->hints |= Qt::ImhFormattedNumbersOnly;
450 break;
451 case content_purpose_phone:
452 pendingState->hints |= Qt::ImhDialableCharactersOnly;
453 break;
454 case content_purpose_url:
455 pendingState->hints |= Qt::ImhUrlCharactersOnly;
456 break;
457 case content_purpose_email:
458 pendingState->hints |= Qt::ImhEmailCharactersOnly;
459 break;
460 case content_purpose_name:
461 case content_purpose_password:
462 break;
463 case content_purpose_date:
464 pendingState->hints |= Qt::ImhDate;
465 break;
466 case content_purpose_time:
467 pendingState->hints |= Qt::ImhTime;
468 break;
469 case content_purpose_datetime:
470 pendingState->hints |= Qt::ImhDate | Qt::ImhTime;
471 break;
472 case content_purpose_terminal:
473 default:
474 break;
475 }
476
477 pendingState->changedState |= Qt::ImHints;
478}
479
480void QWaylandTextInputPrivate::zwp_text_input_v2_set_preferred_language(Resource *resource, const QString &language)
481{
482 if (resource != focusResource)
483 return;
484
485 pendingState->preferredLanguage = language;
486
487 pendingState->changedState |= Qt::ImPreferredLanguage;
488}
489
490void QWaylandTextInputPrivate::zwp_text_input_v2_set_surrounding_text(Resource *resource, const QString &text, int32_t cursor, int32_t anchor)
491{
492 if (resource != focusResource)
493 return;
494
495 pendingState->surroundingText = text;
496 pendingState->cursorPosition = QWaylandInputMethodEventBuilder::indexFromWayland(text, cursor);
497 pendingState->anchorPosition = QWaylandInputMethodEventBuilder::indexFromWayland(text, anchor);
498
499 pendingState->changedState |= Qt::ImSurroundingText | Qt::ImCursorPosition | Qt::ImAnchorPosition;
500}
501
502QWaylandTextInput::QWaylandTextInput(QWaylandObject *container, QWaylandCompositor *compositor)
503 : QWaylandCompositorExtensionTemplate(container, *new QWaylandTextInputPrivate(compositor))
504{
505 connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired,
506 this, &QWaylandTextInput::focusSurfaceDestroyed);
507
508 connect(qApp->inputMethod(), &QInputMethod::visibleChanged,
509 this, &QWaylandTextInput::sendInputPanelState);
510 connect(qApp->inputMethod(), &QInputMethod::keyboardRectangleChanged,
511 this, &QWaylandTextInput::sendInputPanelState);
512 connect(qApp->inputMethod(), &QInputMethod::inputDirectionChanged,
513 this, &QWaylandTextInput::sendTextDirection);
514 connect(qApp->inputMethod(), &QInputMethod::localeChanged,
515 this, &QWaylandTextInput::sendLocale);
516}
517
521
522void QWaylandTextInput::sendInputMethodEvent(QInputMethodEvent *event)
523{
524 Q_D(QWaylandTextInput);
525
526 d->sendInputMethodEvent(event);
527}
528
529void QWaylandTextInput::sendKeyEvent(QKeyEvent *event)
530{
531 Q_D(QWaylandTextInput);
532
533 d->sendKeyEvent(event);
534}
535
536void QWaylandTextInput::sendInputPanelState()
537{
538 Q_D(QWaylandTextInput);
539
540 d->sendInputPanelState();
541}
542
543void QWaylandTextInput::sendTextDirection()
544{
545 Q_D(QWaylandTextInput);
546
547 d->sendTextDirection();
548}
549
550void QWaylandTextInput::sendLocale()
551{
552 Q_D(QWaylandTextInput);
553
554 d->sendLocale();
555}
556
557QVariant QWaylandTextInput::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
558{
559 const Q_D(QWaylandTextInput);
560
561 return d->inputMethodQuery(property, argument);
562}
563
564QWaylandSurface *QWaylandTextInput::focus() const
565{
566 const Q_D(QWaylandTextInput);
567
568 return d->focus;
569}
570
571void QWaylandTextInput::setFocus(QWaylandSurface *surface)
572{
573 Q_D(QWaylandTextInput);
574
575 d->setFocus(surface);
576}
577
578void QWaylandTextInput::focusSurfaceDestroyed(void *)
579{
580 Q_D(QWaylandTextInput);
581
582 d->focusDestroyListener.reset();
583
584 d->focus = nullptr;
585 d->focusResource = nullptr;
586}
587
588bool QWaylandTextInput::isSurfaceEnabled(QWaylandSurface *surface) const
589{
590 const Q_D(QWaylandTextInput);
591
592 return d->enabledSurfaces.values().contains(surface);
593}
594
595void QWaylandTextInput::add(::wl_client *client, uint32_t id, int version)
596{
597 Q_D(QWaylandTextInput);
598
599 d->add(client, id, version);
600}
601
602const wl_interface *QWaylandTextInput::interface()
603{
604 return QWaylandTextInputPrivate::interface();
605}
606
607QByteArray QWaylandTextInput::interfaceName()
608{
609 return QWaylandTextInputPrivate::interfaceName();
610}
611
612
613void QWaylandTextInput::sendModifiersMap(const QByteArray &modifiersMap)
614{
615 Q_D(QWaylandTextInput);
616
617 const QList<QByteArray> modifiers = modifiersMap.split('\0');
618
619 int numModifiers = modifiers.size();
620 if (modifiers.last().isEmpty())
621 numModifiers--;
622
623 for (int i = 0; i < numModifiers; ++i) {
624 const auto modString = modifiers.at(i);
625 if (modString == XKB_MOD_NAME_SHIFT)
626 d->shiftModifierMask = 1 << i;
627 else if (modString == XKB_MOD_NAME_CTRL)
628 d->controlModifierMask = 1 << i;
629 else if (modString == XKB_MOD_NAME_ALT)
630 d->altModifierMask = 1 << i;
631 else if (modString == XKB_MOD_NAME_LOGO)
632 d->metaModifierMask = 1 << i;
633 else
634 qCDebug(qLcWaylandCompositorInputMethods) << "unsupported modifier name " << modString;
635 }
636 d->sendModifiersMap(modifiersMap);
637}
638
639QT_END_NAMESPACE
640
641#include "moc_qwaylandtextinput.cpp"
Qt::InputMethodQueries updatedQueries(const QWaylandTextInputClientState &other) const
Qt::InputMethodQueries mergeChanged(const QWaylandTextInputClientState &other)
void sendInputMethodEvent(QInputMethodEvent *event)
void sendModifiersMap(const QByteArray &modifiersMap)
QVariant inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
void setFocus(QWaylandSurface *surface)
bool isSurfaceEnabled(QWaylandSurface *surface) const
void add(::wl_client *client, uint32_t id, int version)
QWaylandSurface * focus() const
static const struct wl_interface * interface()
void sendKeyEvent(QKeyEvent *event)
Combined button and popup list for selecting options.