File indexing completed on 2025-01-26 05:00:55

0001 /*
0002  *   SPDX-FileCopyrightText: 2012, 2013, 2014 Ivan Cukic <ivan.cukic(at)kde.org>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "VirtualDesktopSwitchPlugin.h"
0008 
0009 #include <QDBusConnection>
0010 #include <QDBusMessage>
0011 #include <QDBusPendingCall>
0012 #include <QDBusPendingCallWatcher>
0013 #include <QDBusReply>
0014 #include <QString>
0015 
0016 #include <KWindowSystem>
0017 #include <KX11Extras>
0018 
0019 K_PLUGIN_CLASS_WITH_JSON(VirtualDesktopSwitchPlugin, "kactivitymanagerd-plugin-virtualdesktopswitch.json")
0020 
0021 const auto configPattern = QStringLiteral("desktop-for-%1");
0022 const auto kwinName = QStringLiteral("org.kde.KWin");
0023 const auto kwinPath = QStringLiteral("/KWin");
0024 
0025 VirtualDesktopSwitchPlugin::VirtualDesktopSwitchPlugin(QObject *parent)
0026     : Plugin(parent)
0027     , m_activitiesService(nullptr)
0028 {
0029     setName("org.kde.ActivityManager.VirtualDesktopSwitch");
0030 }
0031 
0032 VirtualDesktopSwitchPlugin::~VirtualDesktopSwitchPlugin()
0033 {
0034 }
0035 
0036 bool VirtualDesktopSwitchPlugin::init(QHash<QString, QObject *> &modules)
0037 {
0038     Plugin::init(modules);
0039 
0040     m_activitiesService = modules["activities"];
0041 
0042     m_currentActivity = Plugin::retrieve<QString>(m_activitiesService, "CurrentActivity");
0043 
0044     connect(m_activitiesService, SIGNAL(CurrentActivityChanged(QString)), this, SLOT(currentActivityChanged(QString)));
0045     connect(m_activitiesService, SIGNAL(ActivityRemoved(QString)), this, SLOT(activityRemoved(QString)));
0046 
0047     return true;
0048 }
0049 
0050 void VirtualDesktopSwitchPlugin::currentActivityChanged(const QString &activity)
0051 {
0052     if (m_currentActivity == activity) {
0053         return;
0054     }
0055 
0056     const int desktopId = config().readEntry(configPattern.arg(activity), -1);
0057 
0058     if (KWindowSystem::isPlatformX11()) {
0059         config().writeEntry(configPattern.arg(m_currentActivity), QString::number(KX11Extras::currentDesktop()));
0060         if (desktopId <= KX11Extras::numberOfDesktops() && desktopId >= 0) {
0061             KX11Extras::setCurrentDesktop(desktopId);
0062         }
0063     } else {
0064         auto currentMessage = QDBusMessage::createMethodCall(kwinName, kwinPath, kwinName, QStringLiteral("currentDesktop"));
0065         auto currentDesktopCall = QDBusConnection::sessionBus().asyncCall(currentMessage);
0066         if (desktopId >= 0) {
0067             auto setDesktopMessage = QDBusMessage::createMethodCall(kwinName, kwinPath, kwinName, QStringLiteral("setCurrentDesktop"));
0068             setDesktopMessage.setArguments({desktopId});
0069             QDBusConnection::sessionBus().send(setDesktopMessage);
0070         }
0071         const auto watcher = new QDBusPendingCallWatcher(currentDesktopCall);
0072         connect(watcher, &QDBusPendingCallWatcher::finished, this, [oldActivity = m_currentActivity, watcher, this] {
0073             watcher->deleteLater();
0074             auto reply = QDBusReply<int>(*watcher);
0075             config().writeEntry(configPattern.arg(oldActivity), reply.isValid() ? reply.value() : 0);
0076         });
0077     }
0078     m_currentActivity = activity;
0079 }
0080 
0081 void VirtualDesktopSwitchPlugin::activityRemoved(const QString &activity)
0082 {
0083     config().deleteEntry(configPattern.arg(activity));
0084     config().sync();
0085 }
0086 
0087 #include "VirtualDesktopSwitchPlugin.moc"
0088 
0089 #include "moc_VirtualDesktopSwitchPlugin.cpp"