#!/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)