//! ScreenPlugin — 屏幕管理(Thin Wrapper) //! //! 本插件现在是 DevicePlugin 的 thin wrapper,通过 DeviceCommand 消息 //! 调用 DevicePlugin 实现防息屏和光标隐藏功能。 //! //! 历史:v0.1.0 直接调用 systemd-inhibit 和 unclutter //! v0.2.0 迁移到 DevicePlugin(2026-03-13) use crate::core::{ message::{Destination, DeviceCommand, Envelope, Message}, plugin::*, plugin_ids, }; use anyhow::Result; pub struct ScreenPlugin { ctx: Option, } impl ScreenPlugin { pub fn new() -> Self { Self { ctx: None } } fn start_wake_lock(&self) { if let Some(ctx) = &self.ctx { let envelope = Envelope { from: self.id().to_string(), to: Destination::Plugin(plugin_ids::DEVICE.to_string()), message: Message::DeviceCommand(DeviceCommand::SetSleepInhibit(true)), }; let _ = ctx.tx.send(envelope); } } fn stop_wake_lock(&self) { if let Some(ctx) = &self.ctx { let envelope = Envelope { from: self.id().to_string(), to: Destination::Plugin(plugin_ids::DEVICE.to_string()), message: Message::DeviceCommand(DeviceCommand::SetSleepInhibit(false)), }; let _ = ctx.tx.send(envelope); } } fn set_cursor_hidden(&self, hidden: bool) { if let Some(ctx) = &self.ctx { let envelope = Envelope { from: self.id().to_string(), to: Destination::Plugin(plugin_ids::DEVICE.to_string()), message: Message::DeviceCommand(DeviceCommand::SetCursorVisible(!hidden)), }; let _ = ctx.tx.send(envelope); } } } impl Default for ScreenPlugin { fn default() -> Self { Self::new() } } impl Plugin for ScreenPlugin { fn id(&self) -> &str { "screen" } fn info(&self) -> PluginInfo { PluginInfo { name: "Screen Manager".to_string(), version: "0.2.0".to_string(), description: "屏幕唤醒锁 + 光标管理(Thin Wrapper)".to_string(), platform: Platform::Any, } } fn dependencies(&self) -> Vec { vec![plugin_ids::DEVICE.to_string()] } fn init(&mut self, ctx: PluginContext) -> Result<()> { self.ctx = Some(ctx); Ok(()) } fn start(&mut self) -> Result<()> { if self .ctx .as_ref() .map(|ctx| ctx.config.display.prevent_screen_lock) .unwrap_or(false) { self.start_wake_lock(); } self.set_cursor_hidden(true); Ok(()) } fn handle_message(&mut self, msg: Message) -> Result<()> { match msg { Message::ScreenLockRequest(lock) => { if lock { self.start_wake_lock(); } else { self.stop_wake_lock(); } } Message::CursorVisibility(visible) => self.set_cursor_hidden(!visible), Message::Shutdown => { self.stop()?; } _ => {} } Ok(()) } fn stop(&mut self) -> Result<()> { self.stop_wake_lock(); self.set_cursor_hidden(false); Ok(()) } }