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