如何在Tauri应用中监听睡眠、锁定、唤醒等系统事件?
Tauri监听系统睡眠、锁定等事件的实现方案
1. 使用现成插件:tauri-plugin-power-monitor
这是Tauri生态中专门处理电源与系统会话事件的插件,支持Windows、macOS、Linux三大平台,能直接监听睡眠、唤醒、锁屏、解锁等事件。
步骤:
- 安装插件
# Rust端依赖 cargo add tauri-plugin-power-monitor # 前端API依赖(JS/TS环境) npm install tauri-plugin-power-monitor-api
- 在
tauri.conf.json中配置插件:
{ "plugins": { "powerMonitor": {} } }
- 前端监听事件:
import { listen } from '@tauri-apps/api/event'; import { PowerMonitor } from 'tauri-plugin-power-monitor-api'; // 初始化插件 await PowerMonitor.initialize(); // 监听系统睡眠/休眠 listen('power-suspend', () => { console.log('系统即将进入睡眠或休眠状态'); }); // 监听系统唤醒 listen('power-resume', () => { console.log('系统已从睡眠中唤醒'); }); // 监听屏幕锁定 listen('lock-screen', () => { console.log('屏幕已锁定'); }); // 监听屏幕解锁 listen('unlock-screen', () => { console.log('屏幕已解锁'); }); // 监听关机/重启通知(仅接收通知,无法拦截) listen('power-shutdown', () => { console.log('系统即将关机或重启,请立即保存数据'); });
2. 自定义原生绑定(适合特殊需求)
如果插件无法满足定制化需求,可以直接通过Tauri的原生能力绑定系统API,针对不同平台实现监听:
Windows平台(Win32 API)
Rust后端代码:
use tauri::{AppHandle, Manager, WindowEvent}; use windows::Win32::System::Power::*; use windows::Win32::UI::WindowsAndMessaging::*; #[tauri::command] fn register_power_events(app_handle: AppHandle) { let main_window = app_handle.get_window("main").unwrap(); let hwnd = main_window.hwnd().unwrap(); // 注册电源事件监听 unsafe { RegisterPowerSettingNotification(hwnd, &GUID_SYSTEM_AWAYMODE, 0); RegisterPowerSettingNotification(hwnd, &GUID_MONITOR_POWER_ON, 0); } // 监听窗口消息 main_window.on_window_event(move |event| { if let WindowEvent::Win32Message { msg, wparam, .. } = event { if *msg == WM_POWERBROADCAST { match *wparam as u32 { PBT_APMSUSPEND => { app_handle.emit_all("power-suspend", ()).unwrap(); } PBT_APMRESUMEAUTOMATIC => { app_handle.emit_all("power-resume", ()).unwrap(); } PBT_APMSESSIONCHANGED => { // 处理锁屏/解锁会话变化 } _ => {} } } } }); }
前端调用并监听事件:
import { invoke, listen } from '@tauri-apps/api/tauri'; await invoke('register_power_events'); listen('power-suspend', () => { console.log('系统即将睡眠'); });
macOS平台(NSWorkspace)
通过Rust绑定Objective-C的NSWorkspace通知:
use tauri::{AppHandle, Manager}; use objc::{runtime::Object, msg_send, sel, sel_impl}; #[tauri::command] fn register_macos_power_events(app_handle: AppHandle) { unsafe { let workspace: *mut Object = msg_send![class!(NSWorkspace), sharedWorkspace]; let notification_center: *mut Object = msg_send![workspace, notificationCenter]; // 注册睡眠/唤醒通知监听 msg_send![notification_center, addObserver:workspace selector:sel!(handleSleep:) name:NSWorkspaceWillSleepNotification object:nil]; msg_send![notification_center, addObserver:workspace selector:sel!(handleWake:) name:NSWorkspaceDidWakeNotification object:nil]; // 触发Tauri事件(实际需实现对应Objective-C方法) app_handle.emit_all("power-suspend", ()).unwrap(); } }
Linux平台(DBus)
通过DBus监听PowerManagement服务的事件:
use tauri::AppHandle; use zbus::Connection; #[tauri::command] async fn register_linux_power_events(app_handle: AppHandle) -> Result<(), String> { let conn = Connection::system().await.map_err(|e| e.to_string())?; // 订阅DBus电源事件信号(示例简化) let _ = conn.call_method( Some("org.freedesktop.login1"), "/org/freedesktop/login1", Some("org.freedesktop.login1.Manager"), "Sleep", &(), ).await; app_handle.emit_all("power-suspend", ()).unwrap(); Ok(()) }
关键注意事项
- 关机/重启事件:所有平台仅支持接收通知,无法阻止系统关机,收到事件后应尽快完成数据保存、资源释放等操作。
- 跨平台测试:不同平台的事件触发时机和类型略有差异,需在目标平台上验证逻辑。
- 权限要求:Linux平台可能需要赋予应用访问DBus的权限,部分发行版需配置policy文件。
内容的提问来源于stack exchange,提问作者Sourav Paria
相关产品推荐
相关产品推荐

