Changeset View
Changeset View
Standalone View
Standalone View
virtualkeyboard.cpp
Show All 28 Lines | |||||
29 | 29 | | |||
30 | #include <KWayland/Server/display.h> | 30 | #include <KWayland/Server/display.h> | ||
31 | #include <KWayland/Server/seat_interface.h> | 31 | #include <KWayland/Server/seat_interface.h> | ||
32 | #include <KWayland/Server/textinput_interface.h> | 32 | #include <KWayland/Server/textinput_interface.h> | ||
33 | 33 | | |||
34 | #include <KStatusNotifierItem> | 34 | #include <KStatusNotifierItem> | ||
35 | #include <KLocalizedString> | 35 | #include <KLocalizedString> | ||
36 | 36 | | |||
37 | #include <KDecoration2/Decoration> | ||||
38 | | ||||
37 | #include <QDBusConnection> | 39 | #include <QDBusConnection> | ||
38 | #include <QDBusPendingCall> | 40 | #include <QDBusPendingCall> | ||
39 | #include <QDBusMessage> | 41 | #include <QDBusMessage> | ||
40 | #include <QGuiApplication> | 42 | #include <QGuiApplication> | ||
41 | #include <QQmlComponent> | 43 | #include <QQmlComponent> | ||
42 | #include <QQmlContext> | 44 | #include <QQmlContext> | ||
43 | #include <QQmlEngine> | 45 | #include <QQmlEngine> | ||
44 | #include <QQuickItem> | 46 | #include <QQuickItem> | ||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Line(s) | 140 | m_waylandHintsConnection = connect(t, &TextInputInterface::contentTypeChanged, this, | |||
141 | } | 143 | } | ||
142 | ); | 144 | ); | ||
143 | m_waylandResetConnection = connect(t, &TextInputInterface::requestReset, qApp->inputMethod(), &QInputMethod::reset); | 145 | m_waylandResetConnection = connect(t, &TextInputInterface::requestReset, qApp->inputMethod(), &QInputMethod::reset); | ||
144 | m_waylandEnabledConnection = connect(t, &TextInputInterface::enabledChanged, this, | 146 | m_waylandEnabledConnection = connect(t, &TextInputInterface::enabledChanged, this, | ||
145 | [] { | 147 | [] { | ||
146 | qApp->inputMethod()->update(Qt::ImQueryAll); | 148 | qApp->inputMethod()->update(Qt::ImQueryAll); | ||
147 | } | 149 | } | ||
148 | ); | 150 | ); | ||
149 | // TODO: calculate overlap | 151 | | ||
150 | t->setInputPanelState(m_inputWindow->isVisible(), QRect(0, 0, 0, 0)); | 152 | disconnect(m_trackedClient.data(), nullptr, this, nullptr); | ||
153 | m_trackedClient = waylandServer()->findAbstractClient(waylandServer()->seat()->focusedTextInputSurface()); | ||||
davidedmundson: If we move from one subsurface to another we would get into this path with the same client.
It… | |||||
154 | | ||||
155 | | ||||
156 | if (m_trackedClient) { | ||||
157 | connect(m_trackedClient.data(), &AbstractClient::geometryChanged, this, &VirtualKeyboard::updateInputPanelState); | ||||
davidedmundson: m_trackedClient = t; | |||||
mart: t is not an abstractclient but a surface? | |||||
davidedmundson: I meant:
m_trackedClient = waylandServer()->findAbstractClient(t);
| |||||
158 | } | ||||
159 | | ||||
160 | updateInputPanelState(); | ||||
151 | } else { | 161 | } else { | ||
152 | m_waylandShowConnection = QMetaObject::Connection(); | 162 | m_waylandShowConnection = QMetaObject::Connection(); | ||
153 | m_waylandHideConnection = QMetaObject::Connection(); | 163 | m_waylandHideConnection = QMetaObject::Connection(); | ||
154 | m_waylandHintsConnection = QMetaObject::Connection(); | 164 | m_waylandHintsConnection = QMetaObject::Connection(); | ||
155 | m_waylandSurroundingTextConnection = QMetaObject::Connection(); | 165 | m_waylandSurroundingTextConnection = QMetaObject::Connection(); | ||
156 | m_waylandResetConnection = QMetaObject::Connection(); | 166 | m_waylandResetConnection = QMetaObject::Connection(); | ||
157 | m_waylandEnabledConnection = QMetaObject::Connection(); | 167 | m_waylandEnabledConnection = QMetaObject::Connection(); | ||
158 | } | 168 | } | ||
Show All 12 Lines | |||||
171 | connect(m_inputWindow->rootObject(), &QQuickItem::childrenRectChanged, m_inputWindow.data(), | 181 | connect(m_inputWindow->rootObject(), &QQuickItem::childrenRectChanged, m_inputWindow.data(), | ||
172 | [this] { | 182 | [this] { | ||
173 | if (!m_inputWindow) { | 183 | if (!m_inputWindow) { | ||
174 | return; | 184 | return; | ||
175 | } | 185 | } | ||
176 | m_inputWindow->setMask(m_inputWindow->rootObject()->childrenRect().toRect()); | 186 | m_inputWindow->setMask(m_inputWindow->rootObject()->childrenRect().toRect()); | ||
177 | } | 187 | } | ||
178 | ); | 188 | ); | ||
179 | connect(qApp->inputMethod(), &QInputMethod::visibleChanged, m_inputWindow.data(), | 189 | | ||
180 | [this] { | 190 | connect(qApp->inputMethod(), &QInputMethod::visibleChanged, this, &VirtualKeyboard::updateInputPanelState); | ||
181 | m_inputWindow->setVisible(qApp->inputMethod()->isVisible()); | 191 | | ||
182 | if (qApp->inputMethod()->isVisible()) { | 192 | connect(m_inputWindow->rootObject(), &QQuickItem::childrenRectChanged, this, &VirtualKeyboard::updateInputPanelState); | ||
If this changes whilst our text input has focus, we'll cache the wrong m_trackedClientOriginalMaxState davidedmundson: If this changes whilst our text input has focus, we'll cache the wrong… | |||||
hmm, that should happen only when inputPanelHasBeenOpened? mart: hmm, that should happen only when inputPanelHasBeenOpened?
(that means, the keyboard has been… | |||||
183 | m_inputWindow->setMask(m_inputWindow->rootObject()->childrenRect().toRect()); | | |||
184 | } | | |||
185 | if (waylandServer()) { | | |||
186 | if (auto t = waylandServer()->seat()->focusedTextInput()) { | | |||
187 | // TODO: calculate overlap | | |||
188 | t->setInputPanelState(m_inputWindow->isVisible(), QRect(0, 0, 0, 0)); | | |||
189 | } | | |||
190 | } | | |||
191 | } | | |||
192 | ); | | |||
193 | } | 193 | } | ||
194 | 194 | | |||
195 | void VirtualKeyboard::setEnabled(bool enabled) | 195 | void VirtualKeyboard::setEnabled(bool enabled) | ||
196 | { | 196 | { | ||
197 | if (m_enabled == enabled) { | 197 | if (m_enabled == enabled) { | ||
198 | return; | 198 | return; | ||
199 | } | 199 | } | ||
200 | m_enabled = enabled; | 200 | m_enabled = enabled; | ||
Show All 20 Lines | 220 | if (m_enabled) { | |||
221 | m_sni->setIconByName(QStringLiteral("input-keyboard-virtual-on")); | 221 | m_sni->setIconByName(QStringLiteral("input-keyboard-virtual-on")); | ||
222 | m_sni->setToolTipTitle(i18n("Virtual Keyboard is enabled.")); | 222 | m_sni->setToolTipTitle(i18n("Virtual Keyboard is enabled.")); | ||
223 | } else { | 223 | } else { | ||
224 | m_sni->setIconByName(QStringLiteral("input-keyboard-virtual-off")); | 224 | m_sni->setIconByName(QStringLiteral("input-keyboard-virtual-off")); | ||
225 | m_sni->setToolTipTitle(i18n("Virtual Keyboard is disabled.")); | 225 | m_sni->setToolTipTitle(i18n("Virtual Keyboard is disabled.")); | ||
226 | } | 226 | } | ||
227 | } | 227 | } | ||
228 | 228 | | |||
229 | void VirtualKeyboard::updateInputPanelState() | ||||
230 | { | ||||
231 | const bool inputPanelHasBeenOpened = !m_inputWindow->isVisible() && qApp->inputMethod()->isVisible(); | ||||
232 | const bool inputPanelHasBeenClosed = m_inputWindow->isVisible() && !qApp->inputMethod()->isVisible(); | ||||
233 | | ||||
234 | m_inputWindow->setVisible(qApp->inputMethod()->isVisible()); | ||||
235 | | ||||
236 | if (qApp->inputMethod()->isVisible()) { | ||||
237 | m_inputWindow->setMask(m_inputWindow->rootObject()->childrenRect().toRect()); | ||||
238 | } | ||||
Can you put this and the next condition in the beginning and: if(!condition) { return; } romangg: Can you put this and the next condition in the beginning and:
```
if(!condition) {
return… | |||||
239 | if (waylandServer()) { | ||||
240 | | ||||
241 | if (auto t = waylandServer()->seat()->focusedTextInput()) { | ||||
242 | if (m_inputWindow->isVisible() && m_trackedClient && m_inputWindow->rootObject()) { | ||||
243 | | ||||
244 | | ||||
245 | const QRect inputPanelGeom = m_inputWindow->rootObject()->childrenRect().toRect().translated(m_inputWindow->geometry().topLeft()); | ||||
246 | | ||||
247 | if (inputPanelHasBeenOpened) { | ||||
248 | m_trackedClient->setGeometryRestore(m_trackedClient->geometry()); | ||||
249 | } else if (inputPanelHasBeenClosed && !m_trackedClient->geometryRestore().isNull()) { | ||||
250 | m_trackedClient->setGeometry(m_trackedClient->geometryRestore()); | ||||
251 | } | ||||
252 | if (!inputPanelHasBeenClosed) { | ||||
253 | QRect screenArea = workspace()->clientArea(ScreenArea, m_trackedClient); | ||||
254 | screenArea.setBottom(screenArea.bottom() - inputPanelGeom.height()); | ||||
255 | | ||||
256 | QRect newGeom = m_trackedClient->geometry(); | ||||
257 | newGeom.moveBottom(qMin(newGeom.bottom(), inputPanelGeom.top())); | ||||
258 | newGeom.setTop(qMax(screenArea.top(), newGeom.top())); | ||||
259 | m_trackedClient->setGeometry(newGeom); | ||||
260 | } | ||||
261 | | ||||
262 | t->setInputPanelState(true, QRect(0, 0, 0, 0)); | ||||
263 | } else { | ||||
I would expect these two lines need swapping, otherwise you're restoring maximise before we're adjusted the client area. davidedmundson: I would expect these two lines need swapping, otherwise you're restoring maximise before we're… | |||||
This comment is done Writing that explicitly as phab make it look like we should swap them again! davidedmundson: This comment is done
Writing that explicitly as phab make it look like we should swap them… | |||||
264 | t->setInputPanelState(false, QRect(0, 0, 0, 0)); | ||||
265 | } | ||||
266 | } | ||||
267 | } | ||||
268 | } | ||||
269 | | ||||
229 | void VirtualKeyboard::show() | 270 | void VirtualKeyboard::show() | ||
230 | { | 271 | { | ||
231 | if (m_inputWindow.isNull() || !m_enabled) { | 272 | if (m_inputWindow.isNull() || !m_enabled) { | ||
232 | return; | 273 | return; | ||
233 | } | 274 | } | ||
234 | m_inputWindow->setGeometry(screens()->geometry(screens()->current())); | 275 | m_inputWindow->setGeometry(screens()->geometry(screens()->current())); | ||
235 | qApp->inputMethod()->show(); | 276 | qApp->inputMethod()->show(); | ||
236 | } | 277 | } | ||
▲ Show 20 Lines • Show All 213 Lines • Show Last 20 Lines |
If we move from one subsurface to another we would get into this path with the same client.
It might be worth doing