Linux/Gnome环境下开发应用如何提前响应关机、锁屏等系统事件?
Linux GNOME 环境监听系统事件方案
1. 需监听的事件类型
- 锁屏/解锁事件:GNOME 桌面通过 DBus 广播状态变更信号
- 休眠/挂起事件:系统电源管理模块触发的状态切换信号
- 关机/重启事件:系统登录管理服务发出的关机准备信号
2. 监听实现细节
方式一:DBus 信号监听(原生 GNOME 生态推荐)
GNOME 绝大多数系统事件都会通过 DBus 总线广播,直接监听对应接口即可实现实时响应:
- 锁屏/解锁监听:监听
org.gnome.ScreenSaver接口的ActiveChanged信号,参数boolean active为true表示锁屏,false表示解锁。
Python 示例代码(依赖dbus-python库):import dbus from dbus.mainloop.glib import DBusGMainLoop import gobject def handle_screensaver_change(active): if active: # 执行锁屏前任务 print("执行锁屏前置任务") else: # 执行解锁后任务(可选) print("执行解锁后置任务") DBusGMainLoop(set_as_default=True) session_bus = dbus.SessionBus() session_bus.add_signal_receiver( handle_screensaver_change, signal_name="ActiveChanged", dbus_interface="org.gnome.ScreenSaver", bus_name="org.gnome.ScreenSaver" ) loop = gobject.MainLoop() loop.run() - 休眠/关机监听:监听系统总线
org.freedesktop.login1.Manager接口的两个信号:PrepareForSleep对应休眠/挂起(参数preparing为true表示即将进入休眠),PrepareForShutdown对应关机/重启(参数preparing为true表示即将关机)。
Python 示例代码片段:
注意:监听系统总线信号无需特殊权限,但执行系统级任务可能需要 sudo 权限。def handle_prepare_sleep(preparing): if preparing: print("执行休眠前置任务") else: print("执行唤醒后置任务") def handle_prepare_shutdown(preparing): if preparing: print("执行关机前置任务") system_bus = dbus.SystemBus() system_bus.add_signal_receiver( handle_prepare_sleep, signal_name="PrepareForSleep", dbus_interface="org.freedesktop.login1.Manager", bus_name="org.freedesktop.login1" ) system_bus.add_signal_receiver( handle_prepare_shutdown, signal_name="PrepareForShutdown", dbus_interface="org.freedesktop.login1.Manager", bus_name="org.freedesktop.login1" )
方式二:Systemd 服务(适合后台常驻任务)
如果仅需在休眠/关机前执行一次性脚本,可通过 Systemd 服务绑定对应目标:
创建服务文件 /etc/systemd/system/your-task.service:
[Unit] Description=系统事件触发任务 Before=sleep.target shutdown.target [Service] Type=oneshot ExecStart=/path/to/your-pre-task.sh RemainAfterExit=yes [Install] WantedBy=sleep.target shutdown.target
执行以下命令启用服务:
sudo systemctl daemon-reload sudo systemctl enable your-task.service
此方式无法监听锁屏事件,仅适配休眠/关机场景。
macOS 环境扩展方案(后续适配)
1. 需监听的事件类型
- 锁屏/解锁:系统屏幕休眠/唤醒通知
- 休眠/关机:系统电源状态变更通知、应用终止回调
2. 监听实现细节
锁屏/解锁监听
通过 NSWorkspace 监听屏幕休眠/唤醒通知,Swift 示例代码:
import Cocoa class EventHandler: NSObject { override init() { super.init() NotificationCenter.default.addObserver( self, selector: #selector(handleScreenSleep), name: NSWorkspace.screensDidSleepNotification, object: nil ) NotificationCenter.default.addObserver( self, selector: #selector(handleScreenWake), name: NSWorkspace.screensDidWakeNotification, object: nil ) } @objc private func handleScreenSleep() { print("执行锁屏前置任务") } @objc private func handleScreenWake() { print("执行解锁后置任务") } }
休眠/关机监听
通过应用代理回调处理关机事件,同时监听电源状态变更:
import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply { // 关机/退出前执行任务 print("执行关机前置任务") return .terminateNow } func applicationDidFinishLaunching(_ aNotification: Notification) { NotificationCenter.default.addObserver( self, selector: #selector(handlePowerStateChange), name: NSProcessInfo.powerStateDidChangeNotification, object: nil ) } @objc private func handlePowerStateChange() { let powerInfo = NSProcessInfo.processInfo // 可根据 powerInfo 状态判断是否进入休眠 if powerInfo.isLowPowerModeEnabled { print("进入低功耗模式") } } }
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

