Changeset View
Changeset View
Standalone View
Standalone View
libtaskmanager/virtualdesktopinfo.cpp
Show All 21 Lines | |||||
22 | 22 | | |||
23 | #include <KLocalizedString> | 23 | #include <KLocalizedString> | ||
24 | #include <KWayland/Client/connection_thread.h> | 24 | #include <KWayland/Client/connection_thread.h> | ||
25 | #include <KWayland/Client/plasmavirtualdesktop.h> | 25 | #include <KWayland/Client/plasmavirtualdesktop.h> | ||
26 | #include <KWayland/Client/registry.h> | 26 | #include <KWayland/Client/registry.h> | ||
27 | #include <KWindowSystem> | 27 | #include <KWindowSystem> | ||
28 | 28 | | |||
29 | #include <QDBusConnection> | 29 | #include <QDBusConnection> | ||
30 | #include <QDBusPendingCall> | ||||
31 | #include <QDBusPendingCallWatcher> | ||||
32 | #include <QDBusPendingReply> | ||||
33 | #include <QDBusServiceWatcher> | ||||
30 | 34 | | |||
31 | #include <config-X11.h> | 35 | #include <config-X11.h> | ||
32 | 36 | | |||
33 | #if HAVE_X11 | 37 | #if HAVE_X11 | ||
34 | #include <netwm.h> | 38 | #include <netwm.h> | ||
35 | #include <QX11Info> | 39 | #include <QX11Info> | ||
36 | #endif | 40 | #endif | ||
37 | 41 | | |||
▲ Show 20 Lines • Show All 154 Lines • ▼ Show 20 Line(s) | 193 | { | |||
192 | NETRootInfo info(QX11Info::connection(), NET::NumberOfDesktops); | 196 | NETRootInfo info(QX11Info::connection(), NET::NumberOfDesktops); | ||
193 | 197 | | |||
194 | if (info.numberOfDesktops() > 1) { | 198 | if (info.numberOfDesktops() > 1) { | ||
195 | info.setNumberOfDesktops(info.numberOfDesktops() - 1); | 199 | info.setNumberOfDesktops(info.numberOfDesktops() - 1); | ||
196 | } | 200 | } | ||
197 | } | 201 | } | ||
198 | #endif | 202 | #endif | ||
199 | 203 | | |||
204 | static const QString s_serviceName(QStringLiteral("org.kde.KWin")); | ||||
205 | static const QString s_virtualDesktopsInterface(QStringLiteral("org.kde.KWin.VirtualDesktopManager")); | ||||
206 | static const QString s_virtDesktopsPath(QStringLiteral("/VirtualDesktopManager")); | ||||
207 | static const QString s_fdoPropertiesInterface(QStringLiteral("org.freedesktop.DBus.Properties")); | ||||
208 | | ||||
200 | class Q_DECL_HIDDEN VirtualDesktopInfo::WaylandPrivate : public VirtualDesktopInfo::Private | 209 | class Q_DECL_HIDDEN VirtualDesktopInfo::WaylandPrivate : public VirtualDesktopInfo::Private | ||
201 | { | 210 | { | ||
211 | Q_OBJECT | ||||
212 | | ||||
202 | public: | 213 | public: | ||
203 | WaylandPrivate(VirtualDesktopInfo *q); | 214 | WaylandPrivate(VirtualDesktopInfo *q); | ||
204 | 215 | | |||
205 | QVariant currentVirtualDesktop; | 216 | QVariant currentVirtualDesktop; | ||
206 | QStringList virtualDesktops; | 217 | QStringList virtualDesktops; | ||
218 | uint cachedDesktopLayoutRows = 0; | ||||
davidedmundson: Would it be safer to assume there's 1 row until we update.
I'm sure we have some
columns =… | |||||
Indeed. I had 1 initially, but somehow it changed during editing. I'll change it. hein: Indeed. I had 1 initially, but somehow it changed during editing. I'll change it. | |||||
207 | KWayland::Client::PlasmaVirtualDesktopManagement *virtualDesktopManagement = nullptr; | 219 | KWayland::Client::PlasmaVirtualDesktopManagement *virtualDesktopManagement = nullptr; | ||
220 | QDBusServiceWatcher *kwinServiceWatcher = nullptr; | ||||
208 | 221 | | |||
209 | void init() override; | 222 | void init() override; | ||
210 | void addDesktop(const QString &id, quint32 position); | 223 | void addDesktop(const QString &id, quint32 position); | ||
211 | QVariant currentDesktop() const override; | 224 | QVariant currentDesktop() const override; | ||
212 | int numberOfDesktops() const override; | 225 | int numberOfDesktops() const override; | ||
213 | QVariantList desktopIds() const override; | 226 | QVariantList desktopIds() const override; | ||
214 | QStringList desktopNames() const override; | 227 | QStringList desktopNames() const override; | ||
215 | quint32 position(const QVariant &desktop) const override; | 228 | quint32 position(const QVariant &desktop) const override; | ||
216 | int desktopLayoutRows() const override; | 229 | int desktopLayoutRows() const override; | ||
217 | void requestActivate(const QVariant &desktop) override; | 230 | void requestActivate(const QVariant &desktop) override; | ||
218 | void requestCreateDesktop(quint32 position) override; | 231 | void requestCreateDesktop(quint32 position) override; | ||
219 | void requestRemoveDesktop(quint32 position) override; | 232 | void requestRemoveDesktop(quint32 position) override; | ||
233 | | ||||
234 | public Q_SLOTS: | ||||
235 | void handleDesktopLayoutRowsChanged(uint rows); | ||||
220 | }; | 236 | }; | ||
221 | 237 | | |||
222 | VirtualDesktopInfo::WaylandPrivate::WaylandPrivate(VirtualDesktopInfo *q) | 238 | VirtualDesktopInfo::WaylandPrivate::WaylandPrivate(VirtualDesktopInfo *q) | ||
223 | : VirtualDesktopInfo::Private(q) | 239 | : VirtualDesktopInfo::Private(q) | ||
224 | { | 240 | { | ||
225 | init(); | 241 | init(); | ||
226 | } | 242 | } | ||
227 | 243 | | |||
Show All 37 Lines | 279 | if (currentVirtualDesktop == id) { | |||
265 | emit currentDesktopChanged(); | 281 | emit currentDesktopChanged(); | ||
266 | } | 282 | } | ||
267 | } | 283 | } | ||
268 | ); | 284 | ); | ||
269 | } | 285 | } | ||
270 | ); | 286 | ); | ||
271 | 287 | | |||
272 | registry->setup(); | 288 | registry->setup(); | ||
289 | | ||||
290 | kwinServiceWatcher = new QDBusServiceWatcher(s_serviceName, | ||||
291 | QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange); | ||||
292 | | ||||
293 | QObject::connect(kwinServiceWatcher, &QDBusServiceWatcher::serviceRegistered, | ||||
why? If it's not registered it won't emit the signal anyway so there's no need to disconnect. It would arguably make sense to re-query the initial state on service registration in case it changed whilst kwin was offline - but that's not what this does. davidedmundson: why?
If it's not registered it won't emit the signal anyway so there's no need to disconnect. | |||||
It's identical to the code in the KCM that passed review, and I didn't want to take any chances with this one due to the timeline. I think I might leave it as-is, since it's going to be replaced in 5.16 anyway. hein: It's identical to the code in the KCM that passed review, and I didn't want to take any chances… | |||||
294 | this, [this]() { | ||||
295 | QDBusConnection::sessionBus().connect( | ||||
296 | s_serviceName, | ||||
297 | s_virtDesktopsPath, | ||||
298 | s_virtualDesktopsInterface, | ||||
299 | QStringLiteral("rowsChanged"), | ||||
300 | this, | ||||
301 | SLOT(handleDesktopLayoutRowsChanged(uint))); | ||||
302 | }); | ||||
303 | | ||||
304 | QObject::connect(kwinServiceWatcher, &QDBusServiceWatcher::serviceUnregistered, | ||||
305 | this, [this]() { | ||||
306 | QDBusConnection::sessionBus().disconnect( | ||||
307 | s_serviceName, | ||||
308 | s_virtDesktopsPath, | ||||
309 | s_virtualDesktopsInterface, | ||||
310 | QStringLiteral("rowsChanged"), | ||||
311 | this, | ||||
312 | SLOT(handleDesktopLayoutRowsChanged(uint))); | ||||
313 | } | ||||
314 | ); | ||||
315 | | ||||
316 | QDBusConnection::sessionBus().connect( | ||||
317 | s_serviceName, | ||||
318 | s_virtDesktopsPath, | ||||
319 | s_virtualDesktopsInterface, | ||||
320 | QStringLiteral("rowsChanged"), | ||||
321 | this, | ||||
322 | SLOT(handleDesktopLayoutRowsChanged(uint))); | ||||
323 | | ||||
324 | auto callFinished = [this](QDBusPendingCallWatcher *call) { | ||||
325 | QDBusPendingReply<QVariant> reply = *call; | ||||
326 | | ||||
327 | handleDesktopLayoutRowsChanged(reply.value().toUInt()); | ||||
328 | | ||||
329 | call->deleteLater(); | ||||
330 | }; | ||||
331 | | ||||
332 | auto call = QDBusMessage::createMethodCall( | ||||
333 | s_serviceName, | ||||
334 | s_virtDesktopsPath, | ||||
335 | s_fdoPropertiesInterface, | ||||
336 | QStringLiteral("Get")); | ||||
337 | | ||||
338 | call.setArguments({s_virtualDesktopsInterface, QStringLiteral("rows")}); | ||||
339 | | ||||
340 | QDBusPendingCall pending = QDBusConnection::sessionBus().asyncCall(call); | ||||
341 | | ||||
342 | const QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pending, this); | ||||
343 | QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, callFinished); | ||||
273 | } | 344 | } | ||
274 | 345 | | |||
275 | void VirtualDesktopInfo::WaylandPrivate::addDesktop(const QString &id, quint32 position) | 346 | void VirtualDesktopInfo::WaylandPrivate::addDesktop(const QString &id, quint32 position) | ||
276 | { | 347 | { | ||
277 | if (virtualDesktops.indexOf(id) != -1) { | 348 | if (virtualDesktops.indexOf(id) != -1) { | ||
278 | return; | 349 | return; | ||
279 | } | 350 | } | ||
280 | 351 | | |||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Line(s) | 403 | foreach(const QString &id, virtualDesktops) { | |||
337 | } | 408 | } | ||
338 | } | 409 | } | ||
339 | 410 | | |||
340 | return names; | 411 | return names; | ||
341 | } | 412 | } | ||
342 | 413 | | |||
343 | int VirtualDesktopInfo::WaylandPrivate::desktopLayoutRows() const | 414 | int VirtualDesktopInfo::WaylandPrivate::desktopLayoutRows() const | ||
344 | { | 415 | { | ||
345 | // TODO FIXME: We don't have virtual desktop layout information in the Wayland | 416 | return (int)cachedDesktopLayoutRows; | ||
346 | // protocol yet. | | |||
347 | return 0; | | |||
348 | } | 417 | } | ||
349 | 418 | | |||
350 | void VirtualDesktopInfo::WaylandPrivate::requestActivate(const QVariant &desktop) | 419 | void VirtualDesktopInfo::WaylandPrivate::requestActivate(const QVariant &desktop) | ||
351 | { | 420 | { | ||
352 | KWayland::Client::PlasmaVirtualDesktop *desktopObj = virtualDesktopManagement->getVirtualDesktop(desktop.toString()); | 421 | KWayland::Client::PlasmaVirtualDesktop *desktopObj = virtualDesktopManagement->getVirtualDesktop(desktop.toString()); | ||
353 | 422 | | |||
354 | if (desktopObj) { | 423 | if (desktopObj) { | ||
355 | desktopObj->requestActivate(); | 424 | desktopObj->requestActivate(); | ||
Show All 13 Lines | 434 | { | |||
369 | 438 | | |||
370 | if (position > ((quint32)virtualDesktops.count() - 1)) { | 439 | if (position > ((quint32)virtualDesktops.count() - 1)) { | ||
371 | return; | 440 | return; | ||
372 | } | 441 | } | ||
373 | 442 | | |||
374 | virtualDesktopManagement->requestRemoveVirtualDesktop(virtualDesktops.at(position)); | 443 | virtualDesktopManagement->requestRemoveVirtualDesktop(virtualDesktops.at(position)); | ||
375 | } | 444 | } | ||
376 | 445 | | |||
446 | void VirtualDesktopInfo::WaylandPrivate::handleDesktopLayoutRowsChanged(uint rows) | ||||
447 | { | ||||
448 | if (cachedDesktopLayoutRows != rows) { | ||||
449 | cachedDesktopLayoutRows = rows; | ||||
450 | | ||||
451 | emit desktopLayoutRowsChanged(); | ||||
452 | } | ||||
453 | } | ||||
454 | | ||||
377 | VirtualDesktopInfo::Private* VirtualDesktopInfo::d = nullptr; | 455 | VirtualDesktopInfo::Private* VirtualDesktopInfo::d = nullptr; | ||
378 | 456 | | |||
379 | VirtualDesktopInfo::VirtualDesktopInfo(QObject *parent) : QObject(parent) | 457 | VirtualDesktopInfo::VirtualDesktopInfo(QObject *parent) : QObject(parent) | ||
380 | { | 458 | { | ||
381 | if (!d) { | 459 | if (!d) { | ||
382 | #if HAVE_X11 | 460 | #if HAVE_X11 | ||
383 | if (KWindowSystem::isPlatformX11()) { | 461 | if (KWindowSystem::isPlatformX11()) { | ||
384 | d = new VirtualDesktopInfo::XWindowPrivate(this); | 462 | d = new VirtualDesktopInfo::XWindowPrivate(this); | ||
▲ Show 20 Lines • Show All 79 Lines • Show Last 20 Lines |
Would it be safer to assume there's 1 row until we update.
I'm sure we have some
columns = count / rows
code somewhere