6 #include "event_queue.h"
9 #include "textinput_p.h"
10 #include "wayland_pointer_p.h"
12 #include <wayland-text-input-v2-client-protocol.h>
18 class TextInputUnstableV2::Private :
public TextInput::Private
21 Private(TextInputUnstableV2 *q, Seat *seat);
23 void setup(zwp_text_input_v2 *textinputmanagerunstablev0);
26 void enable(Surface *surface)
override;
27 void disable(Surface *surface)
override;
28 void showInputPanel()
override;
29 void hideInputPanel()
override;
30 void setCursorRectangle(
const QRect &rect)
override;
31 void setPreferredLanguage(
const QString &lang)
override;
32 void setSurroundingText(
const QString &text, quint32 cursor, quint32 anchor)
override;
33 void reset()
override;
34 void setContentType(ContentHints hint, ContentPurpose purpose)
override;
36 WaylandPointer<zwp_text_input_v2, zwp_text_input_v2_destroy> textinputunstablev2;
39 static void enterCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface);
40 static void leaveCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface);
41 static void inputPanelStateCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t state, int32_t x, int32_t y, int32_t width, int32_t height);
42 static void preeditStringCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2,
const char *text,
const char *commit);
43 static void preeditStylingCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t index, uint32_t length, uint32_t style);
44 static void preeditCursorCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index);
45 static void commitStringCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2,
const char *text);
46 static void cursorPositionCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index, int32_t anchor);
47 static void deleteSurroundingTextCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t before_length, uint32_t after_length);
48 static void modifiersMapCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, wl_array *map);
49 static void keysymCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers);
50 static void languageCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2,
const char *language);
51 static void textDirectionCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t direction);
52 static void configureSurroundingTextCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t before_cursor, int32_t after_cursor);
53 static void inputMethodChangedCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, uint32_t flags);
55 TextInputUnstableV2 *q;
57 static const zwp_text_input_v2_listener s_listener;
60 const zwp_text_input_v2_listener TextInputUnstableV2::Private::s_listener = {enterCallback,
62 inputPanelStateCallback,
63 preeditStringCallback,
64 preeditStylingCallback,
65 preeditCursorCallback,
67 cursorPositionCallback,
68 deleteSurroundingTextCallback,
72 textDirectionCallback,
73 configureSurroundingTextCallback,
74 inputMethodChangedCallback};
76 void TextInputUnstableV2::Private::enterCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface)
78 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
79 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
80 t->latestSerial = serial;
82 Q_EMIT t->q->entered();
85 void TextInputUnstableV2::Private::leaveCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface)
88 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
89 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
90 t->enteredSurface =
nullptr;
91 t->latestSerial = serial;
95 void TextInputUnstableV2::Private::inputPanelStateCallback(
void *data,
96 zwp_text_input_v2 *zwp_text_input_v2,
107 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
108 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
110 if (t->inputPanelVisible != state) {
111 t->inputPanelVisible = state;
112 Q_EMIT t->q->inputPanelStateChanged();
116 void TextInputUnstableV2::Private::preeditStringCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2,
const char *text,
const char *commit)
118 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
119 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
120 t->pendingPreEdit.commitText =
QByteArray(commit);
122 if (!t->pendingPreEdit.cursorSet) {
123 t->pendingPreEdit.cursor = t->pendingPreEdit.text.length();
125 t->currentPreEdit = t->pendingPreEdit;
126 t->pendingPreEdit = TextInput::Private::PreEdit();
127 Q_EMIT t->q->composingTextChanged();
130 void TextInputUnstableV2::Private::preeditStylingCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t index, uint32_t length, uint32_t style)
136 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
137 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
140 void TextInputUnstableV2::Private::preeditCursorCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index)
142 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
143 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
144 t->pendingPreEdit.cursor = index;
145 t->pendingPreEdit.cursorSet =
true;
148 void TextInputUnstableV2::Private::commitStringCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2,
const char *text)
150 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
151 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
153 t->currentCommit = t->pendingCommit;
155 t->pendingCommit = TextInput::Private::Commit();
156 t->pendingCommit.deleteSurrounding.beforeLength = 0;
157 t->pendingCommit.deleteSurrounding.afterLength = 0;
158 Q_EMIT t->q->committed();
161 void TextInputUnstableV2::Private::cursorPositionCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index, int32_t anchor)
163 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
164 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
165 t->pendingCommit.cursor = index;
166 t->pendingCommit.anchor = anchor;
169 void TextInputUnstableV2::Private::deleteSurroundingTextCallback(
void *data,
170 zwp_text_input_v2 *zwp_text_input_v2,
171 uint32_t before_length,
172 uint32_t after_length)
174 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
175 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
176 t->pendingCommit.deleteSurrounding.beforeLength = before_length;
177 t->pendingCommit.deleteSurrounding.afterLength = after_length;
180 void TextInputUnstableV2::Private::modifiersMapCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, wl_array *map)
184 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
185 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
188 void TextInputUnstableV2::Private::keysymCallback(
void *data,
189 zwp_text_input_v2 *zwp_text_input_v2,
197 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
198 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
201 case WL_KEYBOARD_KEY_STATE_RELEASED:
202 state = TextInput::KeyState::Released;
204 case WL_KEYBOARD_KEY_STATE_PRESSED:
205 state = TextInput::KeyState::Pressed;
214 void TextInputUnstableV2::Private::languageCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2,
const char *language)
216 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
217 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
218 if (qstrcmp(t->language, language) != 0) {
220 Q_EMIT t->q->languageChanged();
224 void TextInputUnstableV2::Private::textDirectionCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t wlDirection)
226 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
227 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
229 switch (wlDirection) {
230 case ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_LTR:
233 case ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_RTL:
236 case ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_AUTO:
243 if (direction != t->textDirection) {
244 t->textDirection = direction;
245 Q_EMIT t->q->textDirectionChanged();
249 void TextInputUnstableV2::Private::configureSurroundingTextCallback(
void *data,
250 zwp_text_input_v2 *zwp_text_input_v2,
251 int32_t before_cursor,
252 int32_t after_cursor)
255 Q_UNUSED(before_cursor)
256 Q_UNUSED(after_cursor)
257 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
258 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
261 void TextInputUnstableV2::Private::inputMethodChangedCallback(
void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, uint32_t flags)
266 auto t =
reinterpret_cast<TextInputUnstableV2::Private *
>(data);
267 Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
270 TextInputUnstableV2::Private::Private(TextInputUnstableV2 *q, Seat *seat)
271 : TextInput::Private(seat)
276 void TextInputUnstableV2::Private::setup(zwp_text_input_v2 *ti)
279 Q_ASSERT(!textinputunstablev2);
280 textinputunstablev2.setup(ti);
281 zwp_text_input_v2_add_listener(ti, &s_listener,
this);
284 bool TextInputUnstableV2::Private::isValid()
const
286 return textinputunstablev2.isValid();
289 void TextInputUnstableV2::Private::enable(Surface *surface)
291 zwp_text_input_v2_enable(textinputunstablev2, *surface);
294 void TextInputUnstableV2::Private::disable(Surface *surface)
296 zwp_text_input_v2_disable(textinputunstablev2, *surface);
299 void TextInputUnstableV2::Private::showInputPanel()
301 zwp_text_input_v2_show_input_panel(textinputunstablev2);
304 void TextInputUnstableV2::Private::hideInputPanel()
306 zwp_text_input_v2_hide_input_panel(textinputunstablev2);
309 void TextInputUnstableV2::Private::setCursorRectangle(
const QRect &rect)
311 zwp_text_input_v2_set_cursor_rectangle(textinputunstablev2, rect.
x(), rect.
y(), rect.
width(), rect.
height());
314 void TextInputUnstableV2::Private::setPreferredLanguage(
const QString &lang)
316 zwp_text_input_v2_set_preferred_language(textinputunstablev2, lang.
toUtf8().
constData());
319 void TextInputUnstableV2::Private::setSurroundingText(
const QString &text, quint32 cursor, quint32 anchor)
323 zwp_text_input_v2_set_surrounding_text(textinputunstablev2,
325 strView.left(cursor).toUtf8().length(),
326 strView.left(anchor).toUtf8().length());
329 void TextInputUnstableV2::Private::reset()
331 zwp_text_input_v2_update_state(textinputunstablev2, latestSerial, ZWP_TEXT_INPUT_V2_UPDATE_STATE_RESET);
334 void TextInputUnstableV2::Private::setContentType(ContentHints hints, ContentPurpose purpose)
336 uint32_t wlHints = 0;
337 uint32_t wlPurpose = 0;
338 if (hints.testFlag(ContentHint::AutoCompletion)) {
339 wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_COMPLETION;
341 if (hints.testFlag(ContentHint::AutoCorrection)) {
342 wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_CORRECTION;
344 if (hints.testFlag(ContentHint::AutoCapitalization)) {
345 wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_CAPITALIZATION;
347 if (hints.testFlag(ContentHint::LowerCase)) {
348 wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_LOWERCASE;
350 if (hints.testFlag(ContentHint::UpperCase)) {
351 wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_UPPERCASE;
353 if (hints.testFlag(ContentHint::TitleCase)) {
354 wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_TITLECASE;
356 if (hints.testFlag(ContentHint::HiddenText)) {
357 wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_HIDDEN_TEXT;
359 if (hints.testFlag(ContentHint::SensitiveData)) {
360 wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_SENSITIVE_DATA;
362 if (hints.testFlag(ContentHint::Latin)) {
363 wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_LATIN;
365 if (hints.testFlag(ContentHint::MultiLine)) {
366 wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_MULTILINE;
369 case ContentPurpose::Normal:
370 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NORMAL;
372 case ContentPurpose::Alpha:
373 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_ALPHA;
375 case ContentPurpose::Digits:
376 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DIGITS;
378 case ContentPurpose::Number:
379 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NUMBER;
381 case ContentPurpose::Phone:
382 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_PHONE;
384 case ContentPurpose::Url:
385 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_URL;
387 case ContentPurpose::Email:
388 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_EMAIL;
390 case ContentPurpose::Name:
391 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NAME;
393 case ContentPurpose::Password:
394 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_PASSWORD;
396 case ContentPurpose::Date:
397 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DATE;
399 case ContentPurpose::Time:
400 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_TIME;
402 case ContentPurpose::DateTime:
403 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DATETIME;
405 case ContentPurpose::Terminal:
406 wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_TERMINAL;
409 zwp_text_input_v2_set_content_type(textinputunstablev2, wlHints, wlPurpose);
412 TextInputUnstableV2::TextInputUnstableV2(Seat *seat,
QObject *parent)
413 : TextInput(new Private(this, seat), parent)
417 TextInputUnstableV2::~TextInputUnstableV2()
422 TextInputUnstableV2::Private *TextInputUnstableV2::d_func()
const
424 return reinterpret_cast<Private *
>(d.data());
427 void TextInputUnstableV2::setup(zwp_text_input_v2 *textinputunstablev2)
430 d->setup(textinputunstablev2);
436 d->textinputunstablev2.release();
439 void TextInputUnstableV2::destroy()
442 d->textinputunstablev2.destroy();
445 TextInputUnstableV2::operator zwp_text_input_v2 *()
448 return d->textinputunstablev2;
451 TextInputUnstableV2::operator zwp_text_input_v2 *()
const
454 return d->textinputunstablev2;
457 class TextInputManagerUnstableV2::Private :
public TextInputManager::Private
463 void destroy()
override;
465 void setupV2(zwp_text_input_manager_v2 *ti)
override;
466 TextInput *createTextInput(Seat *seat,
QObject *parent =
nullptr)
override;
467 using TextInputManager::Private::operator wl_text_input_manager *;
468 operator zwp_text_input_manager_v2 *()
override
470 return textinputmanagerunstablev2;
472 operator zwp_text_input_manager_v2 *()
const override
474 return textinputmanagerunstablev2;
477 WaylandPointer<zwp_text_input_manager_v2, zwp_text_input_manager_v2_destroy> textinputmanagerunstablev2;
482 textinputmanagerunstablev2.release();
485 void TextInputManagerUnstableV2::Private::destroy()
487 textinputmanagerunstablev2.destroy();
490 bool TextInputManagerUnstableV2::Private::isValid()
492 return textinputmanagerunstablev2.isValid();
495 TextInputManagerUnstableV2::TextInputManagerUnstableV2(
QObject *parent)
496 : TextInputManager(new Private, parent)
500 TextInputManagerUnstableV2::~TextInputManagerUnstableV2() =
default;
502 void TextInputManagerUnstableV2::Private::setupV2(zwp_text_input_manager_v2 *ti)
505 Q_ASSERT(!textinputmanagerunstablev2);
506 textinputmanagerunstablev2.setup(ti);
509 TextInput *TextInputManagerUnstableV2::Private::createTextInput(Seat *seat,
QObject *parent)
512 TextInputUnstableV2 *t =
new TextInputUnstableV2(seat, parent);
513 auto w = zwp_text_input_manager_v2_get_text_input(textinputmanagerunstablev2, *seat);