feat: config验证 + StateMachine + WifiPlugin + ScreenPlugin
团队交付 Phase 1 第一轮: - 张明远: config.rs 完整验证逻辑 (Display/VideoItem/Transition/Scenes/StateMachine) - 李思琪: state_machine.rs 完整实现 (defer/ignore triggers, 加权随机, loop range) - 王浩然: wifi/mod.rs WiFi管理插件 (scan/connect/status/ap via nmcli) - 赵雨薇: screen/mod.rs 屏幕管理插件 (systemd-inhibit唤醒锁 + unclutter光标) cargo check 零 warning 通过。 Co-Authored-By: GPT-5.4 <noreply@openai.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,22 +2,106 @@
|
||||
//!
|
||||
//! 唤醒锁(systemd-inhibit)、光标隐藏(unclutter)。
|
||||
|
||||
use crate::core::message::Message;
|
||||
use crate::core::plugin::{Plugin, PluginContext, PluginInfo, Platform};
|
||||
use crate::core::{message::Message, plugin::*};
|
||||
use anyhow::Result;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
|
||||
pub struct ScreenPlugin {
|
||||
ctx: Option<PluginContext>,
|
||||
wake_lock_child: Option<Child>,
|
||||
cursor_hidden: bool,
|
||||
}
|
||||
|
||||
impl ScreenPlugin {
|
||||
pub fn new() -> Self {
|
||||
Self { ctx: None }
|
||||
Self {
|
||||
ctx: None,
|
||||
wake_lock_child: None,
|
||||
cursor_hidden: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn start_wake_lock(&mut self) {
|
||||
if self.wake_lock_child.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
match Command::new("systemd-inhibit")
|
||||
.arg("--what=idle")
|
||||
.arg("--who=ShowenV2")
|
||||
.arg("--why=Prevent screen lock during playback")
|
||||
.arg("sleep")
|
||||
.arg("infinity")
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.spawn()
|
||||
{
|
||||
Ok(child) => self.wake_lock_child = Some(child),
|
||||
Err(err) => eprintln!("[ScreenPlugin] 启动防息屏失败: {err}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn start_wake_lock(&mut self) {}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn stop_wake_lock(&mut self) {
|
||||
if let Some(mut child) = self.wake_lock_child.take() {
|
||||
if let Err(err) = child.kill() {
|
||||
eprintln!("[ScreenPlugin] 停止防息屏失败: {err}");
|
||||
}
|
||||
let _ = child.wait();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn stop_wake_lock(&mut self) {}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn set_cursor_hidden(&mut self, hidden: bool) {
|
||||
if hidden == self.cursor_hidden {
|
||||
return;
|
||||
}
|
||||
|
||||
if hidden {
|
||||
match Command::new("unclutter")
|
||||
.arg("-idle")
|
||||
.arg("0")
|
||||
.arg("-root")
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.spawn()
|
||||
{
|
||||
Ok(_) => self.cursor_hidden = true,
|
||||
Err(err) => eprintln!("[ScreenPlugin] 隐藏光标失败: {err}"),
|
||||
}
|
||||
} else {
|
||||
match Command::new("pkill")
|
||||
.arg("unclutter")
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.status()
|
||||
{
|
||||
Ok(_) => self.cursor_hidden = false,
|
||||
Err(err) => eprintln!("[ScreenPlugin] 恢复光标失败: {err}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn set_cursor_hidden(&mut self, hidden: bool) {
|
||||
self.cursor_hidden = hidden;
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for ScreenPlugin {
|
||||
fn id(&self) -> &'static str { "screen" }
|
||||
fn id(&self) -> &'static str {
|
||||
"screen"
|
||||
}
|
||||
|
||||
fn info(&self) -> PluginInfo {
|
||||
PluginInfo {
|
||||
@@ -33,7 +117,42 @@ impl Plugin for ScreenPlugin {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start(&mut self) -> Result<()> { Ok(()) }
|
||||
fn handle_message(&mut self, _msg: Message) -> Result<()> { Ok(()) }
|
||||
fn stop(&mut self) -> Result<()> { 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(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user