Skip to content

Desktop Integration.zh CN

Saco Song edited this page Aug 14, 2026 · 8 revisions

桌面集成

English · 首页

Hyprland 控制

Voice Input 本身不会捕获按键。Hyprland 会运行简短的 client command,并由这些命令连接 daemon control socket。

加载已安装的 snippet:

source = ~/.local/share/voice-input/omarchy-hyprland-snippet.conf

默认控制集中在相邻的功能键上。Snippet 不会修改 Omarchy 原有的 Super+Ctrl+X Voxtype 快捷键:

binddp = , F8, Cancel voice input, exec, voice-input record cancel
binddp = , F9, Toggle voice input, exec, voice-input record toggle
binddp = , F10, Restart active voice input, exec, voice-input record restart

F10 是单个 daemon restart 操作:它会丢弃并重新开始当前录音,在 idle 时则忽略。请勿用 shell 层的 cancel && start sequence 替代该命令。

当 release event 不可靠时,toggle 更稳定。Daemon 会为每个已接收的录音控制标记当前 idle generation。Session 完成或取消后,generation 会递增,因此在 finalization 之后排队的旧控制无法作用于下一次 idle/session generation;排队时长只用于诊断,不参与是否过期的判断。

如果需要 push-to-talk,请把 F9 toggle 替换为按下和释放 binding:

bind = , F9, exec, voice-input record start
bindr = , F9, exec, voice-input record stop

Hyprland 必须能够收到 release。如果 release 无法可靠触发,请改回 toggle。hotkey.mode 不会自行安装 binding;以下命令会根据该字段生成配置:

voice-input setup hyprland

可以取消当前录音且不输出文本,也可以用一个控制操作重新开始 active session:

voice-input record cancel
voice-input record restart

record restart 只有在 replacement recording 启动后才会报告成功;没有 active session 时,它会返回已忽略 idle 请求的响应。

Quickshell HUD

主 HUD 由独立 service 运行:

systemctl --user status voice-input-hud.service
systemctl --user restart voice-input-hud.service

Unit 会运行:

/usr/bin/qs --no-duplicate --path ~/.local/share/voice-input/quickshell

它设置 XDG_RUNTIME_DIR=%t,加载安装时编译的 shaders/wavy-halo.frag.qsb,为每个 screen 创建一个 PanelWindow variant,并且只在当前 focused Hyprland monitor 上显示。Surface 位于 overlay layer,不请求 keyboard focus,不占用 exclusive zone,并从完整 input mask 中减去自身区域,因此不会接收点击。

HUD 位置是相对于 focused monitor 解释的全局配置:bottom-leftbottom-centerbottom-right、下边距以及 X/Y offset 都应用于该显示器的当前 geometry。焦点改变后,对应 screen variant 会变为可见。Screen variant 会跟随 Quickshell 的实时 screen list;focused-monitor matching 使用稳定的显示器名称,因此焦点切换、显示器移除后重新连接以及热插拔不会让 HUD 继续关联已失效的 monitor object。

HUD 数据路径

$XDG_RUNTIME_DIR/voice-input/state.json
$XDG_RUNTIME_DIR/voice-input/waveform.sock

全部 screen variant 共用一个 StateStore.qml。它在活动 phase 中每 50 ms 读取一次由 daemon 原子替换的 JSON state,在 idle 状态下则每 100 ms 读取一次;程序会严格验证完整 snapshot,拒绝过期、畸形或不完整的 snapshot,并通过一次完整 object assignment 更新 UI。共享的 Quickshell local socket 独立接收 newline-delimited waveform frame,对 frame 长度、全部字段、数值范围、session 和 sequence 执行严格验证,并且只在验证成功后原子替换完整 waveform frame;连接断开后每 400 ms 尝试重连。系统不存在每个 screen 各自执行的 fallback poll。较长的 transcript 使用锚定到最新文本的四行 viewport,并通过边缘渐隐处理较早的内容。

