You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

141 lines
3.9 KiB

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
"""
Author: Zhang Yueqian zhangyueqian@antiy.cn
Date: 2022-10-31 11:20:48
LastEditors: Zhang Yueqian zhangyueqian@antiy.cn
LastEditTime: 2022-10-31 11:34:00
FilePath: /screensaver/backend/medr-screensaver-backend.py
Description: 屏保程序 for MEDR项目. 本文件为后台监控的部分.
原理: 主要负责实现两部分功能
1. 通过dbus方法提供开始菜单中的锁屏功能
2. 通过监听org.gnome.SessionManager.Presence的StatusChanged信号完成自动锁屏功能
以上两种锁屏通过调用 medr-screensaver-command 来实现, 提供不同的参数 `--session-idle` 和 `--lock`
另外: 对于锁屏情况下的黑屏时长, 需要控制lightdm配置实现, 参考
https://askubuntu.com/questions/403859/how-to-control-lightdm-power-saving-preferences
利用额外的文件 /var/run/medr-lightdm 来设置
"""
from datetime import datetime
import threading
from time import sleep
import dbus
import dbus.service
import dbus.glib
import os
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import GObject, Gio
BUS_NAME = "org.ukui.ScreenSaver"
TIMEOUT_FILE = "/var/run/medr-lightdm"
LOCK_FILE = "/var/run/medr-lightdm-lock"
DEFAULT_TIMEOUT = 10
class Service(dbus.service.Object):
"""锁屏dbus服务"""
def __init__(self, bus_name, obj_path):
"""使用bus_name和obj_path初始化dbus服务
Args:
bus_name (dbus.service.BusName): 要注册的bus名
obj_path (str): 要注册的路径
"""
dbus.service.Object.__init__(self, bus_name, obj_path)
self._locked = False
@dbus.service.method(BUS_NAME, in_signature="", out_signature="b")
def GetLockState(self):
print("GetLockState: %s" % self._locked)
return self._locked
@dbus.service.method(BUS_NAME, in_signature="b", out_signature="")
def SetLockState(self, state):
print("SetLockState: %s" % state)
self._locked = state
@dbus.service.method(BUS_NAME, in_signature="", out_signature="")
def Lock(self):
print("Lock")
self._locked = True
os.system("ukui-screensaver-dialog --lock")
@dbus.service.method(BUS_NAME, in_signature="", out_signature="")
def Quit(self):
self._loop.quit()
@dbus.service.signal(BUS_NAME)
def SessionIdle(self):
os.system("ukui-screensaver-dialog --session-idle")
loop = GObject.MainLoop()
bus = dbus.SessionBus()
bus_name = dbus.service.BusName(BUS_NAME, bus=bus)
service = Service(bus_name, "/")
def isLocked():
"""确认当前是否是锁定状态.
Returns:
boolean: 是否锁定.
"""
if not os.path.exists(LOCK_FILE):
return False
status = ""
with open(LOCK_FILE, "r") as fp:
status = fp.readline().strip()
if len(status) != 0 and status == "done":
return True
return False
def sessionStatusChanged(sessionStatus):
print("---- Caught signal of status %s ----" % sessionStatus)
if sessionStatus == 3 and (not isLocked()):
service.SessionIdle()
print("\n")
def checkSessionIdle():
"""检查gsettings中配置的会话闲置时间并写入到配置文件 TIMEOUT_FILE 中"""
while True:
mate_session = Gio.Settings("org.mate.session")
sys_timeout = mate_session.get_value("idle-delay").get_int32()
with open(TIMEOUT_FILE, "r") as fp:
try:
medr_timeout = int(fp.read())
except ValueError:
medr_timeout = DEFAULT_TIMEOUT
if medr_timeout != sys_timeout:
with open(TIMEOUT_FILE, "w") as fp:
fp.write("%s" % sys_timeout)
sleep(5)
t = threading.Thread(target=checkSessionIdle)
if __name__ == "__main__":
bus.add_signal_receiver(
sessionStatusChanged, dbus_interface="org.gnome.SessionManager.Presence", signal_name="StatusChanged"
)
# org.gnome.SessionManager.Presence:StatusChanged
t.start()
loop.run()