diff --git a/src/plugins/device/linux_arm64.rs b/src/plugins/device/linux_arm64.rs index 8b6017f..7e66b12 100644 --- a/src/plugins/device/linux_arm64.rs +++ b/src/plugins/device/linux_arm64.rs @@ -14,6 +14,8 @@ use std::process::{Child, Command, Stdio}; pub struct LinuxArm64Backend { /// systemd-inhibit 子进程(用于防息屏) wake_lock_child: Option, + /// unclutter 子进程(用于隐藏光标) + cursor_child: Option, /// 显示宽度 display_width: u32, /// 显示高度 @@ -27,6 +29,7 @@ impl LinuxArm64Backend { pub fn new() -> Self { Self { wake_lock_child: None, + cursor_child: None, display_width: 1920, // 默认分辨率 display_height: 1080, backlight_enabled: true, @@ -113,6 +116,66 @@ impl LinuxArm64Backend { // 如果没有找到 backlight 设备,返回成功(某些设备可能不支持) Ok(()) } + + /// 设置光标可见性 + fn set_cursor_visible(&mut self, visible: bool) -> Result<()> { + if visible { + // 显示光标:停止 unclutter 进程 + if self.cursor_child.is_some() { + // 先清理已有的 cursor_child + if let Some(mut child) = self.cursor_child.take() { + let _ = child.kill(); + let _ = child.wait(); + } + } + + // 使用 pkill 确保清理所有 unclutter 进程 + let _ = Command::new("pkill") + .args(["-f", "unclutter"]) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status(); + } else { + // 隐藏光标:启动 unclutter 进程 + if self.cursor_child.is_some() { + // 已经隐藏,无需重复操作 + return Ok(()); + } + + // 先清理旧的 unclutter 进程 + let _ = Command::new("pkill") + .args(["-f", "unclutter"]) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status(); + + // 启动 unclutter 进程 + match Command::new("unclutter") + .arg("-idle") + .arg("0") + .arg("-root") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + { + Ok(child) => { + self.cursor_child = Some(child); + } + Err(e) => { + // unclutter 不可用时记录警告但不阻塞 + eprintln!( + "[LinuxArm64Backend] Warning: Failed to start unclutter: {}", + e + ); + } + } + } + + Ok(()) + } } impl DeviceBackend for LinuxArm64Backend { @@ -131,6 +194,7 @@ impl DeviceBackend for LinuxArm64Backend { DeviceCapability::Display, DeviceCapability::Backlight, DeviceCapability::Framebuffer, + DeviceCapability::Cursor, ] } @@ -156,6 +220,11 @@ impl DeviceBackend for LinuxArm64Backend { Ok(DeviceResponse::Ok) } + DeviceCommand::SetCursorVisible(visible) => { + self.set_cursor_visible(visible)?; + Ok(DeviceResponse::Ok) + } + _ => Ok(DeviceResponse::Error("Not implemented".to_string())), } } @@ -163,6 +232,21 @@ impl DeviceBackend for LinuxArm64Backend { fn shutdown(&mut self) -> Result<()> { // 清理 wake_lock_child self.stop_sleep_inhibit()?; + + // 清理 cursor_child + if let Some(mut child) = self.cursor_child.take() { + let _ = child.kill(); + let _ = child.wait(); + } + + // 确保清理所有 unclutter 进程 + let _ = Command::new("pkill") + .args(["-f", "unclutter"]) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status(); + Ok(()) } }