顶部边缘光晕在全部活动 pipeline 中使用同一个频谱包络 renderer。Listening 在说话时会显示 12 个实时麦克风频段;在说话前和停顿期间则显示平缓的虚拟频谱,其延伸距离与 processing 相同。Finalizing、Refining 和 Sending 共用一段持续推进的虚拟频段动画;这些 phase 切换时只会对整个光晕执行颜色 crossfade,不会重置几何轮廓、运动 phase、节奏或亮度,也不会产生移动的颜色边界。session 结束时的 waveform reset 不会立即清空最后一个实时帧;HUD 会等到 runtime snapshot 进入 idle 后再清空。Listening 会通过一次短暂衰减到约 5% 光晕可见度再恢复的过程,把该帧交接给 Finalizing;capsule 本身会始终保持可见。过渡进度会和 phase 变化同步重置,不会等到下一帧动画才重置,因此目标 processing 轮廓不会在 crossfade 之前闪现。

同一个 capsule 的内部底部增加了一行状态栏,并通过增高 capsule 保持原有 transcript viewport 不变。左侧会把 runtime phase 映射为 ArmingListeningFinalizingRefiningSendingError;右侧以 MM:SS 显示有效录音时长。只有 capture 和 ASR 都准备完成,并且 phase 进入 recording 后,daemon 才会开始计时;接受停止请求时会冻结时长。Finalization 及后续阶段继续显示冻结后的数值,因此 arming 和处理阶段的等待时间不会计入录音时长。

HUD 仅使用 Quickshell,并且与识别流程相互独立:

  • 重启 daemon 不会重启 Quickshell;
  • HUD crash 不会停止 ASR 或文本输出;
  • [hud].enabled = false 会隐藏 HUD surface,同时常驻 service 可以继续运行;如需移除该 process,请 stop/disable voice-input-hud.service
  • 每个 state snapshot 都包含 hud_enabledhud_margin_bottomhud_heighthud_positionhud_offset_xhud_offset_y,Quickshell 会应用这些值。

主题

Quickshell 会读取:

~/.config/omarchy/current/theme/colors.toml

它把 accentforegroundcolor3color5color1 映射为不同 phase 的颜色。无法读取或解析文件时,它会保留内置颜色。该主题文件不是必需依赖。

HUD 位置

当前位置和偏移会保存在 config 与 runtime state 中:

voice-input hud position bottom-left
voice-input hud move right
voice-input hud move up 12
voice-input hud center
voice-input hud reset
  • move 未指定数值时使用 [hud].nudge_step
  • X 正值向右;Y 正值让 HUD 上移。
  • center 选择 bottom-center 并只清除 X。
  • reset 选择 bottom-center 并清除两个 offset。

建议使用的可选 binding:

bind = SUPER CTRL ALT, left,  exec, voice-input hud move left
bind = SUPER CTRL ALT, right, exec, voice-input hud move right
bind = SUPER CTRL ALT, up,    exec, voice-input hud move up
bind = SUPER CTRL ALT, down,  exec, voice-input hud move down
bind = SUPER CTRL ALT, c,     exec, voice-input hud center

Quickshell Settings

Settings 使用另一套 Quickshell 配置,并且与常驻 HUD 分开:

~/.local/share/voice-input/quickshell-settings

通过以下命令打开:

voice-input settings

该命令会先通过不包含 secret 的 Quickshell IPC 激活已有的 voiceInputSettings instance。如果没有可激活的实例,则启动:

/usr/bin/qs --daemonize --no-duplicate --path ~/.local/share/voice-input/quickshell-settings

这套配置会创建普通 FloatingWindow,而不是 layer-shell panel;窗口关闭后进程会退出。Settings 按需运行,并且没有 systemd unit。随附的 Hyprland snippet 会让 Voice Input Settings client 浮动并居中,使 compositor 采用窗口请求的 900 × 620 工具窗口尺寸,而不会把它平铺到整个 workspace。

