463 lines
16 KiB
Diff
463 lines
16 KiB
Diff
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
|
||
|