diff --git a/applets/kicker/CMakeLists.txt b/applets/kicker/CMakeLists.txt --- a/applets/kicker/CMakeLists.txt +++ b/applets/kicker/CMakeLists.txt @@ -60,7 +60,6 @@ target_link_libraries(kickerplugin Qt5::Core - Qt5::DBus Qt5::Qml Qt5::Quick Qt5::X11Extras @@ -78,7 +77,6 @@ KF5::PlasmaQuick KF5::Runner KF5::Service - KF5::Solid KF5::WindowSystem PW::KWorkspace) diff --git a/applets/kicker/package/contents/ui/ItemGridDelegate.qml b/applets/kicker/package/contents/ui/ItemGridDelegate.qml --- a/applets/kicker/package/contents/ui/ItemGridDelegate.qml +++ b/applets/kicker/package/contents/ui/ItemGridDelegate.qml @@ -30,6 +30,8 @@ width: GridView.view.cellWidth height: width + enabled: !model.disabled + property bool showLabel: true property int itemIndex: model.index diff --git a/applets/kicker/package/contents/ui/ItemListDelegate.qml b/applets/kicker/package/contents/ui/ItemListDelegate.qml --- a/applets/kicker/package/contents/ui/ItemListDelegate.qml +++ b/applets/kicker/package/contents/ui/ItemListDelegate.qml @@ -30,7 +30,7 @@ height: isSeparator ? separatorHeight : itemHeight width: ListView.view.width - enabled: !isSeparator + enabled: !isSeparator && !model.disabled && (!isParent || (isParent && hasChildren)) signal actionTriggered(string actionId, variant actionArgument) signal aboutToShowActionMenu(variant actionMenu) @@ -211,8 +211,6 @@ PlasmaComponents.Label { id: label - enabled: !isParent || (isParent && hasChildren) - anchors.verticalCenter: parent.verticalCenter width: parent.width - icon.width - arrow.width - parent.actualSpacing diff --git a/applets/kicker/plugin/abstractmodel.cpp b/applets/kicker/plugin/abstractmodel.cpp --- a/applets/kicker/plugin/abstractmodel.cpp +++ b/applets/kicker/plugin/abstractmodel.cpp @@ -44,6 +44,7 @@ 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 --- a/applets/kicker/plugin/actionlist.h +++ b/applets/kicker/plugin/actionlist.h @@ -40,7 +40,8 @@ HasChildrenRole, HasActionListRole, ActionListRole, - UrlRole + UrlRole, + DisabledRole }; QVariantMap createActionItem(const QString &label, const QString &actionId, const QVariant &argument = QVariant()); diff --git a/applets/kicker/plugin/systementry.h b/applets/kicker/plugin/systementry.h --- a/applets/kicker/plugin/systementry.h +++ b/applets/kicker/plugin/systementry.h @@ -22,24 +22,33 @@ #include "abstractentry.h" -class SystemEntry : public AbstractEntry +#include + +class SessionManagement; + +class SystemEntry : public QObject, public AbstractEntry { + Q_OBJECT + public: enum Action { NoAction = 0, LockSession, 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 @@ 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/systementry.cpp b/applets/kicker/plugin/systementry.cpp --- a/applets/kicker/plugin/systementry.cpp +++ b/applets/kicker/plugin/systementry.cpp @@ -19,29 +19,31 @@ #include "systementry.h" -#include -#include -#include - -#include -#include #include -#include -#include -#include -#include "ksmserver_interface.h" -#include - -SystemEntry::SystemEntry(AbstractModel *owner, Action action) : AbstractEntry(owner) -, m_action(action) -, m_valid(false) + +#include "sessionmanagement.h" + +int SystemEntry::s_instanceCount = 0; +SessionManagement* SystemEntry::s_sessionManagement = nullptr; + +SystemEntry::SystemEntry(AbstractModel *owner, Action action) + : QObject() + , AbstractEntry(owner) + , m_initialized(false) + , m_action(action) + , m_valid(false) { - init(); + refresh(); + ++s_instanceCount; + m_initialized = true; } -SystemEntry::SystemEntry(AbstractModel *owner, const QString &id) : AbstractEntry(owner) -, m_action(NoAction) -, m_valid(false) +SystemEntry::SystemEntry(AbstractModel *owner, const QString &id) + : QObject() + , AbstractEntry(owner) + , m_initialized(false) + , m_action(NoAction) + , m_valid(false) { if (id == QLatin1String("lock-screen")) { m_action = LockSession; @@ -52,60 +54,103 @@ } 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; + } +} - m_valid = authorize && c.readEntry("loginMode") == QLatin1String("restoreSavedSession"); - } else { - m_valid = authorize; - } +SystemEntry::Action SystemEntry::action() const +{ + return m_action; +} +void SystemEntry::refresh() +{ + if (!s_sessionManagement) { + s_sessionManagement = new SessionManagement(); + } + + 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 SaveSession: { + valid = s_sessionManagement->canSaveSession(); + QObject::connect(s_sessionManagement, &SessionManagement::canSaveSessionChanged, + this, &SystemEntry::refresh); break; - case SuspendToRam: - m_valid = Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::SuspendState); + } + case SwitchUser: { + valid = s_sessionManagement->canSwitchUser(); + QObject::connect(s_sessionManagement, &SessionManagement::canSwitchUserChanged, + this, &SystemEntry::refresh); break; - case SuspendToDisk: - m_valid = Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::HibernateState); + } + case Suspend: { + valid = s_sessionManagement->canSuspend(); + QObject::connect(s_sessionManagement, &SessionManagement::canSuspendChanged, + this, &SystemEntry::refresh); break; - case Reboot: - m_valid = KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot); + } + case Hibernate: { + valid = s_sessionManagement->canHibernate(); + QObject::connect(s_sessionManagement, &SessionManagement::canHibernateChanged, + this, &SystemEntry::refresh); break; - case Shutdown: - m_valid = KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt); + } + 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 +185,10 @@ 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 +219,10 @@ 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 +253,10 @@ 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 +287,10 @@ 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 +321,10 @@ 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 +346,20 @@ 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/systemmodel.h b/applets/kicker/plugin/systemmodel.h --- 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 @@ void refresh() override; private: - void init(); - - QList m_entryList; + QHash m_entries; }; #endif diff --git a/applets/kicker/plugin/systemmodel.cpp b/applets/kicker/plugin/systemmodel.cpp --- a/applets/kicker/plugin/systemmodel.cpp +++ b/applets/kicker/plugin/systemmodel.cpp @@ -20,54 +20,40 @@ #include "systemmodel.h" #include "actionlist.h" #include "simplefavoritesmodel.h" -#include "systementry.h" #include #include #include 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 @@ 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,20 +83,22 @@ return entry->hasActions(); } else if (role == Kicker::ActionListRole) { return entry->actions(); + } else if (role == Kicker::DisabledRole) { + return !entry->isValid(); } return QVariant(); } 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 @@ void SystemModel::refresh() { - beginResetModel(); - - qDeleteAll(m_entryList); - m_entryList.clear(); - - init(); - - endResetModel(); - - emit countChanged(); - m_favoritesModel->refresh(); } diff --git a/applets/kickoff/package/contents/ui/KickoffItem.qml b/applets/kickoff/package/contents/ui/KickoffItem.qml --- a/applets/kickoff/package/contents/ui/KickoffItem.qml +++ b/applets/kickoff/package/contents/ui/KickoffItem.qml @@ -28,6 +28,8 @@ Item { id: listItem + enabed: !model.disabled + width: ListView.view.width height: (units.smallSpacing * 2) + Math.max(elementIcon.height, titleElement.implicitHeight + subTitleElement.implicitHeight)