1// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qwaylandinputmethodcontrol.h"
5#include "qwaylandinputmethodcontrol_p.h"
6
7#include "qwaylandcompositor.h"
8#include "qwaylandseat.h"
9#include "qwaylandsurface.h"
10#include "qwaylandview.h"
11#include "qwaylandtextinput.h"
12#include "qwaylandtextinputv3.h"
13#include "qwaylandqttextinputmethod.h"
14
15#include <QtGui/QInputMethodEvent>
16
17QWaylandInputMethodControl::QWaylandInputMethodControl(QWaylandSurface *surface)
18 : QObject(*new QWaylandInputMethodControlPrivate(surface), surface)
19{
20 connect(sender: d_func()->compositor, signal: &QWaylandCompositor::defaultSeatChanged,
21 context: this, slot: &QWaylandInputMethodControl::defaultSeatChanged);
22
23 updateTextInput();
24
25 QWaylandTextInputV3 *textInputV3 = d_func()->textInputV3();
26 if (textInputV3) {
27 connect(sender: textInputV3, signal: &QWaylandTextInputV3::surfaceEnabled, context: this, slot: &QWaylandInputMethodControl::surfaceEnabled);
28 connect(sender: textInputV3, signal: &QWaylandTextInputV3::surfaceDisabled, context: this, slot: &QWaylandInputMethodControl::surfaceDisabled);
29 connect(sender: textInputV3, signal: &QWaylandTextInputV3::updateInputMethod, context: this, slot: &QWaylandInputMethodControl::updateInputMethod);
30 }
31
32 QWaylandQtTextInputMethod *textInputMethod = d_func()->textInputMethod();
33 if (textInputMethod) {
34 connect(sender: textInputMethod, signal: &QWaylandQtTextInputMethod::surfaceEnabled, context: this, slot: &QWaylandInputMethodControl::surfaceEnabled);
35 connect(sender: textInputMethod, signal: &QWaylandQtTextInputMethod::surfaceDisabled, context: this, slot: &QWaylandInputMethodControl::surfaceDisabled);
36 connect(sender: textInputMethod, signal: &QWaylandQtTextInputMethod::updateInputMethod, context: this, slot: &QWaylandInputMethodControl::updateInputMethod);
37 }
38}
39
40QVariant QWaylandInputMethodControl::inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const
41{
42 Q_D(const QWaylandInputMethodControl);
43
44 QWaylandTextInput *textInput = d->textInput();
45 if (textInput != nullptr && textInput->focus() == d->surface)
46 return textInput->inputMethodQuery(property: query, argument);
47
48 QWaylandTextInputV3 *textInputV3 = d->textInputV3();
49 if (textInputV3 != nullptr && textInputV3->focus() == d->surface)
50 return textInputV3->inputMethodQuery(property: query, argument);
51
52 QWaylandQtTextInputMethod *textInputMethod = d_func()->textInputMethod();
53 if (textInputMethod && textInputMethod->focusedSurface() == d->surface)
54 return textInputMethod->inputMethodQuery(property: query, argument);
55
56 return QVariant();
57}
58
59void QWaylandInputMethodControl::inputMethodEvent(QInputMethodEvent *event)
60{
61 Q_D(QWaylandInputMethodControl);
62
63 if (QWaylandTextInput *textInput = d->textInput()) {
64 textInput->sendInputMethodEvent(event);
65 } else if (QWaylandTextInputV3 *textInputV3 = d->textInputV3()) {
66 textInputV3->sendInputMethodEvent(event);
67 } else if (QWaylandQtTextInputMethod *textInputMethod = d->textInputMethod()) {
68 textInputMethod->sendInputMethodEvent(event);
69 } else {
70 event->ignore();
71 }
72}
73
74bool QWaylandInputMethodControl::enabled() const
75{
76 Q_D(const QWaylandInputMethodControl);
77
78 return d->enabled;
79}
80
81void QWaylandInputMethodControl::setEnabled(bool enabled)
82{
83 Q_D(QWaylandInputMethodControl);
84
85 if (d->enabled == enabled)
86 return;
87
88 d->enabled = enabled;
89 emit enabledChanged(enabled);
90 emit updateInputMethod(queries: Qt::ImQueryInput);
91}
92
93void QWaylandInputMethodControl::surfaceEnabled(QWaylandSurface *surface)
94{
95 Q_D(QWaylandInputMethodControl);
96
97 if (surface == d->surface)
98 setEnabled(true);
99}
100
101void QWaylandInputMethodControl::surfaceDisabled(QWaylandSurface *surface)
102{
103 Q_D(QWaylandInputMethodControl);
104
105 if (surface == d->surface)
106 setEnabled(false);
107}
108
109void QWaylandInputMethodControl::setSurface(QWaylandSurface *surface)
110{
111 Q_D(QWaylandInputMethodControl);
112
113 if (d->surface == surface)
114 return;
115
116 d->surface = surface;
117
118 QWaylandTextInput *textInput = d->textInput();
119 QWaylandTextInputV3 *textInputV3 = d->textInputV3();
120 QWaylandQtTextInputMethod *textInputMethod = d->textInputMethod();
121 setEnabled((textInput && textInput->isSurfaceEnabled(surface: d->surface))
122 || (textInputV3 && textInputV3->isSurfaceEnabled(surface: d->surface))
123 || (textInputMethod && textInputMethod->isSurfaceEnabled(surface: d->surface)));
124}
125
126void QWaylandInputMethodControl::updateTextInput()
127{
128 QWaylandTextInput *textInput = d_func()->textInput();
129
130 if (textInput) {
131 connect(sender: textInput, signal: &QWaylandTextInput::surfaceEnabled, context: this, slot: &QWaylandInputMethodControl::surfaceEnabled, type: Qt::UniqueConnection);
132 connect(sender: textInput, signal: &QWaylandTextInput::surfaceDisabled, context: this, slot: &QWaylandInputMethodControl::surfaceDisabled, type: Qt::UniqueConnection);
133 connect(sender: textInput, signal: &QWaylandTextInput::updateInputMethod, context: this, slot: &QWaylandInputMethodControl::updateInputMethod, type: Qt::UniqueConnection);
134 }
135}
136
137void QWaylandInputMethodControl::defaultSeatChanged()
138{
139 Q_D(QWaylandInputMethodControl);
140
141 disconnect(sender: d->textInput(), signal: nullptr, receiver: this, member: nullptr);
142 disconnect(sender: d->textInputV3(), signal: nullptr, receiver: this, member: nullptr);
143 disconnect(sender: d->textInputMethod(), signal: nullptr, receiver: this, member: nullptr);
144
145 d->seat = d->compositor->defaultSeat();
146 QWaylandTextInput *textInput = d->textInput();
147 QWaylandTextInputV3 *textInputV3 = d->textInputV3();
148 QWaylandQtTextInputMethod *textInputMethod = d->textInputMethod();
149
150 if (textInput) {
151 connect(sender: textInput, signal: &QWaylandTextInput::surfaceEnabled, context: this, slot: &QWaylandInputMethodControl::surfaceEnabled);
152 connect(sender: textInput, signal: &QWaylandTextInput::surfaceDisabled, context: this, slot: &QWaylandInputMethodControl::surfaceDisabled);
153 }
154
155 if (textInputV3) {
156 connect(sender: textInputV3, signal: &QWaylandTextInputV3::surfaceEnabled, context: this, slot: &QWaylandInputMethodControl::surfaceEnabled);
157 connect(sender: textInputV3, signal: &QWaylandTextInputV3::surfaceDisabled, context: this, slot: &QWaylandInputMethodControl::surfaceDisabled);
158 }
159
160 if (textInputMethod) {
161 connect(sender: textInputMethod, signal: &QWaylandQtTextInputMethod::surfaceEnabled, context: this, slot: &QWaylandInputMethodControl::surfaceEnabled);
162 connect(sender: textInputMethod, signal: &QWaylandQtTextInputMethod::surfaceDisabled, context: this, slot: &QWaylandInputMethodControl::surfaceDisabled);
163 }
164
165 setEnabled((textInput && textInput->isSurfaceEnabled(surface: d->surface))
166 || (textInputV3 && textInputV3->isSurfaceEnabled(surface: d->surface))
167 || (textInputMethod && textInputMethod->isSurfaceEnabled(surface: d->surface)));
168}
169
170QWaylandInputMethodControlPrivate::QWaylandInputMethodControlPrivate(QWaylandSurface *surface)
171 : compositor(surface->compositor())
172 , seat(compositor->defaultSeat())
173 , surface(surface)
174{
175}
176
177QWaylandQtTextInputMethod *QWaylandInputMethodControlPrivate::textInputMethod() const
178{
179 if (!surface->client() || !surface->client()->textInputProtocols().testFlag(flag: QWaylandClient::TextInputProtocol::QtTextInputMethodV1))
180 return nullptr;
181 return QWaylandQtTextInputMethod::findIn(container: seat);
182}
183
184QWaylandTextInput *QWaylandInputMethodControlPrivate::textInput() const
185{
186 if (!surface->client() || !surface->client()->textInputProtocols().testFlag(flag: QWaylandClient::TextInputProtocol::TextInputV2))
187 return nullptr;
188 return QWaylandTextInput::findIn(container: seat);
189}
190
191QWaylandTextInputV3 *QWaylandInputMethodControlPrivate::textInputV3() const
192{
193 return QWaylandTextInputV3::findIn(container: seat);
194}
195
196#include "moc_qwaylandinputmethodcontrol.cpp"
197

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtwayland/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp