diff options
author | Liang Qi <liang.qi@qt.io> | 2021-09-08 15:45:50 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2021-10-07 12:13:01 +0200 |
commit | 99a6eb7b79471114705d7c68b0d5b388ea16ac03 (patch) | |
tree | 483af2a9ca42b298c7846081f9b94f0f854fa56f /src/compositor | |
parent | a572df8ac61d6009a1863ac7216e6abdd24df3cd (diff) |
Support different text input protocols
from clients and one compositor at same time.
For compositor side, just need to have TextInputManager and
QtTextInputMethodManager together.
For client side, set QT_WAYLAND_TEXT_INPUT_PROTOCOL env to choose:
* If the env is unset(empty) or invalid, it will search
qt_text_input_method_v1 and zwp_text_input_v2 in order
* Set as "qt_text_input_method_v1" or "zwp_text_input_v2" if compositor
supports
* Set as "zwp_text_input_v2;qt_text_input_method_v1"
Change-Id: Ieec293ff412bf2d3e5ca9c69a951bfe1899cc808
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'src/compositor')
7 files changed, 58 insertions, 13 deletions
diff --git a/src/compositor/compositor_api/qwaylandclient.cpp b/src/compositor/compositor_api/qwaylandclient.cpp index 9ca61d608..466dd7157 100644 --- a/src/compositor/compositor_api/qwaylandclient.cpp +++ b/src/compositor/compositor_api/qwaylandclient.cpp @@ -103,6 +103,7 @@ public: */ QWaylandClient::QWaylandClient(QWaylandCompositor *compositor, wl_client *client) : QObject(*new QWaylandClientPrivate(compositor, client)) + , mTextInputProtocols(TextInputProtocol::NoProtocol) { Q_D(QWaylandClient); @@ -273,6 +274,17 @@ void QWaylandClient::close() d->compositor->destroyClient(this); } +QWaylandClient::TextInputProtocols QWaylandClient::textInputProtocols() const +{ + return mTextInputProtocols; +} + +void QWaylandClient::setTextInputProtocols(TextInputProtocols p) +{ + if (mTextInputProtocols != p) + mTextInputProtocols = p; +} + QT_END_NAMESPACE #include "moc_qwaylandclient.cpp" diff --git a/src/compositor/compositor_api/qwaylandclient.h b/src/compositor/compositor_api/qwaylandclient.h index 3d215aa74..667d7f644 100644 --- a/src/compositor/compositor_api/qwaylandclient.h +++ b/src/compositor/compositor_api/qwaylandclient.h @@ -61,6 +61,19 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandClient : public QObject public: ~QWaylandClient() override; + enum TextInputProtocol { + NoProtocol = 0, + QtTextInputMethodV1 = 1, + TextInputV2 = 2, + + QtTextInputMethod = QtTextInputMethodV1, + TextInput = TextInputV2 + }; + Q_DECLARE_FLAGS(TextInputProtocols, TextInputProtocol) + + TextInputProtocols textInputProtocols() const; + void setTextInputProtocols(TextInputProtocols p); + static QWaylandClient *fromWlClient(QWaylandCompositor *compositor, wl_client *wlClient); QWaylandCompositor *compositor() const; @@ -79,6 +92,8 @@ public Q_SLOTS: private: explicit QWaylandClient(QWaylandCompositor *compositor, wl_client *client); + + TextInputProtocols mTextInputProtocols; }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp b/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp index 31d6757b5..9c52f6469 100644 --- a/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp +++ b/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp @@ -79,9 +79,10 @@ void QWaylandInputMethodControl::inputMethodEvent(QInputMethodEvent *event) Q_D(QWaylandInputMethodControl); QWaylandTextInput *textInput = d->textInput(); + QWaylandQtTextInputMethod *textInputMethod = d->textInputMethod(); if (textInput) { textInput->sendInputMethodEvent(event); - } else if (QWaylandQtTextInputMethod *textInputMethod = d->textInputMethod()) { + } else if (textInputMethod) { textInputMethod->sendInputMethodEvent(event); } else { event->ignore(); @@ -172,11 +173,15 @@ QWaylandInputMethodControlPrivate::QWaylandInputMethodControlPrivate(QWaylandSur QWaylandQtTextInputMethod *QWaylandInputMethodControlPrivate::textInputMethod() const { + if (!surface->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) + return nullptr; return QWaylandQtTextInputMethod::findIn(seat); } QWaylandTextInput *QWaylandInputMethodControlPrivate::textInput() const { + if (!surface->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) + return nullptr; return QWaylandTextInput::findIn(seat); } diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index d8e61fba3..d1b14ceb5 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -1120,13 +1120,16 @@ void QWaylandQuickItem::takeFocus(QWaylandSeat *device) } target->setKeyboardFocus(surface()); - { + qCDebug(qLcWaylandCompositorInputMethods) << Q_FUNC_INFO << " surface:" << surface() + << ", client:" << surface()->client() + << ", textinputprotocol:" << (int)(surface()->client()->textInputProtocols()); + if (surface()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) { QWaylandTextInput *textInput = QWaylandTextInput::findIn(target); if (textInput) textInput->setFocus(surface()); } - { + if (surface()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) { QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(target); if (textInputMethod) textInputMethod->setFocus(surface()); diff --git a/src/compositor/compositor_api/qwaylandseat.cpp b/src/compositor/compositor_api/qwaylandseat.cpp index ad664ccf9..9f607c5d9 100644 --- a/src/compositor/compositor_api/qwaylandseat.cpp +++ b/src/compositor/compositor_api/qwaylandseat.cpp @@ -469,16 +469,20 @@ void QWaylandSeat::sendFullKeyEvent(QKeyEvent *event) #if QT_CONFIG(im) if (keyboardFocus()->inputMethodControl()->enabled() && event->nativeScanCode() == 0) { - QWaylandTextInput *textInput = QWaylandTextInput::findIn(this); - if (textInput) { - textInput->sendKeyEvent(event); - return; + if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) { + QWaylandTextInput *textInput = QWaylandTextInput::findIn(this); + if (textInput) { + textInput->sendKeyEvent(event); + return; + } } - QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(this); - if (textInputMethod) { - textInputMethod->sendKeyEvent(event); - return; + if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) { + QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(this); + if (textInputMethod) { + textInputMethod->sendKeyEvent(event); + return; + } } } #endif diff --git a/src/compositor/extensions/qwaylandqttextinputmethodmanager.cpp b/src/compositor/extensions/qwaylandqttextinputmethodmanager.cpp index 8b41d5920..f90eb658b 100644 --- a/src/compositor/extensions/qwaylandqttextinputmethodmanager.cpp +++ b/src/compositor/extensions/qwaylandqttextinputmethodmanager.cpp @@ -50,6 +50,10 @@ void QWaylandQtTextInputMethodManagerPrivate::text_input_method_manager_v1_get_t if (textInput == nullptr) textInput = new QWaylandQtTextInputMethod(seat, compositor); textInput->add(resource->client(), id, wl_resource_get_version(resource->handle)); + QWaylandClient *client = QWaylandClient::fromWlClient(compositor, resource->client()); + QWaylandClient::TextInputProtocols p = client->textInputProtocols(); + client->setTextInputProtocols(p.setFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)); + if (!textInput->isInitialized()) textInput->initialize(); } diff --git a/src/compositor/extensions/qwaylandtextinputmanager.cpp b/src/compositor/extensions/qwaylandtextinputmanager.cpp index ae95b9659..15d68c977 100644 --- a/src/compositor/extensions/qwaylandtextinputmanager.cpp +++ b/src/compositor/extensions/qwaylandtextinputmanager.cpp @@ -47,10 +47,12 @@ void QWaylandTextInputManagerPrivate::zwp_text_input_manager_v2_get_text_input(R QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer()); QWaylandSeat *seat = QWaylandSeat::fromSeatResource(seatResource); QWaylandTextInput *textInput = QWaylandTextInput::findIn(seat); - if (!textInput) { + if (!textInput) textInput = new QWaylandTextInput(seat, compositor); - } textInput->add(resource->client(), id, wl_resource_get_version(resource->handle)); + QWaylandClient *client = QWaylandClient::fromWlClient(compositor, resource->client()); + QWaylandClient::TextInputProtocols p = client->textInputProtocols(); + client->setTextInputProtocols(p.setFlag(QWaylandClient::TextInputProtocol::TextInputV2)); if (!textInput->isInitialized()) textInput->initialize(); } |