01 / PROBLEM
问题#
多个桌面 Shell 可能同时绘制面板、争用通知服务。手工停止旧服务、启动新服务时,还需要检查服务状态,不能只看命令有没有返回。
02 / STRUCTURE
结构#
程序读取 TOML 中的名称与 systemd 用户服务映射,通过环境变量识别会话。目标已独占 active 时仅尝试更新选择记录;否则停止全部已注册服务,确认不再报告 active,再启动目标、等待 active,最后尝试写入选择记录。boot 入口选择有效记录或默认服务并发出启动命令,不执行同一套停止和状态轮询流程。
// 确认真的起来了(systemd 可能还在 activating)
let deadline = Instant::now() + START_TIMEOUT;
loop {
if is_active(&target_entry.service) {
println!("{}", t!("switched", target = target));
write_current(target);
return ExitCode::SUCCESS;
}
if Instant::now() >= deadline {
eprintln!("{}", t!("start_timeout", target = target));
return ExitCode::from(1);
}
sleep(Duration::from_millis(200));
}命令返回后,继续确认 active;超时分支只返回错误。
03 / TRADEOFF
取舍#
把进程管理交给 systemd,Rust 程序负责启停顺序与状态判断。先停再启减少主动重叠,但会产生短暂的界面空窗。目前只识别 Hyprland 和 niri,会话检查和固定超时也构成了适用边界。
04 / RESULT
结果#
源码提供状态查询、幂等切换与按记录启动的入口。停止确认超时或启动目标的命令失败时,会尝试启动默认服务并返回错误;程序没有进一步确认恢复成功。等待目标 active 超时则直接返回错误,不执行同样的恢复步骤。
05 / SOURCE
源码与证据#
以上说明对应固定版本 1668dbdc42,不代表对所有运行环境的测试结论。