6 #include "event_queue.h"
9 #include "textinput_p.h"
10 #include "wayland_pointer_p.h"
12 #include <wayland-text-input-v0-client-protocol.h>
18 class TextInputUnstableV0::Private :
public TextInput::Private
21 Private(TextInputUnstableV0 *q, Seat *seat);
23 void setup(wl_text_input *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<wl_text_input, wl_text_input_destroy> textinputunstablev0;
39 static void enterCallaback(
void *data, wl_text_input *wl_text_input, wl_surface *surface);
40 static void leaveCallback(
void *data, wl_text_input *wl_text_input);
41 static void modifiersMapCallback(
void *data, wl_text_input *wl_text_input, wl_array *map);
42 static void inputPanelStateCallback(
void *data, wl_text_input *wl_text_input, uint32_t state);
43 static void preeditStringCallback(
void *data, wl_text_input *wl_text_input, uint32_t serial,
const char *text,
const char *commit);
44 static void preeditStylingCallback(
void *data, wl_text_input *wl_text_input, uint32_t index, uint32_t length, uint32_t style);
45 static void preeditCursorCallback(
void *data, wl_text_input *wl_text_input, int32_t index);
46 static void commitStringCallback(
void *data, wl_text_input *wl_text_input, uint32_t serial,
const char *text);
47 static void cursorPositionCallback(
void *data, wl_text_input *wl_text_input, int32_t index, int32_t anchor);
48 static void deleteSurroundingTextCallback(
void *data, wl_text_input *wl_text_input, int32_t index, uint32_t length);
49 static void keysymCallback(
void *data, wl_text_input *wl_text_input, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers);
50 static void languageCallback(
void *data, wl_text_input *wl_text_input, uint32_t serial,
const char *language);
51 static void textDirectionCallback(
void *data, wl_text_input *wl_text_input, uint32_t serial, uint32_t direction);
53 TextInputUnstableV0 *q;
55 static const wl_text_input_listener s_listener;
58 const wl_text_input_listener TextInputUnstableV0::Private::s_listener = {enterCallaback,
61 inputPanelStateCallback,
62 preeditStringCallback,
63 preeditStylingCallback,
64 preeditCursorCallback,
66 cursorPositionCallback,
67 deleteSurroundingTextCallback,
70 textDirectionCallback};
72 void TextInputUnstableV0::Private::enterCallaback(
void *data, wl_text_input *wl_text_input, wl_surface *surface)
74 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
75 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
77 Q_EMIT t->q->entered();
80 void TextInputUnstableV0::Private::leaveCallback(
void *data, wl_text_input *wl_text_input)
82 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
83 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
84 t->enteredSurface =
nullptr;
88 void TextInputUnstableV0::Private::modifiersMapCallback(
void *data, wl_text_input *wl_text_input, wl_array *map)
91 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
92 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
96 void TextInputUnstableV0::Private::inputPanelStateCallback(
void *data, wl_text_input *wl_text_input, uint32_t state)
98 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
99 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
100 if (t->inputPanelVisible != state) {
101 t->inputPanelVisible = state;
102 Q_EMIT t->q->inputPanelStateChanged();
106 void TextInputUnstableV0::Private::preeditStringCallback(
void *data, wl_text_input *wl_text_input, uint32_t serial,
const char *text,
const char *commit)
109 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
110 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
111 t->pendingPreEdit.commitText =
QByteArray(commit);
113 if (!t->pendingPreEdit.cursorSet) {
114 t->pendingPreEdit.cursor = t->pendingPreEdit.text.length();
116 t->currentPreEdit = t->pendingPreEdit;
117 t->pendingPreEdit = TextInput::Private::PreEdit();
118 Q_EMIT t->q->composingTextChanged();
121 void TextInputUnstableV0::Private::preeditStylingCallback(
void *data, wl_text_input *wl_text_input, uint32_t index, uint32_t length, uint32_t style)
127 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
128 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
131 void TextInputUnstableV0::Private::preeditCursorCallback(
void *data, wl_text_input *wl_text_input, int32_t index)
133 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
134 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
135 t->pendingPreEdit.cursor = index;
136 t->pendingPreEdit.cursorSet =
true;
139 void TextInputUnstableV0::Private::commitStringCallback(
void *data, wl_text_input *wl_text_input, uint32_t serial,
const char *text)
142 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
143 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
145 t->currentCommit = t->pendingCommit;
147 t->pendingCommit = TextInput::Private::Commit();
148 t->pendingCommit.deleteSurrounding.beforeLength = 0;
149 t->pendingCommit.deleteSurrounding.afterLength = 0;
150 Q_EMIT t->q->committed();
153 void TextInputUnstableV0::Private::cursorPositionCallback(
void *data, wl_text_input *wl_text_input, int32_t index, int32_t anchor)
155 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
156 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
157 t->pendingCommit.cursor = index;
158 t->pendingCommit.anchor = anchor;
161 void TextInputUnstableV0::Private::deleteSurroundingTextCallback(
void *data, wl_text_input *wl_text_input, int32_t index, uint32_t length)
163 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
164 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
165 t->pendingCommit.deleteSurrounding.beforeLength = qAbs(index);
166 t->pendingCommit.deleteSurrounding.afterLength = length - t->pendingCommit.deleteSurrounding.beforeLength;
169 void TextInputUnstableV0::Private::keysymCallback(
void *data,
170 wl_text_input *wl_text_input,
180 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
181 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
184 case WL_KEYBOARD_KEY_STATE_RELEASED:
185 state = TextInput::KeyState::Released;
187 case WL_KEYBOARD_KEY_STATE_PRESSED:
188 state = TextInput::KeyState::Pressed;
197 void TextInputUnstableV0::Private::languageCallback(
void *data, wl_text_input *wl_text_input, uint32_t serial,
const char *language)
200 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
201 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
202 if (qstrcmp(t->language, language) != 0) {
204 Q_EMIT t->q->languageChanged();
208 void TextInputUnstableV0::Private::textDirectionCallback(
void *data, wl_text_input *wl_text_input, uint32_t serial, uint32_t wlDirection)
211 auto t =
reinterpret_cast<TextInputUnstableV0::Private *
>(data);
212 Q_ASSERT(t->textinputunstablev0 == wl_text_input);
214 switch (wlDirection) {
215 case WL_TEXT_INPUT_TEXT_DIRECTION_LTR:
218 case WL_TEXT_INPUT_TEXT_DIRECTION_RTL:
221 case WL_TEXT_INPUT_TEXT_DIRECTION_AUTO:
228 if (direction != t->textDirection) {
229 t->textDirection = direction;
230 Q_EMIT t->q->textDirectionChanged();
234 TextInputUnstableV0::Private::Private(TextInputUnstableV0 *q, Seat *seat)
235 : TextInput::Private(seat)
240 void TextInputUnstableV0::Private::setup(wl_text_input *ti)
243 Q_ASSERT(!textinputunstablev0);
244 textinputunstablev0.setup(ti);
245 wl_text_input_add_listener(ti, &s_listener,
this);
248 bool TextInputUnstableV0::Private::isValid()
const
250 return textinputunstablev0.isValid();
253 void TextInputUnstableV0::Private::enable(Surface *surface)
255 wl_text_input_activate(textinputunstablev0, *seat, *surface);
258 void TextInputUnstableV0::Private::disable(Surface *surface)
261 wl_text_input_deactivate(textinputunstablev0, *seat);
264 void TextInputUnstableV0::Private::showInputPanel()
266 wl_text_input_show_input_panel(textinputunstablev0);
269 void TextInputUnstableV0::Private::hideInputPanel()
271 wl_text_input_hide_input_panel(textinputunstablev0);
274 void TextInputUnstableV0::Private::setCursorRectangle(
const QRect &rect)
276 wl_text_input_set_cursor_rectangle(textinputunstablev0, rect.
x(), rect.
y(), rect.
width(), rect.
height());
279 void TextInputUnstableV0::Private::setPreferredLanguage(
const QString &lang)
281 wl_text_input_set_preferred_language(textinputunstablev0, lang.
toUtf8().
constData());
284 void TextInputUnstableV0::Private::setSurroundingText(
const QString &text, quint32 cursor, quint32 anchor)
288 wl_text_input_set_surrounding_text(textinputunstablev0,
290 strView.left(cursor).toUtf8().length(),
291 strView.left(anchor).toUtf8().length());
294 void TextInputUnstableV0::Private::reset()
296 wl_text_input_reset(textinputunstablev0);
299 void TextInputUnstableV0::Private::setContentType(ContentHints hints, ContentPurpose purpose)
301 uint32_t wlHints = 0;
302 uint32_t wlPurpose = 0;
303 if (hints.testFlag(ContentHint::AutoCompletion)) {
304 wlHints |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
306 if (hints.testFlag(ContentHint::AutoCorrection)) {
307 wlHints |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_CORRECTION;
309 if (hints.testFlag(ContentHint::AutoCapitalization)) {
310 wlHints |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION;
312 if (hints.testFlag(ContentHint::LowerCase)) {
313 wlHints |= WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE;
315 if (hints.testFlag(ContentHint::UpperCase)) {
316 wlHints |= WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE;
318 if (hints.testFlag(ContentHint::TitleCase)) {
319 wlHints |= WL_TEXT_INPUT_CONTENT_HINT_TITLECASE;
321 if (hints.testFlag(ContentHint::HiddenText)) {
322 wlHints |= WL_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT;
324 if (hints.testFlag(ContentHint::SensitiveData)) {
325 wlHints |= WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA;
327 if (hints.testFlag(ContentHint::Latin)) {
328 wlHints |= WL_TEXT_INPUT_CONTENT_HINT_LATIN;
330 if (hints.testFlag(ContentHint::MultiLine)) {
331 wlHints |= WL_TEXT_INPUT_CONTENT_HINT_MULTILINE;
334 case ContentPurpose::Normal:
335 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL;
337 case ContentPurpose::Alpha:
338 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_ALPHA;
340 case ContentPurpose::Digits:
341 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS;
343 case ContentPurpose::Number:
344 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER;
346 case ContentPurpose::Phone:
347 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE;
349 case ContentPurpose::Url:
350 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_URL;
352 case ContentPurpose::Email:
353 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL;
355 case ContentPurpose::Name:
356 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NAME;
358 case ContentPurpose::Password:
359 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD;
361 case ContentPurpose::Date:
362 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DATE;
364 case ContentPurpose::Time:
365 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_TIME;
367 case ContentPurpose::DateTime:
368 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME;
370 case ContentPurpose::Terminal:
371 wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL;
374 wl_text_input_set_content_type(textinputunstablev0, wlHints, wlPurpose);
377 TextInputUnstableV0::TextInputUnstableV0(Seat *seat,
QObject *parent)
378 : TextInput(new Private(this, seat), parent)
382 TextInputUnstableV0::~TextInputUnstableV0()
387 TextInputUnstableV0::Private *TextInputUnstableV0::d_func()
const
389 return reinterpret_cast<Private *
>(d.data());
392 void TextInputUnstableV0::setup(wl_text_input *textinputunstablev0)
395 d->setup(textinputunstablev0);
401 d->textinputunstablev0.release();
404 void TextInputUnstableV0::destroy()
407 d->textinputunstablev0.destroy();
410 TextInputUnstableV0::operator wl_text_input *()
413 return d->textinputunstablev0;
416 TextInputUnstableV0::operator wl_text_input *()
const
419 return d->textinputunstablev0;
422 class TextInputManagerUnstableV0::Private :
public TextInputManager::Private
428 void destroy()
override;
430 void setupV0(wl_text_input_manager *ti)
override;
431 TextInput *createTextInput(Seat *seat,
QObject *parent =
nullptr)
override;
432 using TextInputManager::Private::operator zwp_text_input_manager_v2 *;
434 operator wl_text_input_manager *()
override
436 return textinputmanagerunstablev0;
438 operator wl_text_input_manager *()
const override
440 return textinputmanagerunstablev0;
443 WaylandPointer<wl_text_input_manager, wl_text_input_manager_destroy> textinputmanagerunstablev0;
448 textinputmanagerunstablev0.release();
451 void TextInputManagerUnstableV0::Private::destroy()
453 textinputmanagerunstablev0.destroy();
456 bool TextInputManagerUnstableV0::Private::isValid()
458 return textinputmanagerunstablev0.isValid();
461 TextInputManagerUnstableV0::TextInputManagerUnstableV0(
QObject *parent)
462 : TextInputManager(new Private, parent)
466 TextInputManagerUnstableV0::Private *TextInputManagerUnstableV0::d_func()
const
468 return reinterpret_cast<Private *
>(d.data());
471 TextInputManagerUnstableV0::~TextInputManagerUnstableV0()
476 void TextInputManagerUnstableV0::Private::setupV0(wl_text_input_manager *ti)
479 Q_ASSERT(!textinputmanagerunstablev0);
480 textinputmanagerunstablev0.setup(ti);
483 TextInput *TextInputManagerUnstableV0::Private::createTextInput(Seat *seat,
QObject *parent)
486 TextInputUnstableV0 *t =
new TextInputUnstableV0(seat, parent);
487 auto w = wl_text_input_manager_create_text_input(textinputmanagerunstablev0);