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.
 
 

152 lines
4.7 KiB

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
"""
Author: Zhang Yueqian zhangyueqian@antiy.cn
Date: 2022-10-31 11:32:24
LastEditors: Zhang Yueqian zhangyueqian@antiy.cn
LastEditTime: 2022-10-31 11:34:16
FilePath: /screensaver/dialog/medr-screensaver-dialog.py
Description: 屏保程序 for MEDR项目. 本文件为负责锁屏的部分.
提供实际锁屏功能, 支持三个参数: --lock 、--session-idle 和 --screensaver
锁屏包括两个含义: 熄灭屏幕 & 触发lightdm锁定
--lock: 直接锁定lightdm
--session-idle: 根据系统设置进入session-idle模式
如果设置为空闲时激活屏保但不锁定, 那么关闭屏幕
如果设置了空闲激活屏保且锁定, 那么执行锁定, 通知lighdm执行黑屏
如果未设置空闲屏保但设置了锁定, 那么执行锁定, 不通知lightdm黑屏
--screensaver: 首先熄灭屏幕, 然后锁定屏幕
本应用为单例模式, 启动后当前用户只允许一个实例
实现机制:
首先获取sock文件的锁
如果获取失败, 表明已经运行一个了, 那么执行后将命令通过socket发送给当前活跃进程后退出.
如果获取成功, 说明是新运行, 那么启动server监听socket,并且执行命令
"""
from argparse import ArgumentParser
import fcntl
from multiprocessing.managers import BaseManager
import os, socket
import atexit
from time import sleep
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import GObject, Gio
MEDR_LOCK = "/tmp/medr-screensaver.lock"
TIMEOUT_FILE = "/var/run/medr-lightdm"
LOCK_FILE = "/var/run/medr-lightdm-lock"
def parse_args():
"""解析命令行参数
Returns:
(ArgumentParser.Namespace, str): 解析后的命令行参数及帮助信息
"""
argparser = ArgumentParser(add_help=False)
argparser.add_argument("-h", "--help", dest="help", action="store_true", help="Show this message and exit.")
argparser.add_argument("-l", "--lock", dest="lock", action="store_true", help="Locks the screen.")
argparser.add_argument(
"--session-idle", dest="session_idle", action="store_true", help="Activated by session idle signal."
)
argparser.add_argument(
"--screensaver",
dest="screensaver",
action="store_true",
help="Locks the screen and shows screensaver immediatelly.",
)
return argparser.parse_args(), argparser.format_help()
def check_singleton():
"""检查是否是单例运行"""
if not os.path.exists(MEDR_LOCK):
open(MEDR_LOCK, "w").close()
fd = open(MEDR_LOCK, "w")
try:
fcntl.flock(fd.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
fd.close()
return False
atexit.register(lambda: fd.close())
return True
def write_lightdm(cmd):
try:
with open(LOCK_FILE, "w") as fp:
fp.write(cmd)
except Exception:
return
def action(args, help):
"""执行命令
Args:
args (ArgumentParser.Namespace): ArgumentParser解析后的参数
help (str): 帮助信息
"""
first_run = check_singleton()
if not first_run:
print("Already running")
return
if args.help:
print(help)
return
if args.lock:
os.system("dm-tool lock")
return
if args.session_idle:
# 从Gio获取gsettings设置
# 1 判断是否设置了 /org/ukui/screensaver/idle-activation-enabled (空闲时是否激活屏保)
screensaver = Gio.Settings("org.ukui.screensaver")
idle_activation = screensaver.get_value("idle-activation-enabled").get_boolean()
# 2 判断是否设置了 /org/ukui/screensaver/lock-enabled (空闲时是否锁定屏幕)
lock_enabled = screensaver.get_value("lock-enabled").get_boolean()
# idle_activation 0 0 1 1
# lock_enabled 0 1 0 1
# 动作 无 锁 黑不锁 黑锁
if not idle_activation:
if not lock_enabled:
# 既不黑屏,也不锁定
return
else:
# 只锁定不黑屏
os.system("dm-tool lock")
else:
if not lock_enabled:
# 黑屏, 不锁定
os.system("xset dpms force off")
else:
# 黑屏且锁定
os.system("xset dpms force off")
sleep(1)
write_lightdm("blank")
os.system("dm-tool lock")
return
if args.screensaver:
write_lightdm("blank")
os.system("dm-tool lock")
return
print(help)
if __name__ == "__main__":
args, msg = parse_args()
action(args, msg)