全高度导航包含 Overview、Speech、Refinement、Output、Appearance 和 Hotkey & state。Overview 只读显示本地 service 报告,以及当前 Speech、Refinement、Output 和 Appearance 配置的摘要。详细页面采用带有清晰分隔线的扁平桌面表单区域,不再使用多层 dashboard card。Provider 专属字段会按条件显示,技术参数则保留在相关页面的可展开高级设置区域中;隐藏字段仍保留在完整配置草稿中。Header 会显示未保存状态,并提供语言菜单、位于 overflow 菜单中的 Reload settings 操作和 Close 按钮。

Speech 提供完整的实验性 Audio3 配置流程:独立确认开关、Regional/Custom 路由与区域、语言提示、heartbeat、识别预设与 Custom 控制项、动态词汇表、Native final-pass policy,以及 Advanced 中的 Streaming/Native endpoint、model 和 timeout。仅选择 Audio3 不会自动确认或启用实验功能。Save & restart 会验证并持久化完整草稿,更新用户要求替换的 credential,然后请求 systemd 重启 voice-input.service;如果持久化成功但 credential 更新或 service 重启失败,Settings 会分别报告结果。该操作不会重启常驻 HUD,也不会重启 Settings 窗口。

QML 会启动一个专用 Rust child backend,并且只通过继承的 stdin/stdout 使用 protocol version 1 NDJSON 通信;QML 不会直接写入 TOML 或 credential。每个请求的 response deadline 都是 30 秒。Response 最大为 2 MiB,并且只有通过严格的 envelope 和 method-specific payload 验证后才会被接受。如果请求超时,收到畸形、过大或意外 response,或者 backend 退出,Settings 会使全部 pending operation 失效,并按 250 ms 起步、最大 8 秒的指数延迟重启 child,最多自动尝试六次。只有经过验证的 response 才会重置失败计数;达到上限后,Reload settings 可以再手动尝试一次。重启 child backend 不代表 voice-input.service 已重启;请求超时也不能证明保存失败。Settings 会提示该操作可能已经完成,因此重试前应先 reload。runtime.get 只会向 Overview 返回允许公开的 service 与 runtime metadata;该状态与配置保存状态相互独立,也不会宣称 provider 已经连通。

Waybar

随附 JSONC fragment 定义了 custom/voice-input

voice-input setup waybar

其中执行:

voice-input status --follow --format json --extended

status --follow 每 250 ms 检查一次 state,并且只在 payload 发生变化时输出。Snippet 根据 phase class 显示 icon;右键打开 Settings,左键打开 model setup wizard。

请把该 object 合并到 Waybar config,并将 custom/voice-input 加入所需的 module list。Setup command 只会输出 fragment,不会编辑现有 Waybar file,也不会重启 Waybar。

Wayland 与 XWayland 输出目标

开始录音时,CLI 会询问 Hyprland 当前窗口是否属于 XWayland,并把结果作为 hint 发送给 daemon。输出时,daemon 会再次查询。如果开始时的 hint 或当前目标任意一个为 XWayland,程序都会走 XWayland 路径。

目标 剪贴板提供程序 粘贴快捷键
Wayland wl-copy Hyprland dispatch sendshortcut
XWayland xclip xdotool

无论文本长度或旧版 output.mode 的值是什么,所有文本都会使用粘贴路径。在原生 Wayland 路径中,临时 transcript 和恢复的剪贴板 payload 都通过 wl-copy --sensitive 写入。只有兼容的剪贴板管理器才保证不把这些 payload 保存到历史记录中,并避免改变其顺序。XWayland 的 xclip 路径没有等效的 sensitive hint。Daemon 会在粘贴前后备份并恢复目标剪贴板,并且不会创建逐字符合成 keymap。

Hyprland discovery 会优先连接 command socket,失败后调用 hyprctl。程序可以从 systemd 用户管理器环境中读取 HYPRLAND_INSTANCE_SIGNATUREWAYLAND_DISPLAYDISPLAYXDG_RUNTIME_DIR。如果 service 无法访问 session,请在图形会话启动时更新 systemd 用户环境,然后重启 service;不要硬编码其他用户的 runtime path。

另请参阅:故障排查 · 配置参考

Clone this wiki locally