File indexing completed on 2024-12-22 05:09:25

0001 /*
0002     SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #include "event_queue.h"
0007 #include "seat.h"
0008 #include "surface.h"
0009 #include "textinput_p.h"
0010 #include "wayland_pointer_p.h"
0011 
0012 #include <wayland-text-input-v2-client-protocol.h>
0013 
0014 namespace KWayland
0015 {
0016 namespace Client
0017 {
0018 class TextInputUnstableV2::Private : public TextInput::Private
0019 {
0020 public:
0021     Private(TextInputUnstableV2 *q, Seat *seat);
0022 
0023     void setup(zwp_text_input_v2 *textinputmanagerunstablev0);
0024 
0025     bool isValid() const override;
0026     void enable(Surface *surface) override;
0027     void disable(Surface *surface) override;
0028     void showInputPanel() override;
0029     void hideInputPanel() override;
0030     void setCursorRectangle(const QRect &rect) override;
0031     void setPreferredLanguage(const QString &lang) override;
0032     void setSurroundingText(const QString &text, quint32 cursor, quint32 anchor) override;
0033     void reset() override;
0034     void setContentType(ContentHints hint, ContentPurpose purpose) override;
0035 
0036     WaylandPointer<zwp_text_input_v2, zwp_text_input_v2_destroy> textinputunstablev2;
0037 
0038 private:
0039     static void enterCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface);
0040     static void leaveCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface);
0041     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);
0042     static void preeditStringCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *text, const char *commit);
0043     static void preeditStylingCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t index, uint32_t length, uint32_t style);
0044     static void preeditCursorCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index);
0045     static void commitStringCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *text);
0046     static void cursorPositionCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index, int32_t anchor);
0047     static void deleteSurroundingTextCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t before_length, uint32_t after_length);
0048     static void modifiersMapCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, wl_array *map);
0049     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);
0050     static void languageCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *language);
0051     static void textDirectionCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t direction);
0052     static void configureSurroundingTextCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t before_cursor, int32_t after_cursor);
0053     static void inputMethodChangedCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, uint32_t flags);
0054 
0055     TextInputUnstableV2 *q;
0056 
0057     static const zwp_text_input_v2_listener s_listener;
0058 };
0059 
0060 const zwp_text_input_v2_listener TextInputUnstableV2::Private::s_listener = {enterCallback,
0061                                                                              leaveCallback,
0062                                                                              inputPanelStateCallback,
0063                                                                              preeditStringCallback,
0064                                                                              preeditStylingCallback,
0065                                                                              preeditCursorCallback,
0066                                                                              commitStringCallback,
0067                                                                              cursorPositionCallback,
0068                                                                              deleteSurroundingTextCallback,
0069                                                                              modifiersMapCallback,
0070                                                                              keysymCallback,
0071                                                                              languageCallback,
0072                                                                              textDirectionCallback,
0073                                                                              configureSurroundingTextCallback,
0074                                                                              inputMethodChangedCallback};
0075 
0076 void TextInputUnstableV2::Private::enterCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface)
0077 {
0078     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0079     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0080     t->latestSerial = serial;
0081     t->enteredSurface = Surface::get(surface);
0082     Q_EMIT t->q->entered();
0083 }
0084 
0085 void TextInputUnstableV2::Private::leaveCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface)
0086 {
0087     Q_UNUSED(surface)
0088     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0089     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0090     t->enteredSurface = nullptr;
0091     t->latestSerial = serial;
0092     Q_EMIT t->q->left();
0093 }
0094 
0095 void TextInputUnstableV2::Private::inputPanelStateCallback(void *data,
0096                                                            zwp_text_input_v2 *zwp_text_input_v2,
0097                                                            uint32_t state,
0098                                                            int32_t x,
0099                                                            int32_t y,
0100                                                            int32_t width,
0101                                                            int32_t height)
0102 {
0103     Q_UNUSED(x)
0104     Q_UNUSED(y)
0105     Q_UNUSED(width)
0106     Q_UNUSED(height)
0107     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0108     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0109     // TODO: add rect
0110     if (t->inputPanelVisible != state) {
0111         t->inputPanelVisible = state;
0112         Q_EMIT t->q->inputPanelStateChanged();
0113     }
0114 }
0115 
0116 void TextInputUnstableV2::Private::preeditStringCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *text, const char *commit)
0117 {
0118     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0119     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0120     t->pendingPreEdit.commitText = QByteArray(commit);
0121     t->pendingPreEdit.text = QByteArray(text);
0122     if (!t->pendingPreEdit.cursorSet) {
0123         t->pendingPreEdit.cursor = t->pendingPreEdit.text.length();
0124     }
0125     t->currentPreEdit = t->pendingPreEdit;
0126     t->pendingPreEdit = TextInput::Private::PreEdit();
0127     Q_EMIT t->q->composingTextChanged();
0128 }
0129 
0130 void TextInputUnstableV2::Private::preeditStylingCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t index, uint32_t length, uint32_t style)
0131 {
0132     Q_UNUSED(index)
0133     Q_UNUSED(length)
0134     Q_UNUSED(style)
0135     // TODO: implement
0136     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0137     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0138 }
0139 
0140 void TextInputUnstableV2::Private::preeditCursorCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index)
0141 {
0142     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0143     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0144     t->pendingPreEdit.cursor = index;
0145     t->pendingPreEdit.cursorSet = true;
0146 }
0147 
0148 void TextInputUnstableV2::Private::commitStringCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *text)
0149 {
0150     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0151     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0152     t->pendingCommit.text = QByteArray(text);
0153     t->currentCommit = t->pendingCommit;
0154     // TODO: what are the proper values it should be set to?
0155     t->pendingCommit = TextInput::Private::Commit();
0156     t->pendingCommit.deleteSurrounding.beforeLength = 0;
0157     t->pendingCommit.deleteSurrounding.afterLength = 0;
0158     Q_EMIT t->q->committed();
0159 }
0160 
0161 void TextInputUnstableV2::Private::cursorPositionCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index, int32_t anchor)
0162 {
0163     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0164     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0165     t->pendingCommit.cursor = index;
0166     t->pendingCommit.anchor = anchor;
0167 }
0168 
0169 void TextInputUnstableV2::Private::deleteSurroundingTextCallback(void *data,
0170                                                                  zwp_text_input_v2 *zwp_text_input_v2,
0171                                                                  uint32_t before_length,
0172                                                                  uint32_t after_length)
0173 {
0174     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0175     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0176     t->pendingCommit.deleteSurrounding.beforeLength = before_length;
0177     t->pendingCommit.deleteSurrounding.afterLength = after_length;
0178 }
0179 
0180 void TextInputUnstableV2::Private::modifiersMapCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, wl_array *map)
0181 {
0182     // TODO: implement
0183     Q_UNUSED(map)
0184     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0185     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0186 }
0187 
0188 void TextInputUnstableV2::Private::keysymCallback(void *data,
0189                                                   zwp_text_input_v2 *zwp_text_input_v2,
0190                                                   uint32_t time,
0191                                                   uint32_t sym,
0192                                                   uint32_t wlState,
0193                                                   uint32_t modifiers)
0194 {
0195     // TODO: add support for modifiers
0196     Q_UNUSED(modifiers)
0197     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0198     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0199     TextInput::KeyState state;
0200     switch (wlState) {
0201     case WL_KEYBOARD_KEY_STATE_RELEASED:
0202         state = TextInput::KeyState::Released;
0203         break;
0204     case WL_KEYBOARD_KEY_STATE_PRESSED:
0205         state = TextInput::KeyState::Pressed;
0206         break;
0207     default:
0208         // invalid
0209         return;
0210     }
0211     Q_EMIT t->q->keyEvent(sym, state, Qt::KeyboardModifiers(), time);
0212 }
0213 
0214 void TextInputUnstableV2::Private::languageCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *language)
0215 {
0216     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0217     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0218     if (qstrcmp(t->language, language) != 0) {
0219         t->language = QByteArray(language);
0220         Q_EMIT t->q->languageChanged();
0221     }
0222 }
0223 
0224 void TextInputUnstableV2::Private::textDirectionCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t wlDirection)
0225 {
0226     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0227     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0228     Qt::LayoutDirection direction;
0229     switch (wlDirection) {
0230     case ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_LTR:
0231         direction = Qt::LeftToRight;
0232         break;
0233     case ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_RTL:
0234         direction = Qt::RightToLeft;
0235         break;
0236     case ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_AUTO:
0237         direction = Qt::LayoutDirectionAuto;
0238         break;
0239     default:
0240         // invalid
0241         return;
0242     }
0243     if (direction != t->textDirection) {
0244         t->textDirection = direction;
0245         Q_EMIT t->q->textDirectionChanged();
0246     }
0247 }
0248 
0249 void TextInputUnstableV2::Private::configureSurroundingTextCallback(void *data,
0250                                                                     zwp_text_input_v2 *zwp_text_input_v2,
0251                                                                     int32_t before_cursor,
0252                                                                     int32_t after_cursor)
0253 {
0254     // TODO: implement
0255     Q_UNUSED(before_cursor)
0256     Q_UNUSED(after_cursor)
0257     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0258     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0259 }
0260 
0261 void TextInputUnstableV2::Private::inputMethodChangedCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, uint32_t flags)
0262 {
0263     Q_UNUSED(serial)
0264     Q_UNUSED(flags)
0265     // TODO: implement
0266     auto t = reinterpret_cast<TextInputUnstableV2::Private *>(data);
0267     Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2);
0268 }
0269 
0270 TextInputUnstableV2::Private::Private(TextInputUnstableV2 *q, Seat *seat)
0271     : TextInput::Private(seat)
0272     , q(q)
0273 {
0274 }
0275 
0276 void TextInputUnstableV2::Private::setup(zwp_text_input_v2 *ti)
0277 {
0278     Q_ASSERT(ti);
0279     Q_ASSERT(!textinputunstablev2);
0280     textinputunstablev2.setup(ti);
0281     zwp_text_input_v2_add_listener(ti, &s_listener, this);
0282 }
0283 
0284 bool TextInputUnstableV2::Private::isValid() const
0285 {
0286     return textinputunstablev2.isValid();
0287 }
0288 
0289 void TextInputUnstableV2::Private::enable(Surface *surface)
0290 {
0291     zwp_text_input_v2_enable(textinputunstablev2, *surface);
0292 }
0293 
0294 void TextInputUnstableV2::Private::disable(Surface *surface)
0295 {
0296     zwp_text_input_v2_disable(textinputunstablev2, *surface);
0297 }
0298 
0299 void TextInputUnstableV2::Private::showInputPanel()
0300 {
0301     zwp_text_input_v2_show_input_panel(textinputunstablev2);
0302 }
0303 
0304 void TextInputUnstableV2::Private::hideInputPanel()
0305 {
0306     zwp_text_input_v2_hide_input_panel(textinputunstablev2);
0307 }
0308 
0309 void TextInputUnstableV2::Private::setCursorRectangle(const QRect &rect)
0310 {
0311     zwp_text_input_v2_set_cursor_rectangle(textinputunstablev2, rect.x(), rect.y(), rect.width(), rect.height());
0312 }
0313 
0314 void TextInputUnstableV2::Private::setPreferredLanguage(const QString &lang)
0315 {
0316     zwp_text_input_v2_set_preferred_language(textinputunstablev2, lang.toUtf8().constData());
0317 }
0318 
0319 void TextInputUnstableV2::Private::setSurroundingText(const QString &text, quint32 cursor, quint32 anchor)
0320 {
0321     const QStringView strView(text);
0322 
0323     zwp_text_input_v2_set_surrounding_text(textinputunstablev2,
0324                                            text.toUtf8().constData(),
0325                                            strView.left(cursor).toUtf8().length(),
0326                                            strView.left(anchor).toUtf8().length());
0327 }
0328 
0329 void TextInputUnstableV2::Private::reset()
0330 {
0331     zwp_text_input_v2_update_state(textinputunstablev2, latestSerial, ZWP_TEXT_INPUT_V2_UPDATE_STATE_RESET);
0332 }
0333 
0334 void TextInputUnstableV2::Private::setContentType(ContentHints hints, ContentPurpose purpose)
0335 {
0336     uint32_t wlHints = 0;
0337     uint32_t wlPurpose = 0;
0338     if (hints.testFlag(ContentHint::AutoCompletion)) {
0339         wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_COMPLETION;
0340     }
0341     if (hints.testFlag(ContentHint::AutoCorrection)) {
0342         wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_CORRECTION;
0343     }
0344     if (hints.testFlag(ContentHint::AutoCapitalization)) {
0345         wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_CAPITALIZATION;
0346     }
0347     if (hints.testFlag(ContentHint::LowerCase)) {
0348         wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_LOWERCASE;
0349     }
0350     if (hints.testFlag(ContentHint::UpperCase)) {
0351         wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_UPPERCASE;
0352     }
0353     if (hints.testFlag(ContentHint::TitleCase)) {
0354         wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_TITLECASE;
0355     }
0356     if (hints.testFlag(ContentHint::HiddenText)) {
0357         wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_HIDDEN_TEXT;
0358     }
0359     if (hints.testFlag(ContentHint::SensitiveData)) {
0360         wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_SENSITIVE_DATA;
0361     }
0362     if (hints.testFlag(ContentHint::Latin)) {
0363         wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_LATIN;
0364     }
0365     if (hints.testFlag(ContentHint::MultiLine)) {
0366         wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_MULTILINE;
0367     }
0368     switch (purpose) {
0369     case ContentPurpose::Normal:
0370         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NORMAL;
0371         break;
0372     case ContentPurpose::Alpha:
0373         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_ALPHA;
0374         break;
0375     case ContentPurpose::Digits:
0376         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DIGITS;
0377         break;
0378     case ContentPurpose::Number:
0379         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NUMBER;
0380         break;
0381     case ContentPurpose::Phone:
0382         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_PHONE;
0383         break;
0384     case ContentPurpose::Url:
0385         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_URL;
0386         break;
0387     case ContentPurpose::Email:
0388         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_EMAIL;
0389         break;
0390     case ContentPurpose::Name:
0391         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NAME;
0392         break;
0393     case ContentPurpose::Password:
0394         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_PASSWORD;
0395         break;
0396     case ContentPurpose::Date:
0397         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DATE;
0398         break;
0399     case ContentPurpose::Time:
0400         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_TIME;
0401         break;
0402     case ContentPurpose::DateTime:
0403         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DATETIME;
0404         break;
0405     case ContentPurpose::Terminal:
0406         wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_TERMINAL;
0407         break;
0408     }
0409     zwp_text_input_v2_set_content_type(textinputunstablev2, wlHints, wlPurpose);
0410 }
0411 
0412 TextInputUnstableV2::TextInputUnstableV2(Seat *seat, QObject *parent)
0413     : TextInput(new Private(this, seat), parent)
0414 {
0415 }
0416 
0417 TextInputUnstableV2::~TextInputUnstableV2()
0418 {
0419     release();
0420 }
0421 
0422 TextInputUnstableV2::Private *TextInputUnstableV2::d_func() const
0423 {
0424     return reinterpret_cast<Private *>(d.data());
0425 }
0426 
0427 void TextInputUnstableV2::setup(zwp_text_input_v2 *textinputunstablev2)
0428 {
0429     Q_D();
0430     d->setup(textinputunstablev2);
0431 }
0432 
0433 void TextInputUnstableV2::release()
0434 {
0435     Q_D();
0436     d->textinputunstablev2.release();
0437 }
0438 
0439 void TextInputUnstableV2::destroy()
0440 {
0441     Q_D();
0442     d->textinputunstablev2.destroy();
0443 }
0444 
0445 TextInputUnstableV2::operator zwp_text_input_v2 *()
0446 {
0447     Q_D();
0448     return d->textinputunstablev2;
0449 }
0450 
0451 TextInputUnstableV2::operator zwp_text_input_v2 *() const
0452 {
0453     Q_D();
0454     return d->textinputunstablev2;
0455 }
0456 
0457 class TextInputManagerUnstableV2::Private : public TextInputManager::Private
0458 {
0459 public:
0460     Private() = default;
0461 
0462     void release() override;
0463     void destroy() override;
0464     bool isValid() override;
0465     void setupV2(zwp_text_input_manager_v2 *ti) override;
0466     TextInput *createTextInput(Seat *seat, QObject *parent = nullptr) override;
0467     using TextInputManager::Private::operator wl_text_input_manager *;
0468     operator zwp_text_input_manager_v2 *() override
0469     {
0470         return textinputmanagerunstablev2;
0471     }
0472     operator zwp_text_input_manager_v2 *() const override
0473     {
0474         return textinputmanagerunstablev2;
0475     }
0476 
0477     WaylandPointer<zwp_text_input_manager_v2, zwp_text_input_manager_v2_destroy> textinputmanagerunstablev2;
0478 };
0479 
0480 void TextInputManagerUnstableV2::Private::release()
0481 {
0482     textinputmanagerunstablev2.release();
0483 }
0484 
0485 void TextInputManagerUnstableV2::Private::destroy()
0486 {
0487     textinputmanagerunstablev2.destroy();
0488 }
0489 
0490 bool TextInputManagerUnstableV2::Private::isValid()
0491 {
0492     return textinputmanagerunstablev2.isValid();
0493 }
0494 
0495 TextInputManagerUnstableV2::TextInputManagerUnstableV2(QObject *parent)
0496     : TextInputManager(new Private, parent)
0497 {
0498 }
0499 
0500 TextInputManagerUnstableV2::~TextInputManagerUnstableV2() = default;
0501 
0502 void TextInputManagerUnstableV2::Private::setupV2(zwp_text_input_manager_v2 *ti)
0503 {
0504     Q_ASSERT(ti);
0505     Q_ASSERT(!textinputmanagerunstablev2);
0506     textinputmanagerunstablev2.setup(ti);
0507 }
0508 
0509 TextInput *TextInputManagerUnstableV2::Private::createTextInput(Seat *seat, QObject *parent)
0510 {
0511     Q_ASSERT(isValid());
0512     TextInputUnstableV2 *t = new TextInputUnstableV2(seat, parent);
0513     auto w = zwp_text_input_manager_v2_get_text_input(textinputmanagerunstablev2, *seat);
0514     if (queue) {
0515         queue->addProxy(w);
0516     }
0517     t->setup(w);
0518     return t;
0519 }
0520 
0521 }
0522 }