Projects
Eulaceura:Mainline
kiran-session-manager
_service:obs_scm:0001-feature-lockscreen-Add-Lo...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:0001-feature-lockscreen-Add-LockScreenWhenHibernate-and-L.patch of Package kiran-session-manager
From b6ac29d2838bedab513d6cdfb21084b95da0a70c Mon Sep 17 00:00:00 2001 From: tangjie02 <tangjie02@kylinsec.com.cn> Date: Tue, 9 May 2023 17:06:03 +0800 Subject: [PATCH] feature(lockscreen): Add LockScreenWhenHibernate and LockScreenWhenSuspend functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加当计算机休眠/待机时是否锁屏功能 Relates #68459 Signed-off-by: tangjie02 <tangjie02@kylinsec.com.cn> --- ...insec.kiran.session-manager.gschema.xml.in | 10 +++ data/org.gnome.SessionManager.xml | 40 +++++++++++ include/ksm-i.h | 12 ++-- lib/dbus/systemd-login1.cpp | 1 + src/core/power.cpp | 68 +++++++++++++++++-- src/core/power.h | 7 ++ src/core/presence.cpp | 3 - src/core/session-manager.cpp | 68 +++++++++++++++++++ src/core/session-manager.h | 15 ++++ 9 files changed, 210 insertions(+), 14 deletions(-) diff --git a/data/com.kylinsec.kiran.session-manager.gschema.xml.in b/data/com.kylinsec.kiran.session-manager.gschema.xml.in index 6d2b361..b71dd3e 100644 --- a/data/com.kylinsec.kiran.session-manager.gschema.xml.in +++ b/data/com.kylinsec.kiran.session-manager.gschema.xml.in @@ -5,6 +5,16 @@ <summary>Time before session is considered idle</summary> <description>The number of minutes of inactivity before the session is considered idle</description> </key> + + <key name="screen-locked-when-suspend" type="b"> + <default>true</default> + <description>Whether lock screen when the computer is suspend.</description> + </key> + + <key name="screen-locked-when-hibernate" type="b"> + <default>true</default> + <description>Whether lock screen when the computer is hibernate.</description> + </key> </schema> </schemalist> diff --git a/data/org.gnome.SessionManager.xml b/data/org.gnome.SessionManager.xml index 9b4cec5..92ba554 100644 --- a/data/org.gnome.SessionManager.xml +++ b/data/org.gnome.SessionManager.xml @@ -72,6 +72,28 @@ <description>This gets a list of all the inhibitors that are currently known to the session manager.</description> </method> + <method name="Suspend"> + <description>Suspend computer.</description> + </method> + + <method name="CanSuspend"> + <arg name="is_available" direction="out" type="b"> + <summary>True if suspend is available to the user, false otherwise.</summary> + </arg> + <description>Whether the user can suspend.</description> + </method> + + <method name="Hibernate"> + <description>Hibernate computer.</description> + </method> + + <method name="CanHibernate"> + <arg name="is_available" direction="out" type="b"> + <summary>True if hibernate is available to the user, false otherwise.</summary> + </arg> + <description>Whether the user can hibernate.</description> + </method> + <method name="Shutdown"> <description>Shutdown the system.</description> </method> @@ -126,6 +148,14 @@ <description>Adds the variable name to the application launch environment with the specified value. May only be used during the Session Manager initialization phase.</description> </method> + <property name="ScreenLockedWhenSuspend" type="b" access="readwrite"> + <description>Whether lock screen when the computer is suspend.</description> + </property> + + <property name="ScreenLockedWhenHibernate" type="b" access="readwrite"> + <description>Whether lock screen when the computer is hibernate.</description> + </property> + <signal name="InhibitorAdded"> <arg name="cookie" type="u"> <summary>The inhibitor cookie.</summary> @@ -145,5 +175,15 @@ <description>The stage where session manager is in.</description> </signal> + <signal name="ScreenLockedWhenSuspendChanged"> + <arg name="screen_locked_when_suspend" type="b" /> + <description>Whether lock screen when the computer is suspend.</description> + </signal> + + <signal name="ScreenLockedWhenHibernateChanged"> + <arg name="screen_locked_when_hibernate" type="b" /> + <description>Whether lock screen when the computer is hibernate.</description> + </signal> + </interface> </node> diff --git a/include/ksm-i.h b/include/ksm-i.h index 71376dc..ca4bb86 100644 --- a/include/ksm-i.h +++ b/include/ksm-i.h @@ -21,6 +21,8 @@ extern "C" #define DESKTOP_ENVIRONMENT "KIRAN" +/* 为了保持跟第三方应用(firefox、pluma等)兼容,暂时还是使用gnome名字。 + 但后续版本有可能更名,所以最好使用宏定义,不要直接使用字符串常量。*/ #define KSM_DBUS_NAME "org.gnome.SessionManager" #define KSM_DBUS_OBJECT_PATH "/org/gnome/SessionManager" #define KSM_DBUS_INTERFACE_NAME "org.gnome.SessionManager" @@ -34,10 +36,12 @@ extern "C" #define KSM_IDLE_DBUS_OBJECT_PATH "/com/kylinsec/Kiran/SessionManager/IdleMonitor" #define KSM_SCHEMA_ID "com.kylinsec.kiran.session-manager" -#define KSM_SCHEMA_KEY_SESSION_DAEMONS "session-daemons" -#define KSM_SCHEMA_KEY_WINDOW_MANAGER "window-manager" -#define KSM_SCHEMA_KEY_PANEL "panel" -#define KSM_SCHEMA_KEY_FILE_MANAGER "file-manager" +// 计算机多久未操作视为空闲 +#define KSM_SCHEMA_KEY_IDLE_DELAY "idle-delay" +// 待机时是否锁定屏幕 +#define KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_SUSPEND "screen-locked-when-suspend" +// 休眠时是否锁定屏幕 +#define KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_HIBERNATE "screen-locked-when-hibernate" // JK: json key #define KSM_INHIBITOR_JK_COOKIE "cookie" diff --git a/lib/dbus/systemd-login1.cpp b/lib/dbus/systemd-login1.cpp index dea49e8..e2416a3 100644 --- a/lib/dbus/systemd-login1.cpp +++ b/lib/dbus/systemd-login1.cpp @@ -188,6 +188,7 @@ bool SystemdLogin1::canDoMethod(const QString &methodName) auto canResult = replyMessage.arguments().takeFirst().toString(); KLOG_DEBUG() << "Function " << methodName << " return " << canResult; + // TODO: 需要确认challenge状态是否可以执行电源动作 return (canResult == "yes" || canResult == "challenge"); } diff --git a/src/core/power.cpp b/src/core/power.cpp index 2bc3ac5..87200fb 100644 --- a/src/core/power.cpp +++ b/src/core/power.cpp @@ -13,6 +13,7 @@ */ #include "src/core/power.h" +#include <QGSettings> #include "lib/base/base.h" #include "lib/dbus/display-manager.h" #include "lib/dbus/screensaver.h" @@ -22,6 +23,7 @@ namespace Kiran { Power::Power(QObject *parent) : QObject(parent) { + this->m_settings = new QGSettings(KSM_SCHEMA_ID, "", this); } void Power::init() @@ -54,7 +56,7 @@ bool Power::canPowerAction(PowerAction powerAction) bool Power::doPowerAction(PowerAction powerAction) { - KLOG_DEBUG() << "Power action: " << powerAction; + KLOG_DEBUG() << "Do power action: " << this->powerActionEnum2Str(powerAction); switch (powerAction) { @@ -84,20 +86,50 @@ bool Power::switchUser() bool Power::suspend() { + uint32_t throttle = 0; + RETURN_VAL_IF_TRUE(!SystemdLogin1::getDefault()->canSuspend(), false); - // 这里忽略锁屏失败的情况 - ScreenSaver::getDefault()->lock(); - return SystemdLogin1::getDefault()->suspend(); + // 挂起之前判断是否锁定屏幕 + auto lockscreen = this->m_settings->get(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_SUSPEND).toBool(); + if (lockscreen) + { + throttle = ScreenSaver::getDefault()->lockAndThrottle("suspend"); + } + + auto retval = SystemdLogin1::getDefault()->suspend(); + + ScreenSaver::getDefault()->poke(); + if (throttle) + { + ScreenSaver::getDefault()->removeThrottle(throttle); + } + + return retval; } bool Power::hibernate() { + uint32_t throttle = 0; + RETURN_VAL_IF_TRUE(!SystemdLogin1::getDefault()->canHibernate(), false); - // 这里忽略锁屏失败的情况 - ScreenSaver::getDefault()->lock(); - return SystemdLogin1::getDefault()->hibernate(); + // 休眠之前判断是否锁定屏幕 + auto lockscreen = this->m_settings->get(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_HIBERNATE).toBool(); + if (lockscreen) + { + throttle = ScreenSaver::getDefault()->lockAndThrottle("hibernate"); + } + + auto retval = SystemdLogin1::getDefault()->hibernate(); + + ScreenSaver::getDefault()->poke(); + if (throttle) + { + ScreenSaver::getDefault()->removeThrottle(throttle); + } + + return retval; } bool Power::shutdown() @@ -112,4 +144,26 @@ bool Power::reboot() return SystemdLogin1::getDefault()->reboot(); } +QString Power::powerActionEnum2Str(PowerAction powerAction) +{ + switch (powerAction) + { + case PowerAction::POWER_ACTION_SWITCH_USER: + return "switch user"; + case PowerAction::POWER_ACTION_LOGOUT: + return "logout"; + case PowerAction::POWER_ACTION_SUSPEND: + return "suspend"; + case PowerAction::POWER_ACTION_HIBERNATE: + return "hibernate"; + case PowerAction::POWER_ACTION_SHUTDOWN: + return "shutdown"; + case PowerAction::POWER_ACTION_REBOOT: + return "reboot"; + default: + break; + } + return "unknown"; +} + } // namespace Kiran \ No newline at end of file diff --git a/src/core/power.h b/src/core/power.h index cbc2b21..14bcdda 100644 --- a/src/core/power.h +++ b/src/core/power.h @@ -17,6 +17,8 @@ #include <QObject> #include "ksm-i.h" +class QGSettings; + namespace Kiran { class Power : public QObject @@ -44,5 +46,10 @@ private: bool shutdown(); // 重启 bool reboot(); + + QString powerActionEnum2Str(PowerAction powerAction); + +private: + QGSettings *m_settings; }; } // namespace Kiran \ No newline at end of file diff --git a/src/core/presence.cpp b/src/core/presence.cpp index f41fa24..d7e73f3 100644 --- a/src/core/presence.cpp +++ b/src/core/presence.cpp @@ -22,9 +22,6 @@ namespace Kiran { -#define KSM_SCHEMA_ID "com.kylinsec.kiran.session-manager" -#define KSM_SCHEMA_KEY_IDLE_DELAY "idleDelay" - Presence::Presence(QObject *parent) : QObject(parent), m_idleMonitorProxy(nullptr), m_enabledIdleTimeout(true), diff --git a/src/core/session-manager.cpp b/src/core/session-manager.cpp index 1f33db7..12dcc15 100644 --- a/src/core/session-manager.cpp +++ b/src/core/session-manager.cpp @@ -73,6 +73,39 @@ void SessionManager::start() this->processPhase(); } +bool SessionManager::screenLockedWhenHibernate() +{ + return this->m_settings->get(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_HIBERNATE).toBool(); +} + +void SessionManager::setScreenLockedWhenHibernate(bool screenLockedWhenHibernate) +{ + if (screenLockedWhenHibernate != this->screenLockedWhenHibernate()) + { + this->m_settings->set(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_HIBERNATE, screenLockedWhenHibernate); + Q_EMIT this->ScreenLockedWhenHibernateChanged(screenLockedWhenHibernate); + } +} + +bool SessionManager::screenLockedWhenSuspend() +{ + return this->m_settings->get(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_SUSPEND).toBool(); +} + +void SessionManager::setScreenLockedWhenSuspend(bool screenLockedWhenSuspend) +{ + if (screenLockedWhenSuspend != this->screenLockedWhenSuspend()) + { + this->m_settings->set(KSM_SCHEMA_KEY_SCREEN_LOCKED_WHEN_SUSPEND, screenLockedWhenSuspend); + Q_EMIT this->ScreenLockedWhenSuspendChanged(screenLockedWhenSuspend); + } +} + +bool SessionManager::CanHibernate() +{ + return this->m_power->canPowerAction(PowerAction::POWER_ACTION_HIBERNATE); +} + bool SessionManager::CanLogout() { return true; @@ -88,6 +121,11 @@ bool SessionManager::CanShutdown() return this->m_power->canPowerAction(PowerAction::POWER_ACTION_SHUTDOWN); } +bool SessionManager::CanSuspend() +{ + return this->m_power->canPowerAction(PowerAction::POWER_ACTION_SUSPEND); +} + QString SessionManager::GetInhibitor(uint cookie) { QJsonDocument jsonDoc; @@ -133,6 +171,21 @@ QString SessionManager::GetInhibitors() return QString(jsonDoc.toJson()); } +void SessionManager::Hibernate() +{ + if (this->m_currentPhase > KSMPhase::KSM_PHASE_RUNNING) + { + DBUS_ERROR_REPLY_AND_RET(QDBusError::InvalidArgs, KSMErrorCode::ERROR_MANAGER_PHASE_INVALID); + } + + if (!this->m_power->canPowerAction(PowerAction::POWER_ACTION_HIBERNATE)) + { + DBUS_ERROR_REPLY_AND_RET(QDBusError::AccessDenied, KSMErrorCode::ERROR_MANAGER_POWER_ACTION_UNSUPPORTED); + } + + this->m_power->doPowerAction(PowerAction::POWER_ACTION_HIBERNATE); +} + uint SessionManager::SessionManager::Inhibit(const QString &appID, uint toplevelXID, const QString &reason, @@ -246,6 +299,21 @@ void SessionManager::Shutdown() this->startNextPhase(); } +void SessionManager::Suspend() +{ + if (this->m_currentPhase > KSMPhase::KSM_PHASE_RUNNING) + { + DBUS_ERROR_REPLY_AND_RET(QDBusError::InvalidArgs, KSMErrorCode::ERROR_MANAGER_PHASE_INVALID); + } + + if (!this->m_power->canPowerAction(PowerAction::POWER_ACTION_SUSPEND)) + { + DBUS_ERROR_REPLY_AND_RET(QDBusError::AccessDenied, KSMErrorCode::ERROR_MANAGER_POWER_ACTION_UNSUPPORTED); + } + + this->m_power->doPowerAction(PowerAction::POWER_ACTION_SUSPEND); +} + void SessionManager::Uninhibit(uint inhibitCookie) { auto inhibitor = InhibitorManager::getInstance()->getInhibitor(inhibitCookie); diff --git a/src/core/session-manager.h b/src/core/session-manager.h index 8e6ffab..3d934e2 100644 --- a/src/core/session-manager.h +++ b/src/core/session-manager.h @@ -40,6 +40,9 @@ class SessionManager : public QObject, protected QDBusContext { Q_OBJECT + + Q_PROPERTY(bool ScreenLockedWhenHibernate READ screenLockedWhenHibernate WRITE setScreenLockedWhenHibernate) + Q_PROPERTY(bool ScreenLockedWhenSuspend READ screenLockedWhenSuspend WRITE setScreenLockedWhenSuspend) public: SessionManager(AppManager *appManager, ClientManager *clientManager, @@ -57,13 +60,22 @@ public: // 会话开始 void start(); + bool screenLockedWhenHibernate(); + void setScreenLockedWhenHibernate(bool screenLockedWhenHibernate); + + bool screenLockedWhenSuspend(); + void setScreenLockedWhenSuspend(bool screenLockedWhenSuspend); + public Q_SLOTS: // METHODS + bool CanHibernate(); bool CanLogout(); bool CanReboot(); bool CanShutdown(); + bool CanSuspend(); // 获取抑制器 QString GetInhibitor(uint cookie); QString GetInhibitors(); + void Hibernate(); // 添加抑制器 uint Inhibit(const QString &appID, uint toplevelXID, const QString &reason, uint flags); // 判断指定flags的抑制器是否存在 @@ -76,12 +88,15 @@ public Q_SLOTS: // METHODS // 添加会话程序的环境变量 void Setenv(const QString &name, const QString &value); void Shutdown(); + void Suspend(); // 删除抑制器 void Uninhibit(uint inhibitCookie); Q_SIGNALS: // SIGNALS void InhibitorAdded(uint cookie); void InhibitorRemoved(uint cookie); void PhaseChanged(int phase); + void ScreenLockedWhenHibernateChanged(bool screen_locked_when_hibernate); + void ScreenLockedWhenSuspendChanged(bool screen_locked_when_suspend); public Q_SLOTS: // 应用启动超时 -- 2.36.1
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2