feat: Phase2 Task2 — LinuxArm64Backend添加光标控制(unclutter)
This commit is contained in:
@@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user