diff --git a/src/client/textinput_v0.cpp b/src/client/textinput_v0.cpp index e294c1b..1b52ed3 100644 --- a/src/client/textinput_v0.cpp +++ b/src/client/textinput_v0.cpp @@ -1,500 +1,501 @@ /**************************************************************************** Copyright 2016 Martin Gräßlin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . ****************************************************************************/ #include "textinput_p.h" #include "event_queue.h" #include "seat.h" #include "surface.h" #include "wayland_pointer_p.h" #include namespace KWayland { namespace Client { class TextInputUnstableV0::Private : public TextInput::Private { public: Private(TextInputUnstableV0 *q, Seat *seat); void setup(wl_text_input *textinputmanagerunstablev0); bool isValid() const override; void enable(Surface *surface) override; void disable(Surface * surface) override; void showInputPanel() override; void hideInputPanel() override; void setCursorRectangle(const QRect &rect) override; void setPreferredLanguage(const QString &lang) override; void setSurroundingText(const QString &text, quint32 cursor, quint32 anchor) override; void reset() override; void setContentType(ContentHints hint, ContentPurpose purpose) override; WaylandPointer textinputunstablev0; private: static void enterCallaback(void *data, wl_text_input *wl_text_input, wl_surface *surface); static void leaveCallback(void *data, wl_text_input *wl_text_input); static void modifiersMapCallback(void *data, wl_text_input *wl_text_input, wl_array *map); static void inputPanelStateCallback(void *data, wl_text_input *wl_text_input, uint32_t state); static void preeditStringCallback(void *data, wl_text_input *wl_text_input, uint32_t serial, const char *text, const char *commit); static void preeditStylingCallback(void *data, wl_text_input *wl_text_input, uint32_t index, uint32_t length, uint32_t style); static void preeditCursorCallback(void *data, wl_text_input *wl_text_input, int32_t index); static void commitStringCallback(void *data, wl_text_input *wl_text_input, uint32_t serial, const char *text); static void cursorPositionCallback(void *data, wl_text_input *wl_text_input, int32_t index, int32_t anchor); static void deleteSurroundingTextCallback(void *data, wl_text_input *wl_text_input, int32_t index, uint32_t length); 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); static void languageCallback(void *data, wl_text_input *wl_text_input, uint32_t serial, const char *language); static void textDirectionCallback(void *data, wl_text_input *wl_text_input, uint32_t serial, uint32_t direction); TextInputUnstableV0 *q; static const wl_text_input_listener s_listener; }; const wl_text_input_listener TextInputUnstableV0::Private::s_listener = { enterCallaback, leaveCallback, modifiersMapCallback, inputPanelStateCallback, preeditStringCallback, preeditStylingCallback, preeditCursorCallback, commitStringCallback, cursorPositionCallback, deleteSurroundingTextCallback, keysymCallback, languageCallback, textDirectionCallback }; void TextInputUnstableV0::Private::enterCallaback(void *data, wl_text_input *wl_text_input, wl_surface *surface) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); t->enteredSurface = Surface::get(surface); emit t->q->entered(); } void TextInputUnstableV0::Private::leaveCallback(void *data, wl_text_input *wl_text_input) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); t->enteredSurface = nullptr; emit t->q->left(); } void TextInputUnstableV0::Private::modifiersMapCallback(void *data, wl_text_input *wl_text_input, wl_array *map) { Q_UNUSED(map) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); // TODO: implement } void TextInputUnstableV0::Private::inputPanelStateCallback(void *data, wl_text_input *wl_text_input, uint32_t state) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); if (t->inputPanelVisible != state) { t->inputPanelVisible = state; emit t->q->inputPanelStateChanged(); } } void TextInputUnstableV0::Private::preeditStringCallback(void *data, wl_text_input *wl_text_input, uint32_t serial, const char *text, const char *commit) { Q_UNUSED(serial) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); t->pendingPreEdit.commitText = QByteArray(commit); t->pendingPreEdit.text = QByteArray(text); if (!t->pendingPreEdit.cursorSet) { t->pendingPreEdit.cursor = t->pendingPreEdit.text.length(); } t->currentPreEdit = t->pendingPreEdit; t->pendingPreEdit = TextInput::Private::PreEdit(); emit t->q->composingTextChanged(); } void TextInputUnstableV0::Private::preeditStylingCallback(void *data, wl_text_input *wl_text_input, uint32_t index, uint32_t length, uint32_t style) { Q_UNUSED(index) Q_UNUSED(length) Q_UNUSED(style) // TODO: implement auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); } void TextInputUnstableV0::Private::preeditCursorCallback(void *data, wl_text_input *wl_text_input, int32_t index) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); t->pendingPreEdit.cursor = index; t->pendingPreEdit.cursorSet = true; } void TextInputUnstableV0::Private::commitStringCallback(void *data, wl_text_input *wl_text_input, uint32_t serial, const char *text) { Q_UNUSED(serial) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); t->pendingCommit.text = QByteArray(text); t->currentCommit = t->pendingCommit; // TODO: what are the proper values it should be set to? t->pendingCommit = TextInput::Private::Commit(); t->pendingCommit.deleteSurrounding.beforeLength = 0; t->pendingCommit.deleteSurrounding.afterLength = 0; emit t->q->committed(); } void TextInputUnstableV0::Private::cursorPositionCallback(void *data, wl_text_input *wl_text_input, int32_t index, int32_t anchor) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); t->pendingCommit.cursor = index; t->pendingCommit.anchor = anchor; } void TextInputUnstableV0::Private::deleteSurroundingTextCallback(void *data, wl_text_input *wl_text_input, int32_t index, uint32_t length) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); t->pendingCommit.deleteSurrounding.beforeLength = qAbs(index); t->pendingCommit.deleteSurrounding.afterLength = length - t->pendingCommit.deleteSurrounding.beforeLength; } void TextInputUnstableV0::Private::keysymCallback(void *data, wl_text_input *wl_text_input, uint32_t serial, uint32_t time, uint32_t sym, uint32_t wlState, uint32_t modifiers) { Q_UNUSED(serial) // TODO: add support for modifiers Q_UNUSED(modifiers) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); TextInput::KeyState state; switch (wlState) { case WL_KEYBOARD_KEY_STATE_RELEASED: state = TextInput::KeyState::Released; break; case WL_KEYBOARD_KEY_STATE_PRESSED: state = TextInput::KeyState::Pressed; break; default: // invalid return; } emit t->q->keyEvent(sym, state, Qt::KeyboardModifiers(), time); } void TextInputUnstableV0::Private::languageCallback(void *data, wl_text_input *wl_text_input, uint32_t serial, const char *language) { Q_UNUSED(serial) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); if (qstrcmp(t->language, language) != 0) { t->language = QByteArray(language); emit t->q->languageChanged(); } } void TextInputUnstableV0::Private::textDirectionCallback(void *data, wl_text_input *wl_text_input, uint32_t serial, uint32_t wlDirection) { Q_UNUSED(serial) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev0 == wl_text_input); Qt::LayoutDirection direction; switch (wlDirection) { case WL_TEXT_INPUT_TEXT_DIRECTION_LTR: direction = Qt::LeftToRight; break; case WL_TEXT_INPUT_TEXT_DIRECTION_RTL: direction = Qt::RightToLeft; break; case WL_TEXT_INPUT_TEXT_DIRECTION_AUTO: direction = Qt::LayoutDirectionAuto; break; default: // invalid return; } if (direction != t->textDirection) { t->textDirection = direction; emit t->q->textDirectionChanged(); } } TextInputUnstableV0::Private::Private(TextInputUnstableV0 *q, Seat *seat) : TextInput::Private(seat) , q(q) { } void TextInputUnstableV0::Private::setup(wl_text_input *ti) { Q_ASSERT(ti); Q_ASSERT(!textinputunstablev0); textinputunstablev0.setup(ti); wl_text_input_add_listener(ti, &s_listener, this); } bool TextInputUnstableV0::Private::isValid() const { return textinputunstablev0.isValid(); } void TextInputUnstableV0::Private::enable(Surface *surface) { wl_text_input_activate(textinputunstablev0, *seat, *surface); } void TextInputUnstableV0::Private::disable(Surface *surface) { Q_UNUSED(surface) wl_text_input_deactivate(textinputunstablev0, *seat); } void TextInputUnstableV0::Private::showInputPanel() { wl_text_input_show_input_panel(textinputunstablev0); } void TextInputUnstableV0::Private::hideInputPanel() { wl_text_input_hide_input_panel(textinputunstablev0); } void TextInputUnstableV0::Private::setCursorRectangle(const QRect &rect) { wl_text_input_set_cursor_rectangle(textinputunstablev0, rect.x(), rect.y(), rect.width(), rect.height()); } void TextInputUnstableV0::Private::setPreferredLanguage(const QString &lang) { wl_text_input_set_preferred_language(textinputunstablev0, lang.toUtf8().constData()); } void TextInputUnstableV0::Private::setSurroundingText(const QString &text, quint32 cursor, quint32 anchor) { wl_text_input_set_surrounding_text(textinputunstablev0, text.toUtf8().constData(), text.leftRef(cursor).toUtf8().length(), text.leftRef(anchor).toUtf8().length()); } void TextInputUnstableV0::Private::reset() { wl_text_input_reset(textinputunstablev0); } void TextInputUnstableV0::Private::setContentType(ContentHints hints, ContentPurpose purpose) { uint32_t wlHints = 0; uint32_t wlPurpose = 0; if (hints.testFlag(ContentHint::AutoCompletion)) { wlHints |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION; } if (hints.testFlag(ContentHint::AutoCorrection)) { wlHints |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_CORRECTION; } if (hints.testFlag(ContentHint::AutoCapitalization)) { wlHints |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION; } if (hints.testFlag(ContentHint::LowerCase)) { wlHints |= WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE; } if (hints.testFlag(ContentHint::UpperCase)) { wlHints |= WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE; } if (hints.testFlag(ContentHint::TitleCase)) { wlHints |= WL_TEXT_INPUT_CONTENT_HINT_TITLECASE; } if (hints.testFlag(ContentHint::HiddenText)) { wlHints |= WL_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT; } if (hints.testFlag(ContentHint::SensitiveData)) { wlHints |= WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA; } if (hints.testFlag(ContentHint::Latin)) { wlHints |= WL_TEXT_INPUT_CONTENT_HINT_LATIN; } if (hints.testFlag(ContentHint::MultiLine)) { wlHints |= WL_TEXT_INPUT_CONTENT_HINT_MULTILINE; } switch (purpose) { case ContentPurpose::Normal: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL; break; case ContentPurpose::Alpha: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_ALPHA; break; case ContentPurpose::Digits: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS; break; case ContentPurpose::Number: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER; break; case ContentPurpose::Phone: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE; break; case ContentPurpose::Url: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_URL; break; case ContentPurpose::Email: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL; break; case ContentPurpose::Name: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NAME; break; case ContentPurpose::Password: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD; break; case ContentPurpose::Date: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DATE; break; case ContentPurpose::Time: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_TIME; break; case ContentPurpose::DateTime: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME; break; case ContentPurpose::Terminal: wlPurpose = WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL; break; } wl_text_input_set_content_type(textinputunstablev0, wlHints, wlPurpose); } TextInputUnstableV0::TextInputUnstableV0(Seat *seat, QObject *parent) : TextInput(new Private(this, seat), parent) { } TextInputUnstableV0::~TextInputUnstableV0() { release(); } TextInputUnstableV0::Private *TextInputUnstableV0::d_func() const { return reinterpret_cast(d.data()); } void TextInputUnstableV0::setup(wl_text_input *textinputunstablev0) { Q_D(); d->setup(textinputunstablev0); } void TextInputUnstableV0::release() { Q_D(); d->textinputunstablev0.release(); } void TextInputUnstableV0::destroy() { Q_D(); d->textinputunstablev0.destroy(); } TextInputUnstableV0::operator wl_text_input*() { Q_D(); return d->textinputunstablev0; } TextInputUnstableV0::operator wl_text_input*() const { Q_D(); return d->textinputunstablev0; } class TextInputManagerUnstableV0::Private : public TextInputManager::Private { public: Private() = default; void release() override; void destroy() override; bool isValid() override; void setupV0(wl_text_input_manager *ti) override; TextInput *createTextInput(Seat *seat, QObject *parent = nullptr) override; + using TextInputManager::Private::operator zwp_text_input_manager_v2*; //overriding only one overload results in a compiler warning. This tells GCC we're doing it deliberately operator wl_text_input_manager*() override { return textinputmanagerunstablev0; } operator wl_text_input_manager*() const override { return textinputmanagerunstablev0; } WaylandPointer textinputmanagerunstablev0; }; void TextInputManagerUnstableV0::Private::release() { textinputmanagerunstablev0.release(); } void TextInputManagerUnstableV0::Private::destroy() { textinputmanagerunstablev0.destroy(); } bool TextInputManagerUnstableV0::Private::isValid() { return textinputmanagerunstablev0.isValid(); } TextInputManagerUnstableV0::TextInputManagerUnstableV0(QObject *parent) : TextInputManager(new Private, parent) { } TextInputManagerUnstableV0::Private *TextInputManagerUnstableV0::d_func() const { return reinterpret_cast(d.data()); } TextInputManagerUnstableV0::~TextInputManagerUnstableV0() { release(); } void TextInputManagerUnstableV0::Private::setupV0(wl_text_input_manager *ti) { Q_ASSERT(ti); Q_ASSERT(!textinputmanagerunstablev0); textinputmanagerunstablev0.setup(ti); } TextInput *TextInputManagerUnstableV0::Private::createTextInput(Seat *seat, QObject *parent) { Q_ASSERT(isValid()); TextInputUnstableV0 *t = new TextInputUnstableV0(seat, parent); auto w = wl_text_input_manager_create_text_input(textinputmanagerunstablev0); if (queue) { queue->addProxy(w); } t->setup(w); return t; } } } diff --git a/src/client/textinput_v2.cpp b/src/client/textinput_v2.cpp index 1a2a478..32219aa 100644 --- a/src/client/textinput_v2.cpp +++ b/src/client/textinput_v2.cpp @@ -1,516 +1,517 @@ /**************************************************************************** Copyright 2016 Martin Gräßlin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . ****************************************************************************/ #include "textinput_p.h" #include "event_queue.h" #include "seat.h" #include "surface.h" #include "wayland_pointer_p.h" #include namespace KWayland { namespace Client { class TextInputUnstableV2::Private : public TextInput::Private { public: Private(TextInputUnstableV2 *q, Seat *seat); void setup(zwp_text_input_v2 *textinputmanagerunstablev0); bool isValid() const override; void enable(Surface *surface) override; void disable(Surface * surface) override; void showInputPanel() override; void hideInputPanel() override; void setCursorRectangle(const QRect &rect) override; void setPreferredLanguage(const QString &lang) override; void setSurroundingText(const QString &text, quint32 cursor, quint32 anchor) override; void reset() override; void setContentType(ContentHints hint, ContentPurpose purpose) override; WaylandPointer textinputunstablev2; private: static void enterCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface); static void leaveCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface); 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); static void preeditStringCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *text, const char *commit); static void preeditStylingCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t index, uint32_t length, uint32_t style); static void preeditCursorCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index); static void commitStringCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *text); static void cursorPositionCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index, int32_t anchor); static void deleteSurroundingTextCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t before_length, uint32_t after_length); static void modifiersMapCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, wl_array *map); 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); static void languageCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *language); static void textDirectionCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t direction); static void configureSurroundingTextCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t before_cursor, int32_t after_cursor); static void inputMethodChangedCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, uint32_t flags); TextInputUnstableV2 *q; static const zwp_text_input_v2_listener s_listener; }; const zwp_text_input_v2_listener TextInputUnstableV2::Private::s_listener = { enterCallback, leaveCallback, inputPanelStateCallback, preeditStringCallback, preeditStylingCallback, preeditCursorCallback, commitStringCallback, cursorPositionCallback, deleteSurroundingTextCallback, modifiersMapCallback, keysymCallback, languageCallback, textDirectionCallback, configureSurroundingTextCallback, inputMethodChangedCallback }; void TextInputUnstableV2::Private::enterCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); t->latestSerial = serial; t->enteredSurface = Surface::get(surface); emit t->q->entered(); } void TextInputUnstableV2::Private::leaveCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, wl_surface *surface) { Q_UNUSED(surface) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); t->enteredSurface = nullptr; t->latestSerial = serial; emit t->q->left(); } void TextInputUnstableV2::Private::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) { Q_UNUSED(x) Q_UNUSED(y) Q_UNUSED(width) Q_UNUSED(height) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); // TODO: add rect if (t->inputPanelVisible != state) { t->inputPanelVisible = state; emit t->q->inputPanelStateChanged(); } } void TextInputUnstableV2::Private::preeditStringCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *text, const char *commit) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); t->pendingPreEdit.commitText = QByteArray(commit); t->pendingPreEdit.text = QByteArray(text); if (!t->pendingPreEdit.cursorSet) { t->pendingPreEdit.cursor = t->pendingPreEdit.text.length(); } t->currentPreEdit = t->pendingPreEdit; t->pendingPreEdit = TextInput::Private::PreEdit(); emit t->q->composingTextChanged(); } void TextInputUnstableV2::Private::preeditStylingCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t index, uint32_t length, uint32_t style) { Q_UNUSED(index) Q_UNUSED(length) Q_UNUSED(style) // TODO: implement auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); } void TextInputUnstableV2::Private::preeditCursorCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); t->pendingPreEdit.cursor = index; t->pendingPreEdit.cursorSet = true; } void TextInputUnstableV2::Private::commitStringCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *text) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); t->pendingCommit.text = QByteArray(text); t->currentCommit = t->pendingCommit; // TODO: what are the proper values it should be set to? t->pendingCommit = TextInput::Private::Commit(); t->pendingCommit.deleteSurrounding.beforeLength = 0; t->pendingCommit.deleteSurrounding.afterLength = 0; emit t->q->committed(); } void TextInputUnstableV2::Private::cursorPositionCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t index, int32_t anchor) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); t->pendingCommit.cursor = index; t->pendingCommit.anchor = anchor; } void TextInputUnstableV2::Private::deleteSurroundingTextCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t before_length, uint32_t after_length) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); t->pendingCommit.deleteSurrounding.beforeLength = before_length; t->pendingCommit.deleteSurrounding.afterLength = after_length; } void TextInputUnstableV2::Private::modifiersMapCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, wl_array *map) { // TODO: implement Q_UNUSED(map) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); } void TextInputUnstableV2::Private::keysymCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t time, uint32_t sym, uint32_t wlState, uint32_t modifiers) { // TODO: add support for modifiers Q_UNUSED(modifiers) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); TextInput::KeyState state; switch (wlState) { case WL_KEYBOARD_KEY_STATE_RELEASED: state = TextInput::KeyState::Released; break; case WL_KEYBOARD_KEY_STATE_PRESSED: state = TextInput::KeyState::Pressed; break; default: // invalid return; } emit t->q->keyEvent(sym, state, Qt::KeyboardModifiers(), time); } void TextInputUnstableV2::Private::languageCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, const char *language) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); if (qstrcmp(t->language, language) != 0) { t->language = QByteArray(language); emit t->q->languageChanged(); } } void TextInputUnstableV2::Private::textDirectionCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t wlDirection) { auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); Qt::LayoutDirection direction; switch (wlDirection) { case ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_LTR: direction = Qt::LeftToRight; break; case ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_RTL: direction = Qt::RightToLeft; break; case ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_AUTO: direction = Qt::LayoutDirectionAuto; break; default: // invalid return; } if (direction != t->textDirection) { t->textDirection = direction; emit t->q->textDirectionChanged(); } } void TextInputUnstableV2::Private::configureSurroundingTextCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, int32_t before_cursor, int32_t after_cursor) { // TODO: implement Q_UNUSED(before_cursor) Q_UNUSED(after_cursor) auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); } void TextInputUnstableV2::Private::inputMethodChangedCallback(void *data, zwp_text_input_v2 *zwp_text_input_v2, uint32_t serial, uint32_t flags) { Q_UNUSED(serial) Q_UNUSED(flags) // TODO: implement auto t = reinterpret_cast(data); Q_ASSERT(t->textinputunstablev2 == zwp_text_input_v2); } TextInputUnstableV2::Private::Private(TextInputUnstableV2 *q, Seat *seat) : TextInput::Private(seat) , q(q) { } void TextInputUnstableV2::Private::setup(zwp_text_input_v2 *ti) { Q_ASSERT(ti); Q_ASSERT(!textinputunstablev2); textinputunstablev2.setup(ti); zwp_text_input_v2_add_listener(ti, &s_listener, this); } bool TextInputUnstableV2::Private::isValid() const { return textinputunstablev2.isValid(); } void TextInputUnstableV2::Private::enable(Surface *surface) { zwp_text_input_v2_enable(textinputunstablev2, *surface); } void TextInputUnstableV2::Private::disable(Surface * surface) { zwp_text_input_v2_disable(textinputunstablev2, *surface); } void TextInputUnstableV2::Private::showInputPanel() { zwp_text_input_v2_show_input_panel(textinputunstablev2); } void TextInputUnstableV2::Private::hideInputPanel() { zwp_text_input_v2_hide_input_panel(textinputunstablev2); } void TextInputUnstableV2::Private::setCursorRectangle(const QRect &rect) { zwp_text_input_v2_set_cursor_rectangle(textinputunstablev2, rect.x(), rect.y(), rect.width(), rect.height()); } void TextInputUnstableV2::Private::setPreferredLanguage(const QString &lang) { zwp_text_input_v2_set_preferred_language(textinputunstablev2, lang.toUtf8().constData()); } void TextInputUnstableV2::Private::setSurroundingText(const QString &text, quint32 cursor, quint32 anchor) { zwp_text_input_v2_set_surrounding_text(textinputunstablev2, text.toUtf8().constData(), text.leftRef(cursor).toUtf8().length(), text.leftRef(anchor).toUtf8().length()); } void TextInputUnstableV2::Private::reset() { zwp_text_input_v2_update_state(textinputunstablev2, latestSerial, ZWP_TEXT_INPUT_V2_UPDATE_STATE_RESET); } void TextInputUnstableV2::Private::setContentType(ContentHints hints, ContentPurpose purpose) { uint32_t wlHints = 0; uint32_t wlPurpose = 0; if (hints.testFlag(ContentHint::AutoCompletion)) { wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_COMPLETION; } if (hints.testFlag(ContentHint::AutoCorrection)) { wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_CORRECTION; } if (hints.testFlag(ContentHint::AutoCapitalization)) { wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_CAPITALIZATION; } if (hints.testFlag(ContentHint::LowerCase)) { wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_LOWERCASE; } if (hints.testFlag(ContentHint::UpperCase)) { wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_UPPERCASE; } if (hints.testFlag(ContentHint::TitleCase)) { wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_TITLECASE; } if (hints.testFlag(ContentHint::HiddenText)) { wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_HIDDEN_TEXT; } if (hints.testFlag(ContentHint::SensitiveData)) { wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_SENSITIVE_DATA; } if (hints.testFlag(ContentHint::Latin)) { wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_LATIN; } if (hints.testFlag(ContentHint::MultiLine)) { wlHints |= ZWP_TEXT_INPUT_V2_CONTENT_HINT_MULTILINE; } switch (purpose) { case ContentPurpose::Normal: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NORMAL; break; case ContentPurpose::Alpha: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_ALPHA; break; case ContentPurpose::Digits: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DIGITS; break; case ContentPurpose::Number: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NUMBER; break; case ContentPurpose::Phone: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_PHONE; break; case ContentPurpose::Url: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_URL; break; case ContentPurpose::Email: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_EMAIL; break; case ContentPurpose::Name: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NAME; break; case ContentPurpose::Password: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_PASSWORD; break; case ContentPurpose::Date: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DATE; break; case ContentPurpose::Time: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_TIME; break; case ContentPurpose::DateTime: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DATETIME; break; case ContentPurpose::Terminal: wlPurpose = ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_TERMINAL; break; } zwp_text_input_v2_set_content_type(textinputunstablev2, wlHints, wlPurpose); } TextInputUnstableV2::TextInputUnstableV2(Seat *seat, QObject *parent) : TextInput(new Private(this, seat), parent) { } TextInputUnstableV2::~TextInputUnstableV2() { release(); } TextInputUnstableV2::Private *TextInputUnstableV2::d_func() const { return reinterpret_cast(d.data()); } void TextInputUnstableV2::setup(zwp_text_input_v2 *textinputunstablev2) { Q_D(); d->setup(textinputunstablev2); } void TextInputUnstableV2::release() { Q_D(); d->textinputunstablev2.release(); } void TextInputUnstableV2::destroy() { Q_D(); d->textinputunstablev2.destroy(); } TextInputUnstableV2::operator zwp_text_input_v2*() { Q_D(); return d->textinputunstablev2; } TextInputUnstableV2::operator zwp_text_input_v2*() const { Q_D(); return d->textinputunstablev2; } class TextInputManagerUnstableV2::Private : public TextInputManager::Private { public: Private() = default; void release() override; void destroy() override; bool isValid() override; void setupV2(zwp_text_input_manager_v2 *ti) override; TextInput *createTextInput(Seat *seat, QObject *parent = nullptr) override; + using TextInputManager::Private::operator wl_text_input_manager*; operator zwp_text_input_manager_v2*() override { return textinputmanagerunstablev2; } operator zwp_text_input_manager_v2*() const override { return textinputmanagerunstablev2; } WaylandPointer textinputmanagerunstablev2; }; void TextInputManagerUnstableV2::Private::release() { textinputmanagerunstablev2.release(); } void TextInputManagerUnstableV2::Private::destroy() { textinputmanagerunstablev2.destroy(); } bool TextInputManagerUnstableV2::Private::isValid() { return textinputmanagerunstablev2.isValid(); } TextInputManagerUnstableV2::TextInputManagerUnstableV2(QObject *parent) : TextInputManager(new Private, parent) { } TextInputManagerUnstableV2::~TextInputManagerUnstableV2() = default; void TextInputManagerUnstableV2::Private::setupV2(zwp_text_input_manager_v2 *ti) { Q_ASSERT(ti); Q_ASSERT(!textinputmanagerunstablev2); textinputmanagerunstablev2.setup(ti); } TextInput *TextInputManagerUnstableV2::Private::createTextInput(Seat *seat, QObject *parent) { Q_ASSERT(isValid()); TextInputUnstableV2 *t = new TextInputUnstableV2(seat, parent); auto w = zwp_text_input_manager_v2_get_text_input(textinputmanagerunstablev2, *seat); if (queue) { queue->addProxy(w); } t->setup(w); return t; } } }