feat: Phase2 Task2 — LinuxArm64Backend添加光标控制(unclutter)

This commit is contained in:
showen
2026-03-13 07:32:00 +08:00
parent f0605196fe
commit 5310a92633

View File

@@ -14,6 +14,8 @@ use std::process::{Child, Command, Stdio};
pub struct LinuxArm64Backend {
/// systemd-inhibit 子进程(用于防息屏)
wake_lock_child: Option<Child>,
/// unclutter 子进程(用于隐藏光标)
cursor_child: Option<Child>,
/// 显示宽度
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(())
}
}