diff --git a/containmentactions/contextmenu/menu.cpp b/containmentactions/contextmenu/menu.cpp index ad33bb3e2..50b059835 100644 --- a/containmentactions/contextmenu/menu.cpp +++ b/containmentactions/contextmenu/menu.cpp @@ -1,320 +1,299 @@ /* * Copyright 2009 by Chani Armitage * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "menu.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "kworkspace.h" +#include #include "krunner_interface.h" -#include "screensaver_interface.h" - -#ifdef Q_OS_WIN -#define _WIN32_WINNT 0x0500 // require NT 5.0 (win 2k pro) -#include -#endif // Q_OS_WIN ContextMenu::ContextMenu(QObject *parent, const QVariantList &args) : Plasma::ContainmentActions(parent, args), m_runCommandAction(nullptr), m_lockScreenAction(nullptr), m_logoutAction(nullptr), m_separator1(nullptr), m_separator2(nullptr), m_separator3(nullptr), - m_buttons(nullptr) + m_buttons(nullptr), + m_session(new SessionManagement(this)) { } ContextMenu::~ContextMenu() { } void ContextMenu::restore(const KConfigGroup &config) { Plasma::Containment *c = containment(); Q_ASSERT(c); m_actions.clear(); m_actionOrder.clear(); QHash actions; QSet disabled; if (c->containmentType() == Plasma::Types::PanelContainment || c->containmentType() == Plasma::Types::CustomPanelContainment) { m_actionOrder << QStringLiteral("add widgets") << QStringLiteral("_add panel") << QStringLiteral("lock widgets") << QStringLiteral("_context") << QStringLiteral("configure") << QStringLiteral("remove"); } else { actions.insert(QStringLiteral("configure shortcuts"), false); m_actionOrder << QStringLiteral("_context") << QStringLiteral("_run_command") << QStringLiteral("add widgets") << QStringLiteral("_add panel") << QStringLiteral("manage activities") << QStringLiteral("remove") << QStringLiteral("lock widgets") << QStringLiteral("edit mode") << QStringLiteral("_sep1") < it(actions); while (it.hasNext()) { it.next(); m_actions.insert(it.key(), config.readEntry(it.key(), it.value())); } // everything below should only happen once, so check for it if (!m_runCommandAction) { m_runCommandAction = new QAction(i18nc("plasma_containmentactions_contextmenu", "Show KRunner"), this); m_runCommandAction->setIcon(QIcon::fromTheme(QStringLiteral("plasma-search"))); m_runCommandAction->setShortcut(KGlobalAccel::self()->globalShortcut(QStringLiteral("krunner.desktop"), QStringLiteral("_launch")).value(0)); connect(m_runCommandAction, &QAction::triggered, this, &ContextMenu::runCommand); m_lockScreenAction = new QAction(i18nc("plasma_containmentactions_contextmenu", "Lock Screen"), this); m_lockScreenAction->setIcon(QIcon::fromTheme(QStringLiteral("system-lock-screen"))); m_lockScreenAction->setShortcut(KGlobalAccel::self()->globalShortcut(QStringLiteral("ksmserver"), QStringLiteral("Lock Session")).value(0)); - connect(m_lockScreenAction, &QAction::triggered, this, &ContextMenu::lockScreen); + m_lockScreenAction->setEnabled(m_session->canLock()); + connect(m_session, &SessionManagement::canLockChanged, this, [this]() { + m_lockScreenAction->setEnabled(m_session->canLock()); + }); + connect(m_lockScreenAction, &QAction::triggered, m_session, &SessionManagement::lock); + m_logoutAction = new QAction(i18nc("plasma_containmentactions_contextmenu", "Leave..."), this); m_logoutAction->setIcon(QIcon::fromTheme(QStringLiteral("system-log-out"))); m_logoutAction->setShortcut(KGlobalAccel::self()->globalShortcut(QStringLiteral("ksmserver"), QStringLiteral("Log Out")).value(0)); + m_logoutAction->setEnabled(m_session->canLogout()); + connect(m_session, &SessionManagement::canLogoutChanged, this, [this]() { + m_logoutAction->setEnabled(m_session->canLogout()); + }); connect(m_logoutAction, &QAction::triggered, this, &ContextMenu::startLogout); m_separator1 = new QAction(this); m_separator1->setSeparator(true); m_separator2 = new QAction(this); m_separator2->setSeparator(true); m_separator3 = new QAction(this); m_separator3->setSeparator(true); } } QList ContextMenu::contextualActions() { Plasma::Containment *c = containment(); Q_ASSERT(c); QList actions; foreach (const QString &name, m_actionOrder) { if (!m_actions.value(name)) { continue; } if (name == QLatin1String("_context")) { actions << c->contextualActions(); } if (name == QLatin1String("_wallpaper")) { if (!c->wallpaper().isEmpty()) { QObject *wallpaperGraphicsObject = c->property("wallpaperGraphicsObject").value(); if (wallpaperGraphicsObject) { actions << wallpaperGraphicsObject->property("contextualActions").value >(); } } } else if (QAction *a = action(name)) { // Bug 364292: show "Remove this Panel" option only when panelcontroller is opened if (name != QLatin1String("remove") || c->isUserConfiguring() || (c->containmentType() != Plasma::Types::PanelContainment && c->containmentType() != Plasma::Types::CustomPanelContainment)) { if (name != QLatin1String("lock widgets") || c->corona()->immutability() != Plasma::Types::Mutable) { actions << a; } } } } return actions; } QAction *ContextMenu::action(const QString &name) { Plasma::Containment *c = containment(); Q_ASSERT(c); if (name == QLatin1String("_sep1")) { return m_separator1; } else if (name == QLatin1String("_sep2")) { return m_separator2; } else if (name == QLatin1String("_sep3")) { return m_separator3; } else if (name == QLatin1String("_add panel")) { if (c->corona() && c->corona()->immutability() == Plasma::Types::Mutable) { return c->corona()->actions()->action(QStringLiteral("add panel")); } } else if (name == QLatin1String("_run_command")) { if (KAuthorized::authorizeAction(QStringLiteral("run_command")) && KAuthorized::authorize(QStringLiteral("run_command"))) { return m_runCommandAction; } } else if (name == QLatin1String("_lock_screen")) { if (KAuthorized::authorizeAction(QStringLiteral("lock_screen"))) { return m_lockScreenAction; } } else if (name == QLatin1String("_logout")) { if (KAuthorized::authorize(QStringLiteral("logout"))) { return m_logoutAction; } } else if (name == QLatin1String("lock widgets")) { if (c->corona()) { return c->corona()->actions()->action(QStringLiteral("lock widgets")); } } else if (name == QLatin1String("edit mode")) { if (c->corona()) { return c->corona()->actions()->action(QStringLiteral("edit mode")); } } else if (name == QLatin1String("manage activities")) { if (c->corona()) { return c->corona()->actions()->action(QStringLiteral("manage activities")); } } else { //FIXME: remove action: make removal of current activity possible return c->actions()->action(name); } return nullptr; } void ContextMenu::runCommand() { if (!KAuthorized::authorizeAction(QStringLiteral("run_command"))) { return; } QString interface(QStringLiteral("org.kde.krunner")); org::kde::krunner::App krunner(interface, QStringLiteral("/App"), QDBusConnection::sessionBus()); krunner.display(); } -void ContextMenu::lockScreen() -{ - if (!KAuthorized::authorizeAction(QStringLiteral("lock_screen"))) { - return; - } - -#ifndef Q_OS_WIN - QString interface(QStringLiteral("org.freedesktop.ScreenSaver")); - org::freedesktop::ScreenSaver screensaver(interface, QStringLiteral("/ScreenSaver"), - QDBusConnection::sessionBus()); - if (screensaver.isValid()) { - screensaver.Lock(); - } -#else - LockWorkStation(); -#endif // !Q_OS_WIN -} - void ContextMenu::startLogout() { - // this short delay is due to two issues: - // a) KWorkSpace's DBus alls are all synchronous - // b) the destruction of the menu that this action is in is delayed - // - // (a) leads to the menu hanging out where everyone can see it because - // the even loop doesn't get returned to allowing it to close. - // - // (b) leads to a 0ms timer not working since a 0ms timer just appends to - // the event queue, and then the menu closing event gets appended to that. - // - // ergo a timer with small timeout - QTimer::singleShot(10, this, &ContextMenu::logout); -} - -void ContextMenu::logout() -{ - if (!KAuthorized::authorizeAction(QStringLiteral("logout"))) { - return; + KConfig config(QStringLiteral("ksmserverrc")); + const auto group = config.group("General"); + switch (group.readEntry("shutdownType", int(KWorkSpace::ShutdownTypeNone))) { + case int(KWorkSpace::ShutdownTypeHalt): + m_session->requestShutdown(); + break; + case int(KWorkSpace::ShutdownTypeReboot): + m_session->requestReboot(); + break; + default: + m_session->requestLogout(); + break; } - - KWorkSpace::requestShutDown(); } QWidget* ContextMenu::createConfigurationInterface(QWidget* parent) { QWidget *widget = new QWidget(parent); QVBoxLayout *lay = new QVBoxLayout(); widget->setLayout(lay); widget->setWindowTitle(i18nc("plasma_containmentactions_contextmenu", "Configure Contextual Menu Plugin")); m_buttons = new QButtonGroup(widget); m_buttons->setExclusive(false); foreach (const QString &name, m_actionOrder) { QCheckBox *item = nullptr; if (name == QLatin1String("_context")) { item = new QCheckBox(widget); //FIXME better text item->setText(i18nc("plasma_containmentactions_contextmenu", "[Other Actions]")); } else if (name == QLatin1String("_wallpaper")) { item = new QCheckBox(widget); item->setText(i18nc("plasma_containmentactions_contextmenu", "Wallpaper Actions")); item->setIcon(QIcon::fromTheme(QStringLiteral("user-desktop"))); } else if (name == QLatin1String("_sep1") || name ==QLatin1String("_sep2") || name == QLatin1String("_sep3")) { item = new QCheckBox(widget); item->setText(i18nc("plasma_containmentactions_contextmenu", "[Separator]")); } else { QAction *a = action(name); if (a) { item = new QCheckBox(widget); item->setText(a->text()); item->setIcon(a->icon()); } } if (item) { item->setChecked(m_actions.value(name)); item->setProperty("actionName", name); lay->addWidget(item); m_buttons->addButton(item); } } return widget; } void ContextMenu::configurationAccepted() { QList buttons = m_buttons->buttons(); QListIterator it(buttons); while (it.hasNext()) { QAbstractButton *b = it.next(); if (b) { m_actions.insert(b->property("actionName").toString(), b->isChecked()); } } } void ContextMenu::save(KConfigGroup &config) { QHashIterator it(m_actions); while (it.hasNext()) { it.next(); config.writeEntry(it.key(), it.value()); } } K_EXPORT_PLASMA_CONTAINMENTACTIONS_WITH_JSON(contextmenu, ContextMenu, "plasma-containmentactions-contextmenu.json") #include "menu.moc" diff --git a/containmentactions/contextmenu/menu.h b/containmentactions/contextmenu/menu.h index 2b0bbe4b0..813ff380e 100644 --- a/containmentactions/contextmenu/menu.h +++ b/containmentactions/contextmenu/menu.h @@ -1,62 +1,63 @@ /* * Copyright 2009 by Chani Armitage * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CONTEXTMENU_HEADER #define CONTEXTMENU_HEADER #include #include +class SessionManagement; + class ContextMenu : public Plasma::ContainmentActions { Q_OBJECT public: ContextMenu(QObject* parent, const QVariantList& args); ~ContextMenu() override; void restore(const KConfigGroup&) override; QList contextualActions() override; QAction* action(const QString &name); QWidget* createConfigurationInterface(QWidget* parent) override; void configurationAccepted() override; void save(KConfigGroup &config) override; public Q_SLOTS: void runCommand(); - void lockScreen(); void startLogout(); - void logout(); private: QAction *m_runCommandAction; QAction *m_lockScreenAction; QAction *m_logoutAction; QAction *m_separator1; QAction *m_separator2; QAction *m_separator3; // action name and whether it is enabled or not QHash m_actions; QStringList m_actionOrder; QButtonGroup *m_buttons; + SessionManagement *m_session; }; #endif diff --git a/dataengines/powermanagement/powermanagementjob.cpp b/dataengines/powermanagement/powermanagementjob.cpp index 0cc57f6a8..cfc2bfc06 100644 --- a/dataengines/powermanagement/powermanagementjob.cpp +++ b/dataengines/powermanagement/powermanagementjob.cpp @@ -1,142 +1,152 @@ /* * Copyright 2011 Sebastian Kügler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as * published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include // kde-workspace/libs -#include +#include #include #include "powermanagementjob.h" #include -PowerManagementJob::PowerManagementJob(const QString &operation, QMap ¶meters, QObject *parent) : - ServiceJob(parent->objectName(), operation, parameters, parent) +PowerManagementJob::PowerManagementJob(const QString &operation, QMap ¶meters, QObject *parent) + : ServiceJob(parent->objectName(), operation, parameters, parent) + , m_session(new SessionManagement(this)) { } PowerManagementJob::~PowerManagementJob() { } static void callWhenFinished(const QDBusPendingCall& pending, std::function func, QObject* parent) { QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(pending, parent); QObject::connect(watcher, &QDBusPendingCallWatcher::finished, parent, [func](QDBusPendingCallWatcher* watcher) { watcher->deleteLater(); func(); }); } void PowerManagementJob::start() { const QString operation = operationName(); //qDebug() << "starting operation ... " << operation; if (operation == QLatin1String("lockScreen")) { - if (KAuthorized::authorizeAction(QStringLiteral("lock_screen"))) { - const QString interface(QStringLiteral("org.freedesktop.ScreenSaver")); - QDBusInterface screensaver(interface, QStringLiteral("/ScreenSaver")); - screensaver.asyncCall(QStringLiteral("Lock")); + if (m_session->canLock()) { + m_session->lock(); setResult(true); return; } qDebug() << "operation denied " << operation; setResult(false); return; } else if (operation == QLatin1String("suspend") || operation == QLatin1String("suspendToRam")) { - Solid::PowerManagement::requestSleep(Solid::PowerManagement::SuspendState, nullptr, nullptr); - setResult(Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::SuspendState)); + if (m_session->canSuspend()) { + m_session->suspend(); + setResult(true); + } else { + setResult(false); + } return; } else if (operation == QLatin1String("suspendToDisk")) { - Solid::PowerManagement::requestSleep(Solid::PowerManagement::HibernateState, nullptr, nullptr); - setResult(Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::HibernateState)); + if (m_session->canHibernate()) { + m_session->hibernate(); + setResult(true); + } else { + setResult(false); + } return; } else if (operation == QLatin1String("suspendHybrid")) { - Solid::PowerManagement::requestSleep(Solid::PowerManagement::HybridSuspendState, nullptr, nullptr); - setResult(Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::HybridSuspendState)); + if (m_session->canHybridSuspend()) { + m_session->hybridSuspend(); + setResult(true); + } else { + setResult(false); + } return; } else if (operation == QLatin1String("requestShutDown")) { - requestShutDown(); - setResult(true); + if (m_session->canShutdown()) { + m_session->requestShutdown(); + setResult(true); + } else { + setResult(false); + } return; } else if (operation == QLatin1String("switchUser")) { - // Taken from kickoff/core/itemhandlers.cpp - org::kde::krunner::App krunner(QStringLiteral("org.kde.krunner"), QStringLiteral("/App"), QDBusConnection::sessionBus()); - krunner.switchUser(); - setResult(true); + if (m_session->canSwitchUser()) { + m_session->switchUser(); + setResult(true); + } + setResult(false); return; } else if (operation == QLatin1String("beginSuppressingSleep")) { setResult(Solid::PowerManagement::beginSuppressingSleep(parameters().value(QStringLiteral("reason")).toString())); return; } else if (operation == QLatin1String("stopSuppressingSleep")) { setResult(Solid::PowerManagement::stopSuppressingSleep(parameters().value(QStringLiteral("cookie")).toInt())); return; } else if (operation == QLatin1String("beginSuppressingScreenPowerManagement")) { setResult(Solid::PowerManagement::beginSuppressingScreenPowerManagement(parameters().value(QStringLiteral("reason")).toString())); return; } else if (operation == QLatin1String("stopSuppressingScreenPowerManagement")) { setResult(Solid::PowerManagement::stopSuppressingScreenPowerManagement(parameters().value(QStringLiteral("cookie")).toInt())); return; } else if (operation == QLatin1String("setBrightness")) { auto pending = setScreenBrightness(parameters().value(QStringLiteral("brightness")).toInt(), parameters().value(QStringLiteral("silent")).toBool()); callWhenFinished(pending, [this] { setResult(true); }, this); return; } else if (operation == QLatin1String("setKeyboardBrightness")) { auto pending = setKeyboardBrightness(parameters().value(QStringLiteral("brightness")).toInt(), parameters().value(QStringLiteral("silent")).toBool()); callWhenFinished(pending, [this] { setResult(true); }, this); return; } qDebug() << "don't know what to do with " << operation; setResult(false); } QDBusPendingCall PowerManagementJob::setScreenBrightness(int value, bool silent) { QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"), QStringLiteral("org.kde.Solid.PowerManagement.Actions.BrightnessControl"), silent ? "setBrightnessSilent" : "setBrightness"); msg << value; return QDBusConnection::sessionBus().asyncCall(msg); } QDBusPendingCall PowerManagementJob::setKeyboardBrightness(int value, bool silent) { QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl"), QStringLiteral("org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl"), silent ? "setKeyboardBrightnessSilent" : "setKeyboardBrightness"); msg << value; return QDBusConnection::sessionBus().asyncCall(msg); } - -void PowerManagementJob::requestShutDown() -{ - KWorkSpace::requestShutDown(); -} - diff --git a/dataengines/powermanagement/powermanagementjob.h b/dataengines/powermanagement/powermanagementjob.h index a2cf8308f..5bebdc608 100644 --- a/dataengines/powermanagement/powermanagementjob.h +++ b/dataengines/powermanagement/powermanagementjob.h @@ -1,45 +1,46 @@ /* * Copyright 2011 Sebastian Kügler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as * published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef POWERMANAGEMENTJOB_H #define POWERMANAGEMENTJOB_H // plasma #include +class SessionManagement; class QDBusPendingCall; class PowerManagementJob : public Plasma::ServiceJob { Q_OBJECT public: PowerManagementJob(const QString &operation, QMap ¶meters, QObject *parent = nullptr); ~PowerManagementJob() override; protected: void start() override; private: - void requestShutDown(); QDBusPendingCall setScreenBrightness(int value, bool silent); QDBusPendingCall setKeyboardBrightness(int value, bool silent); + SessionManagement *m_session; }; #endif // POWERMANAGEMENTJOB_H diff --git a/runners/sessions/sessionrunner.cpp b/runners/sessions/sessionrunner.cpp index 43e6ba6ca..44864de4e 100644 --- a/runners/sessions/sessionrunner.cpp +++ b/runners/sessions/sessionrunner.cpp @@ -1,280 +1,261 @@ /* * Copyright (C) 2006 Aaron Seigo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as * published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "sessionrunner.h" - #include #include #include #include #include "kworkspace.h" #include "screensaver_interface.h" K_EXPORT_PLASMA_RUNNER(calculatorrunner, SessionRunner) SessionRunner::SessionRunner(QObject *parent, const QVariantList &args) : Plasma::AbstractRunner(parent, args) { setObjectName( QLatin1String("Sessions" )); setPriority(LowPriority); setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | Plasma::RunnerContext::NetworkLocation); m_canLogout = KAuthorized::authorizeAction(QStringLiteral("logout")) && KAuthorized::authorize(QStringLiteral("logout")); if (m_canLogout) { addSyntax(Plasma::RunnerSyntax(i18nc("log out command", "logout"), i18n("Logs out, exiting the current desktop session"))); addSyntax(Plasma::RunnerSyntax(i18nc("shut down computer command", "shut down"), i18n("Turns off the computer"))); } if (KAuthorized::authorizeAction(QStringLiteral("lock_screen")) && m_canLogout) { addSyntax(Plasma::RunnerSyntax(i18nc("lock screen command", "lock"), i18n("Locks the current sessions and starts the screen saver"))); } Plasma::RunnerSyntax rebootSyntax(i18nc("restart computer command", "restart"), i18n("Reboots the computer")); rebootSyntax.addExampleQuery(i18nc("restart computer command", "reboot")); addSyntax(rebootSyntax); m_triggerWord = i18nc("switch user command", "switch"); addSyntax(Plasma::RunnerSyntax(i18nc("switch user command", "switch :q:"), i18n("Switches to the active session for the user :q:, " "or lists all active sessions if :q: is not provided"))); Plasma::RunnerSyntax fastUserSwitchSyntax(i18n("switch user"), i18n("Starts a new session as a different user")); fastUserSwitchSyntax.addExampleQuery(i18n("new session")); addSyntax(fastUserSwitchSyntax); //"SESSIONS" should not be translated; it's used programmaticaly setDefaultSyntax(Plasma::RunnerSyntax(QStringLiteral("SESSIONS"), i18n("Lists all sessions"))); } SessionRunner::~SessionRunner() { } void SessionRunner::matchCommands(QList &matches, const QString& term) { if (!m_canLogout) { return; } if (term.compare(i18nc("log out command","logout"), Qt::CaseInsensitive) == 0 || term.compare(i18n("log out"), Qt::CaseInsensitive) == 0) { Plasma::QueryMatch match(this); match.setText(i18nc("log out command","Logout")); match.setIconName(QStringLiteral("system-log-out")); match.setData(LogoutAction); match.setType(Plasma::QueryMatch::ExactMatch); match.setRelevance(0.9); matches << match; } else if (term.compare(i18nc("restart computer command", "restart"), Qt::CaseInsensitive) == 0 || term.compare(i18nc("restart computer command", "reboot"), Qt::CaseInsensitive) == 0) { Plasma::QueryMatch match(this); match.setText(i18n("Restart the computer")); match.setIconName(QStringLiteral("system-reboot")); match.setData(RestartAction); match.setType(Plasma::QueryMatch::ExactMatch); match.setRelevance(0.9); matches << match; } else if (term.compare(i18nc("shut down computer command","shut down"), Qt::CaseInsensitive) == 0 || term.compare(i18nc("shut down computer command", "shutdown"), Qt::CaseInsensitive) == 0) { Plasma::QueryMatch match(this); match.setText(i18n("Shut down the computer")); match.setIconName(QStringLiteral("system-shutdown")); match.setData(ShutdownAction); match.setType(Plasma::QueryMatch::ExactMatch); match.setRelevance(0.9); matches << match; } else if (term.compare(i18nc("lock screen command","lock"), Qt::CaseInsensitive) == 0) { if (KAuthorized::authorizeAction(QStringLiteral("lock_screen"))) { Plasma::QueryMatch match(this); match.setText(i18n("Lock the screen")); match.setIconName(QStringLiteral("system-lock-screen")); match.setData(LockAction); match.setType(Plasma::QueryMatch::ExactMatch); match.setRelevance(0.9); matches << match; } } } void SessionRunner::match(Plasma::RunnerContext &context) { const QString term = context.query(); QString user; bool matchUser = false; QList matches; if (term.size() < 3) { return; } // first compare with SESSIONS. this must *NOT* be translated (i18n) // as it is used as an internal command trigger (e.g. via d-bus), // not as a user supplied query. and yes, "Ugh, magic strings" bool listAll = term.compare(QLatin1String("SESSIONS"), Qt::CaseInsensitive) == 0 || term.compare(i18nc("User sessions", "sessions"), Qt::CaseInsensitive) == 0; if (!listAll) { //no luck, try the "switch" user command if (term.startsWith(m_triggerWord, Qt::CaseInsensitive)) { user = term.right(term.size() - m_triggerWord.length()).trimmed(); listAll = user.isEmpty(); matchUser = !listAll; } else { // we know it's not SESSION or "switch ", so let's // try some other possibilities matchCommands(matches, term); } } bool switchUser = listAll || term.compare(i18n("switch user"), Qt::CaseInsensitive) == 0 || term.compare(i18n("new session"), Qt::CaseInsensitive) == 0; if (switchUser && KAuthorized::authorizeAction(QStringLiteral("start_new_session")) && dm.isSwitchable() && dm.numReserve() >= 0) { Plasma::QueryMatch match(this); match.setType(Plasma::QueryMatch::ExactMatch); match.setIconName(QStringLiteral("system-switch-user")); match.setText(i18n("New Session")); matches << match; } // now add the active sessions if (listAll || matchUser) { SessList sessions; dm.localSessions(sessions); for (const SessEnt& session : qAsConst(sessions)) { if (!session.vt || session.self) { continue; } QString name = KDisplayManager::sess2Str(session); Plasma::QueryMatch::Type type = Plasma::QueryMatch::NoMatch; qreal relevance = 0.7; if (listAll) { type = Plasma::QueryMatch::ExactMatch; relevance = 1; } else if (matchUser) { if (name.compare(user, Qt::CaseInsensitive) == 0) { // we need an elif branch here because we don't // want the last conditional to be checked if !listAll type = Plasma::QueryMatch::ExactMatch; relevance = 1; } else if (name.contains(user, Qt::CaseInsensitive)) { type = Plasma::QueryMatch::PossibleMatch; } } if (type != Plasma::QueryMatch::NoMatch) { Plasma::QueryMatch match(this); match.setType(type); match.setRelevance(relevance); match.setIconName(QStringLiteral("user-identity")); match.setText(name); match.setData(QString::number(session.vt)); matches << match; } } } context.addMatches(matches); } void SessionRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) { Q_UNUSED(context); if (match.data().type() == QVariant::Int) { - KWorkSpace::ShutdownType type = KWorkSpace::ShutdownTypeDefault; - switch (match.data().toInt()) { case LogoutAction: - type = KWorkSpace::ShutdownTypeNone; + m_session.requestLogout(); break; case RestartAction: - type = KWorkSpace::ShutdownTypeReboot; + m_session.requestReboot(); break; case ShutdownAction: - type = KWorkSpace::ShutdownTypeHalt; + m_session.requestShutdown(); break; case LockAction: - lock(); - return; + m_session.lock(); break; } - - if (type != KWorkSpace::ShutdownTypeDefault) { - KWorkSpace::ShutdownConfirm confirm = KWorkSpace::ShutdownConfirmDefault; - KWorkSpace::requestShutDown(confirm, type); - return; - } + return; } if (!match.data().toString().isEmpty()) { dm.lockSwitchVT(match.data().toString().toInt()); return; } //TODO: this message is too verbose and too technical. int result = QMessageBox::warning( nullptr, i18n("Warning - New Session"), i18n("

You have chosen to open another desktop session.
" "The current session will be hidden " "and a new login screen will be displayed.
" "An F-key is assigned to each session; " "F%1 is usually assigned to the first session, " "F%2 to the second session and so on. " "You can switch between sessions by pressing " "Ctrl, Alt and the appropriate F-key at the same time. " "Additionally, the KDE Panel and Desktop menus have " "actions for switching between sessions.

", 7, 8)); if (result == QMessageBox::Cancel) { return; } + m_session.lock(); - lock(); dm.startReserve(); } -void SessionRunner::lock() -{ - QString interface(QStringLiteral("org.freedesktop.ScreenSaver")); - org::freedesktop::ScreenSaver screensaver(interface, QStringLiteral("/ScreenSaver"), - QDBusConnection::sessionBus()); - if (screensaver.isValid()) { - screensaver.Lock(); - } -} - #include "sessionrunner.moc" diff --git a/runners/sessions/sessionrunner.h b/runners/sessions/sessionrunner.h index 763d2e7b7..a4d67b908 100644 --- a/runners/sessions/sessionrunner.h +++ b/runners/sessions/sessionrunner.h @@ -1,53 +1,54 @@ /* * Copyright (C) 2006 Aaron Seigo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as * published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SESSIONRUNNER_H #define SESSIONRUNNER_H #include #include +#include /** * This class provides matches for running sessions as well as * an action to start a new session, etc. */ class SessionRunner : public Plasma::AbstractRunner { Q_OBJECT public: SessionRunner(QObject *parent, const QVariantList &args); ~SessionRunner() override; void match(Plasma::RunnerContext &context) override; void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action) override; enum { LogoutAction = 1, ShutdownAction, RestartAction, LockAction }; private: - void lock(); void matchCommands(QList &matches, const QString& term); QString m_triggerWord; KDisplayManager dm; + SessionManagement m_session; bool m_canLogout; }; #endif