From 05414ed58d43d87d907326636faac53ae2e7bd60 Mon Sep 17 00:00:00 2001 From: Eike Hein Date: Fri, 17 Jul 2020 10:37:11 +0100 Subject: [PATCH] Port to new KWorkspace API This patch adds a new enabled role to kicker items instead of creating and deleting them if they're not available due to configuration. It ports to the new session code in libkworkspace dropping our need for KDE4Support. From: D20237 --- applets/kicker/CMakeLists.txt | 5 +- applets/kicker/plugin/abstractmodel.cpp | 1 + applets/kicker/plugin/actionlist.h | 3 +- applets/kicker/plugin/systementry.cpp | 197 +++++++++++++----------- applets/kicker/plugin/systementry.h | 25 ++- applets/kicker/plugin/systemmodel.cpp | 77 ++++----- applets/kicker/plugin/systemmodel.h | 7 +- 7 files changed, 163 insertions(+), 152 deletions(-) diff --git a/applets/kicker/CMakeLists.txt b/applets/kicker/CMakeLists.txt index 3e183545a..63e562a24 100644 --- a/applets/kicker/CMakeLists.txt +++ b/applets/kicker/CMakeLists.txt @@ -58,7 +58,6 @@ add_library(kickerplugin SHARED ${kickerplugin_SRCS}) target_link_libraries(kickerplugin Qt5::Core - Qt5::DBus Qt5::Qml Qt5::Quick Qt5::X11Extras @@ -67,17 +66,17 @@ target_link_libraries(kickerplugin KF5::ConfigCore KF5::CoreAddons KF5::I18n + KF5::IconThemes KF5::ItemModels - KF5::KDELibs4Support # FIXME: New Solid power management API doesn't exist yet, so we need to use deprecated stuff. KF5::KIOCore KF5::KIOWidgets KF5::KIOFileWidgets + KF5::Notifications KF5::People KF5::PeopleWidgets KF5::PlasmaQuick KF5::Runner KF5::Service - KF5::Solid KF5::WindowSystem PW::KWorkspace) diff --git a/applets/kicker/plugin/abstractmodel.cpp b/applets/kicker/plugin/abstractmodel.cpp index a4966d8d3..154802022 100644 --- a/applets/kicker/plugin/abstractmodel.cpp +++ b/applets/kicker/plugin/abstractmodel.cpp @@ -44,6 +44,7 @@ QHash AbstractModel::roleNames() const roles.insert(Kicker::HasActionListRole, "hasActionList"); roles.insert(Kicker::ActionListRole, "actionList"); roles.insert(Kicker::UrlRole, "url"); + roles.insert(Kicker::DisabledRole, "disabled"); return roles; } diff --git a/applets/kicker/plugin/actionlist.h b/applets/kicker/plugin/actionlist.h index 25ef4379b..dd23ca4a8 100644 --- a/applets/kicker/plugin/actionlist.h +++ b/applets/kicker/plugin/actionlist.h @@ -40,7 +40,8 @@ enum { HasChildrenRole, HasActionListRole, ActionListRole, - UrlRole + UrlRole, + DisabledRole }; QVariantMap createActionItem(const QString &label, const QString &icon, const QString &actionId, const QVariant &argument = QVariant()); diff --git a/applets/kicker/plugin/systementry.cpp b/applets/kicker/plugin/systementry.cpp index 547893fc9..455134cdc 100644 --- a/applets/kicker/plugin/systementry.cpp +++ b/applets/kicker/plugin/systementry.cpp @@ -28,20 +28,25 @@ #include #include #include -#include -#include "ksmserver_interface.h" -#include +#include + +int SystemEntry::s_instanceCount = 0; +SessionManagement* SystemEntry::s_sessionManagement = nullptr; SystemEntry::SystemEntry(AbstractModel *owner, Action action) : AbstractEntry(owner) , m_action(action) , m_valid(false) +, m_initialized(false) { - init(); + refresh(); + ++s_instanceCount; + m_initialized = true; } SystemEntry::SystemEntry(AbstractModel *owner, const QString &id) : AbstractEntry(owner) , m_action(NoAction) , m_valid(false) +, m_initialized(false) { if (id == QLatin1String("lock-screen")) { m_action = LockSession; @@ -52,60 +57,103 @@ SystemEntry::SystemEntry(AbstractModel *owner, const QString &id) : AbstractEntr } else if (id == QLatin1String("switch-user")) { m_action = SwitchUser; } else if (id == QLatin1String("suspend")) { - m_action = SuspendToRam; + m_action = Suspend; } else if (id == QLatin1String("hibernate")) { - m_action = SuspendToDisk; + m_action = Hibernate; } else if (id == QLatin1String("reboot")) { m_action = Reboot; } else if (id == QLatin1String("shutdown")) { m_action = Shutdown; } - init(); + refresh(); + ++s_instanceCount; + m_initialized = true; } -void SystemEntry::init() +SystemEntry::~SystemEntry() { - switch (m_action) { - case NoAction: - m_valid = false; - break; - case LockSession: - m_valid = KAuthorized::authorizeAction(QStringLiteral("lock_screen")); - break; - case LogoutSession: - case SaveSession: - { - bool authorize = KAuthorized::authorizeAction(QStringLiteral("logout")) && KAuthorized::authorize(QStringLiteral("logout")); + --s_instanceCount; - if (m_action == SaveSession) { - const KConfigGroup c(KSharedConfig::openConfig(QStringLiteral("ksmserverrc"), KConfig::NoGlobals), "General"); + if (!s_instanceCount) { + delete s_sessionManagement; + s_sessionManagement = nullptr; + } +} + +SystemEntry::Action SystemEntry::action() const +{ + return m_action; +} + +void SystemEntry::refresh() +{ + if (!s_sessionManagement) { + s_sessionManagement = new SessionManagement(); + } - m_valid = authorize && c.readEntry("loginMode") == QLatin1String("restoreSavedSession"); - } else { - m_valid = authorize; - } + bool valid = false; + switch (m_action) { + case LockSession: { + valid = s_sessionManagement->canLock(); + QObject::connect(s_sessionManagement, &SessionManagement::canLockChanged, + this, &SystemEntry::refresh); break; } - case SwitchUser: - m_valid = (KAuthorized::authorizeAction(QStringLiteral("start_new_session")) || KAuthorized::authorizeAction(QStringLiteral("switch_user"))) - && KDisplayManager().isSwitchable(); + case LogoutSession: { + valid = s_sessionManagement->canLogout(); + QObject::connect(s_sessionManagement, &SessionManagement::canLogoutChanged, + this, &SystemEntry::refresh); break; - case SuspendToRam: - m_valid = Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::SuspendState); + } + case SaveSession: { + valid = s_sessionManagement->canSaveSession(); + QObject::connect(s_sessionManagement, &SessionManagement::canSaveSessionChanged, + this, &SystemEntry::refresh); break; - case SuspendToDisk: - m_valid = Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::HibernateState); + } + case SwitchUser: { + valid = s_sessionManagement->canSwitchUser(); + QObject::connect(s_sessionManagement, &SessionManagement::canSwitchUserChanged, + this, &SystemEntry::refresh); break; - case Reboot: - m_valid = KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot); + } + case Suspend: { + valid = s_sessionManagement->canSuspend(); + QObject::connect(s_sessionManagement, &SessionManagement::canSuspendChanged, + this, &SystemEntry::refresh); break; - case Shutdown: - m_valid = KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt); + } + case Hibernate: { + valid = s_sessionManagement->canHibernate(); + QObject::connect(s_sessionManagement, &SessionManagement::canHibernateChanged, + this, &SystemEntry::refresh); + break; + } + case Reboot: { + valid = s_sessionManagement->canReboot(); + QObject::connect(s_sessionManagement, &SessionManagement::canRebootChanged, + this, &SystemEntry::refresh); break; + } + case Shutdown: { + valid = s_sessionManagement->canShutdown(); + QObject::connect(s_sessionManagement, &SessionManagement::canShutdownChanged, + this, &SystemEntry::refresh); + break; + } default: - m_valid = true; + break; + } + + + if (m_valid != valid) { + m_valid = valid; + + if (m_initialized) { + emit isValidChanged(); + } } } @@ -140,10 +188,10 @@ QString SystemEntry::iconName() const case SwitchUser: return QStringLiteral("system-switch-user"); break; - case SuspendToRam: + case Suspend: return QStringLiteral("system-suspend"); break; - case SuspendToDisk: + case Hibernate: return QStringLiteral("system-suspend-hibernate"); break; case Reboot: @@ -174,10 +222,10 @@ QString SystemEntry::name() const case SwitchUser: return i18n("Switch User"); break; - case SuspendToRam: + case Suspend: return i18nc("Suspend to RAM", "Sleep"); break; - case SuspendToDisk: + case Hibernate: return i18n("Hibernate"); break; case Reboot: @@ -208,10 +256,10 @@ QString SystemEntry::group() const case SwitchUser: return i18n("Session"); break; - case SuspendToRam: + case Suspend: return i18n("System"); break; - case SuspendToDisk: + case Hibernate: return i18n("System"); break; case Reboot: @@ -242,10 +290,10 @@ QString SystemEntry::description() const case SwitchUser: return i18n("Start a parallel session as a different user"); break; - case SuspendToRam: + case Suspend: return i18n("Suspend to RAM"); break; - case SuspendToDisk: + case Hibernate: return i18n("Suspend to disk"); break; case Reboot: @@ -276,10 +324,10 @@ QString SystemEntry::id() const case SwitchUser: return QStringLiteral("switch-user"); break; - case SuspendToRam: + case Suspend: return QStringLiteral("suspend"); break; - case SuspendToDisk: + case Hibernate: return QStringLiteral("hibernate"); break; case Reboot: @@ -301,49 +349,20 @@ bool SystemEntry::run(const QString& actionId, const QVariant &argument) Q_UNUSED(actionId) Q_UNUSED(argument) - switch (m_action) { - case LockSession: - { - QDBusConnection bus = QDBusConnection::sessionBus(); - QDBusInterface interface(QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("/ScreenSaver"), QStringLiteral("org.freedesktop.ScreenSaver"), bus); - interface.asyncCall(QStringLiteral("Lock")); - break; - } - case LogoutSession: - KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeNone); - break; - case SaveSession: - { - org::kde::KSMServerInterface ksmserver(QStringLiteral("org.kde.ksmserver"), - QStringLiteral("/KSMServer"), QDBusConnection::sessionBus()); - - if (ksmserver.isValid()) { - ksmserver.saveCurrentSession(); - } + if (!m_valid) { + return false; + } - break; - } - case SwitchUser: - { - QDBusConnection bus = QDBusConnection::sessionBus(); - QDBusInterface interface(QStringLiteral("org.kde.ksmserver"), QStringLiteral("/KSMServer"), QStringLiteral("org.kde.KSMServerInterface"), bus); - interface.asyncCall(QStringLiteral("openSwitchUserDialog")); - break; - }; - case SuspendToRam: - Solid::PowerManagement::requestSleep(Solid::PowerManagement::SuspendState, nullptr, nullptr); - break; - case SuspendToDisk: - Solid::PowerManagement::requestSleep(Solid::PowerManagement::HibernateState, nullptr, nullptr); - break; - case Reboot: - KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot); - break; - case Shutdown: - KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt); - break; - default: - return false; + switch (m_action) { + case LockSession: s_sessionManagement->lock(); break; + case LogoutSession: s_sessionManagement->requestLogout(); break; + case SaveSession: s_sessionManagement->saveSession(); break; + case SwitchUser: s_sessionManagement->switchUser(); break; + case Suspend: s_sessionManagement->suspend(); break; + case Hibernate: s_sessionManagement->hibernate(); break; + case Reboot: s_sessionManagement->requestReboot(); break; + case Shutdown: s_sessionManagement->requestShutdown(); break; + default: break; } return true; diff --git a/applets/kicker/plugin/systementry.h b/applets/kicker/plugin/systementry.h index da0f72f33..b3fa1c26b 100644 --- a/applets/kicker/plugin/systementry.h +++ b/applets/kicker/plugin/systementry.h @@ -22,8 +22,14 @@ #include "abstractentry.h" -class SystemEntry : public AbstractEntry +#include + +class SessionManagement; + +class SystemEntry : public QObject, public AbstractEntry { + Q_OBJECT + public: enum Action { @@ -32,14 +38,17 @@ class SystemEntry : public AbstractEntry LogoutSession, SaveSession, SwitchUser, - SuspendToRam, - SuspendToDisk, + Suspend, + Hibernate, Reboot, Shutdown }; explicit SystemEntry(AbstractModel *owner, Action action); explicit SystemEntry(AbstractModel *owner, const QString &id); + ~SystemEntry(); + + Action action() const; EntryType type() const override { return RunnableType; } @@ -55,12 +64,20 @@ class SystemEntry : public AbstractEntry bool run(const QString& actionId = QString(), const QVariant &argument = QVariant()) override; + Q_SIGNALS: + void isValidChanged() const; + + private Q_SLOTS: + void refresh(); + private: - void init(); + bool m_initialized; Action m_action; bool m_valid; + static int s_instanceCount; + static SessionManagement *s_sessionManagement; }; #endif diff --git a/applets/kicker/plugin/systemmodel.cpp b/applets/kicker/plugin/systemmodel.cpp index 339bf0aa2..7f0796efd 100644 --- a/applets/kicker/plugin/systemmodel.cpp +++ b/applets/kicker/plugin/systemmodel.cpp @@ -20,7 +20,6 @@ #include "systemmodel.h" #include "actionlist.h" #include "simplefavoritesmodel.h" -#include "systementry.h" #include @@ -29,45 +28,32 @@ SystemModel::SystemModel(QObject *parent) : AbstractModel(parent) { - init(); - m_favoritesModel = new SimpleFavoritesModel(this); - const QString configFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/ksmserverrc"); - - KDirWatch *watch = new KDirWatch(this); - - watch->addFile(configFile); - - connect(watch, &KDirWatch::dirty, this, &SystemModel::refresh); - connect(watch, &KDirWatch::created, this, &SystemModel::refresh); + m_entries[SystemEntry::LockSession] = new SystemEntry(this, SystemEntry::LockSession); + m_entries[SystemEntry::LogoutSession] = new SystemEntry(this, SystemEntry::LogoutSession); + m_entries[SystemEntry::SaveSession] = new SystemEntry(this, SystemEntry::SaveSession); + m_entries[SystemEntry::SwitchUser] = new SystemEntry(this, SystemEntry::SwitchUser); + m_entries[SystemEntry::Suspend] = new SystemEntry(this, SystemEntry::Suspend); + m_entries[SystemEntry::Hibernate] = new SystemEntry(this, SystemEntry::Hibernate); + m_entries[SystemEntry::Reboot] = new SystemEntry(this, SystemEntry::Reboot); + m_entries[SystemEntry::Shutdown] = new SystemEntry(this, SystemEntry::Shutdown); + + for (SystemEntry *entry : m_entries.values()) { + QObject::connect(entry, &SystemEntry::isValidChanged, this, + [this, entry]() { + const QModelIndex &idx = index(entry->action(), 0); + emit dataChanged(idx, idx, QVector{Kicker::DisabledRole}); + } + ); + + QObject::connect(entry, &SystemEntry::isValidChanged, m_favoritesModel, &AbstractModel::refresh); + } } SystemModel::~SystemModel() { - qDeleteAll(m_entryList); -} - -void SystemModel::init() -{ - QList actions; - - actions << new SystemEntry(this, SystemEntry::LockSession); - actions << new SystemEntry(this, SystemEntry::LogoutSession); - actions << new SystemEntry(this, SystemEntry::SaveSession); - actions << new SystemEntry(this, SystemEntry::SwitchUser); - actions << new SystemEntry(this, SystemEntry::SuspendToRam); - actions << new SystemEntry(this, SystemEntry::SuspendToDisk); - actions << new SystemEntry(this, SystemEntry::Reboot); - actions << new SystemEntry(this, SystemEntry::Shutdown); - - foreach(SystemEntry *entry, actions) { - if (entry->isValid()) { - m_entryList << entry; - } else { - delete entry; - } - } + qDeleteAll(m_entries); } QString SystemModel::description() const @@ -77,11 +63,11 @@ QString SystemModel::description() const QVariant SystemModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= m_entryList.count()) { + if (!index.isValid() || index.row() >= m_entries.count()) { return QVariant(); } - const SystemEntry *entry = m_entryList.at(index.row()); + const SystemEntry *entry = m_entries.value(static_cast(index.row() + 1)); if (role == Qt::DisplayRole) { return entry->name(); @@ -97,6 +83,8 @@ QVariant SystemModel::data(const QModelIndex &index, int role) const return entry->hasActions(); } else if (role == Kicker::ActionListRole) { return entry->actions(); + } else if (role == Kicker::DisabledRole) { + return !entry->isValid(); } return QVariant(); @@ -104,13 +92,13 @@ QVariant SystemModel::data(const QModelIndex &index, int role) const int SystemModel::rowCount(const QModelIndex &parent) const { - return parent.isValid() ? 0 : m_entryList.count(); + return parent.isValid() ? 0 : m_entries.count(); } bool SystemModel::trigger(int row, const QString &actionId, const QVariant &argument) { - if (row >= 0 && row < m_entryList.count()) { - m_entryList.at(row)->run(actionId, argument); + if (row >= 0 && row < m_entries.count()) { + m_entries.value(static_cast(row + 1))->run(actionId, argument); return true; } @@ -120,16 +108,5 @@ bool SystemModel::trigger(int row, const QString &actionId, const QVariant &argu void SystemModel::refresh() { - beginResetModel(); - - qDeleteAll(m_entryList); - m_entryList.clear(); - - init(); - - endResetModel(); - - emit countChanged(); - m_favoritesModel->refresh(); } diff --git a/applets/kicker/plugin/systemmodel.h b/applets/kicker/plugin/systemmodel.h index 56baef2dc..cab1f2fd8 100644 --- a/applets/kicker/plugin/systemmodel.h +++ b/applets/kicker/plugin/systemmodel.h @@ -21,8 +21,7 @@ #define SYSTEMMODEL_H #include "abstractmodel.h" - -class SystemEntry; +#include "systementry.h" class SystemModel : public AbstractModel { @@ -44,9 +43,7 @@ class SystemModel : public AbstractModel void refresh() override; private: - void init(); - - QList m_entryList; + QHash m_entries; }; #endif -- GitLab