47 Commits
Author SHA1 Message Date
aeoformandClaude Opus 4.7 1033130852 fix: resolve merge conflicts with beta (frost removal + audio cue)
Accept beta's WindowChrome/global.css/FloatingShell changes for Linux
surface treatment, re-apply AudioCueListener component on top.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-06 17:42:37 +08:00
aeoformandClaude Opus 4.7 ac650113ab fix: move audio cue listener from capsule window to main window
- AudioCueListener is a new component rendered in FloatingShellBody
  that listens to capsule:state on the main window, so the record
  start cue works on Linux where the capsule window is hidden.
- Coordinator now emits capsule:state to both "capsule" and "main"
  windows so the listener receives state changes.
- Remove duplicate audio cue logic from Capsule.tsx to avoid
  double-triggering on macOS/Windows where capsules are shown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-05 22:47:37 +08:00
aeoformandClaude Opus 4.7 1658af4dfd ci(linux): upload fcitx5 plugin as standalone release artifact
- Add upload step for libopenless.so + openless.conf as a separate
  artifact (openless-fcitx5-plugin-linux-x64) for AppImage users
  and manual installation
- Include plugin files in GitHub Release assets alongside existing
  deb/rpm/AppImage bundles

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-05 22:12:10 +08:00
aeoformandClaude Opus 4.7 7e21123bad fix(linux): fcitx5 hotkey intercept + remove backdrop-filter + clipboard cleanup
- fcitx5 plugin: fix Alt+a hotkey leaking 'a' character by normalizing
  case comparison (Alt produces uppercase sym, Key::check expects lowercase)
- fcitx5 plugin: use PreInputMethod + filterAndAccept to block engine
  before commit happens (same strategy as clipboard addon)
- Linux: remove backdrop-filter (unreliable on WebKitGTK, #553),
  replace with opaque background
- Linux: skip clipboard writes after streaming insert (fcitx5 commits
  directly, clipboard fallback corrupts user data)
- SettingsModal: render via React Portal to document.body (#580, fixes
  scrollbars overlapping modal)
- Remove is_no_compositing_mode command and CSS fallback (no longer needed)
- Remove StartupShell loading screen (app renders FloatingShell immediately)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-05 21:59:12 +08:00
aeoformandClaude Opus 4.7 737ca4491e fix: restore is_no_compositing_mode useEffect for Linux frost fallback
The useEffect that invokes is_no_compositing_mode was removed along
with StartupShell, but it is the sole trigger for #553/#570's CSS
frost fallback on Linux. Without it, WEBKIT_DISABLE_COMPOSITING_MODE=1
users never get the fallback and see broken frosted glass.

Also fix the dead ternary: isTauri ? 'ready' : 'ready' → 'ready'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-04 22:05:02 +08:00
aeoformandClaude Opus 4.7 a2af260d80 chore(linux): plugin check improvements + remove startup shell + fix i18n
- ensure_plugin_installed: check ~/.local/ XDG paths in addition to system
  paths; warn when both user and system plugins coexist (old user version
  takes priority over newly installed system version)
- App.tsx: remove StartupShell loading screen and 'checking' gate state,
  app renders FloatingShell immediately
- i18n: "切换上一次风格" → "切换到上一个风格" (zh-CN/zh-TW)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-04 00:07:43 +08:00
aeoformandClaude Opus 4.7 8d386815f2 fix(ci): restore macOS/Windows imports removed by cargo fix
Restore std::path::Path, std::sync::Arc, parking_lot::Mutex, anyhow::Result,
std::time::{Duration, Instant} imports in cache.rs, PhysicalPosition/PhysicalSize
in lib.rs, and std::time::Duration in selection.rs. These were removed by
cargo fix --broken-code because they appear unused on Linux but are needed
on macOS and Windows.

Add unused_imports to cfg_attr allow lists so future cargo fix runs on
Linux won't strip cross-platform imports again.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 23:29:41 +08:00
aeoformandClaude Opus 4.7 b4d0f1e36e fix(ci): restore variables broken by cargo fix --broken-code
Restore handle_pressed/handle_released imports and window/show_capsule/
visible/audio_timeout/duration_ms variable names that cargo fix renamed
with _ prefix. These are used on macOS/Windows but the _ prefix broke
the builds. Add platform-gated import for model_dir in test_run.rs.

Expand cfg_attr allow lists to cover unused_imports and unused_variables
where needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 23:19:07 +08:00
aeoformandClaude Opus 4.7 72b53520f2 chore: suppress all Linux build warnings (192 → 0)
Add #[cfg_attr(target_os = "linux", allow(dead_code, unused_variables))]
to 20+ source files where Linux builds see platform-specific dead code
(Windows IME, macOS permissions, Sherpa ASR, clipboard restore, etc.).
Also manually fix 3 real warnings: unused imports in coordinator.rs,
unreachable expression in insertion.rs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 23:01:31 +08:00
aeoformandClaude Opus 4.7 05a4634768 fix(linux): move streaming insert toggle into recording card
On Linux, hide the clipboard/paste/capsule settings group and move
the streaming insert toggle directly into the recording input card.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 21:36:49 +08:00
aeoformandClaude Opus 4.7 eb05bc1ca1 fix(linux): fcitx5 auxDown persistent + hotkey mode save + hide clipboard/capsule settings
- coordinator.rs: terminal state (Done/Error/Cancelled) auto-clears after 3s;
  fix RETRY_GEN comparison (fetch_add returns old value, use latest_gen > gen+1);
  remove broken 300ms retry
- HotkeySettingsContext.tsx: fix queueSetSettings never calling setSettings()
  (latestPrefsRef was already updated to the new object before microtask ran)
- openless.cpp: add PostInputMethod event hook to restore auxDown after
  fcitx5 processes key events
- RecordingInputSection.tsx: hide clipboard/paste/capsule settings on Linux;
  streaming insert shown as standalone card instead of inside clipboard group
- ShortcutsSection.tsx: hide "capsule confirm" shortcut hint on Linux

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 20:53:32 +08:00
aeoformandClaude Opus 4.7 28ef33267c fix(inject): fail loudly when RPM injection cannot complete
exit 0 on rpmrebuild failure produced a broken RPM silently.
Use exit 1 and print to stderr so the CI pipeline catches it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 23:59:53 +08:00
aeoformandClaude Opus 4.7 f5bf1ff153 fix(inject): remove AppImage support, detect Debian multiarch dynamically
- AppImage cannot work for fcitx5 plugin injection: fcitx5 runs on the
  host system and loads addons from host paths (/usr/lib/.../fcitx5).
  Files placed inside the AppImage mount are invisible to fcitx5.
- For Debian, use dpkg-architecture to detect the multiarch triplet
  (x86_64-linux-gnu, aarch64-linux-gnu, etc.) instead of hardcoding.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 23:53:53 +08:00
aeoformandClaude Opus 4.7 71a36344b2 fix(fcitx): probe multiple distro lib paths for plugin check
Debian uses /usr/lib/x86_64-linux-gnu/fcitx5, RPM uses /usr/lib64/fcitx5,
and some distros use /usr/lib/fcitx5. Check all three to avoid false
alarms on non-Debian systems.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 23:38:08 +08:00
aeoformandClaude Opus 4.7 0e5f90bcf2 fix(inject): use correct RPM lib path, remove broken AppImage file mode
- RPM: use /usr/lib64/fcitx5/ (RPM 64-bit standard) instead of
  Debian multiarch path
- AppImage: only support AppDir directory input, remove .AppImage file
  extraction which couldn't repack and would lose changes

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 23:32:10 +08:00
aeoformandClaude Opus 4.7 2bd733ecb3 fix(ci): remove Tauri resources for plugin files, simplify to path check
- Remove `resources` from tauri.linux.conf.json — the .so/.conf files
  don't exist on CI (plugin is built separately), causing cargo check
  to fail with "resource path doesn't exist"
- Simplify ensure_plugin_installed to just check system paths exist,
  no bundled comparison needed
- Remove prebuild script and copy-plugin.mjs (no longer needed)
- Remove plugin entries from .gitignore

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 23:16:53 +08:00
aeoformandClaude Opus 4.7 d426b9e7b8 fix(ci): replace bash prebuild with cross-platform Node.js script
The prebuild script used bash syntax (mkdir, for, [ -f ]) which fails on
Windows. Replace with a Node.js script that checks platform() and skips
non-Linux, keeping the plugin copy logic only where it's needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 23:13:44 +08:00
aeoformandClaude Opus 4.7 19ab7429cd chore(linux): fcitx5 插件打包注入 + 清理 rdev 残留 + 声明系统依赖
- fcitx5 插件改为打包时注入系统路径(inject-fcitx5-plugin.sh),不再运行时复制
- ensure_plugin_installed 改为纯版本检查,不做文件 I/O
- 清理 hotkey/permissions/unicode_keystroke 中 rdev 相关注释和日志
- tauri.linux.conf.json 声明 deb/rpm 运行时依赖及 fcitx5 推荐
- prebuild 脚本自动复制插件文件供 Tauri resources 打包

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 23:08:00 +08:00
aeoformandClaude Opus 4.7 a4705fa286 fix: 修复 PR review 发现的两个问题
- 最大化状态同步:mount 后监听 tauri://resize 事件,每次 resize 都重新查询
  isMaximized(),确保双击拖拽栏/键盘快捷键触发最大化时图标不脱节
- 按钮点击后 300ms 再次查询 isMaximized(),防止窗口管理器拒绝 toggle 时
  状态错误
- 启动 nudge drift check:只修正 ±1px 的 nudge 产物,不再覆盖用户/合成器
  的实质性窗口大小变化
- 还原误删的中文注释,移除冗余 closeBtn 常量,<style> 移到 WindowChrome
  层级避免每个 LinuxTitlebar 实例重复注入

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 23:55:45 +08:00
aeoformandClaude Opus 4.7 4254d835ff fix: Linux Wayland 改用应用级自定义标题栏,绕过 GTK CSD 点击无响应问题
KDE/Wayland 下 GTK Client-Side Decorations 的 minimize/maximize/close
按钮无法响应鼠标事件(tao#1218, tauri#9394)。此前尝试的 WebKit 环境变量 +
async nudge resize 均不能可靠修复,最终方案参考 cc-switch,完全放弃系统装饰:

- decorations: false → 应用级 WindowChrome 绘制 36px 拖拽栏 + 三键窗口控制
- transparent: true → 配合 CSS 磨砂玻璃背景
- WEBKIT_DISABLE_COMPOSITING_MODE + DMABUF_RENDERER 兜底 WebKit 合成异常
- async nudge(set_focus + ±1px resize)保留为辅助修复,防止 show() 后
  webview surface 输入区域未初始化

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 23:38:46 +08:00
aeoformandClaude Opus 4.7 28324376a5 fix(review): 自动化审核修复 — 注释误判 + gen counter 去重 + bailian warn
1. _name_match/_match 生命周期注释:Rust 的 `let _name =` 不会提前 drop,
   仅有 `let _ =` 才会。两个 guard 与 loop{} 同闭包作用域,自动化审核 HIGH 误判。
2. emit_capsule retry 用 AtomicU64 gen counter 去重,避免快速状态切换时
   多个 retry 线程同时生效。
3. bailian.rs sentence_id==0 的 final 句加 warn 日志,方便排查。
4. 删除空 libopenless.so 占位文件,CI 会在构建前实时 cp。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 15:27:13 +08:00
aeoformandClaude Opus 4.7 de5c55b00f fix(review): clear_aux_down 同样加状态守卫
避免快速状态切换 (Done→Idle→Recording) 时旧 clear 跑到新 set 后面把新文字清掉。
NameOwnerChanged Stale Sync 是已知低概率场景,注释保留。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 15:10:14 +08:00
aeoformandClaude Opus 4.7 52084999a6 fix(review): Claude Code 审查问题修复
1. NameOwnerChanged 回调内 sleep 移到独立线程,不再阻塞 DBus 事件循环
2. emit_capsule 首次 set_aux_down spawn 加 LAST_AUX 状态守卫
3. ensure_plugin_installed 注释更新为"总是覆盖"语义
4. NameOwnerChanged match rule 移除不支持的 arg0,改回调内过滤

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 13:28:56 +08:00
aeoformandClaude Opus 4.7 1b0e41c206 docs: NameOwnerChanged 快照语义注释
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 21:32:14 +08:00
aeoformandClaude Opus 4.7 77455cf268 fix(build): sync_custom_dictation_to_plugin 加上 #[cfg(target_os = "linux")]
函数体内引用了 crate::linux_fcitx,非 Linux 平台该模块不存在导致 E0433。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 21:29:43 +08:00
aeoformandClaude Opus 4.7 163327e17b fix(review): NameOwnerChanged 支持自定义组合键 + 总是覆盖旧版插件
1. start_dictation_signal_listener 新增 custom_trigger_key 参数,
   NameOwnerChanged 和初始同步都通过 resync_main_binding 分支处理
   自定义组合键 vs 预设修饰键
2. ensure_plugin_installed 去掉"已安装即跳过"检查,AppImage 每次启动
   都覆盖最新 .so + .conf,确保新 DBus 方法不会因旧插件丢失

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 21:20:19 +08:00
aeoformandClaude Opus 4.7 c4cb3c9ee5 fix(review): DBus 调用挪出音频线程 + 安装检查同步校验 .conf
1. set_aux_down/clear_aux_down 从 emit_capsule(被 cpal 音频回调调用)
   移到独立线程执行,避免同步 DBus I/O 阻塞录音导致卡顿
2. is_plugin_installed_on_disk 同时检查 .so 和 .conf,孤立的 .so
   没有 addon 配置 fcitx5 不会加载

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 21:05:01 +08:00
aeoformandClaude Opus 4.7 7403597be8 fix(review): 修复 PR review 指出的 Stale Status 和 Retry Race
1. clearAuxDown 找不到 IC 时也会清掉 lastAuxText_,避免 FocusIn 时
   重放旧状态(如"已插入"→切窗口→突然显示"已插入")
2. 300ms 延迟重试前检查 LAST_AUX,状态已变则跳过,避免旧文字覆盖

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 20:58:38 +08:00
aeoformandClaude Opus 4.7 54f07d85e9 fix(bailian): 修复 DashScope ASR 部分语句重复输出的问题
两个根因:
1. end_time 判断用 is_some() 而非 > 0:API 对 interim 结果设 end_time:0,
   导致所有中间结果被当成 final 推入 segments
2. 累积文本拼接:同一句 API 多次发送("你"→"你好"→"你好吗"),
   每次作为新 segment push,join 后变成重复拼接

修复:
- end_time 改用 > 0 判断真正的句子结束
- 引入 sentence_id → BTreeMap 按序存储,同一 sentence_id 后到覆盖前到

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 20:49:11 +08:00
aeoformandClaude Opus 4.7 7635df5df5 fix(test): 同步 capsule_show_strategy 单测的 Linux cfg
Linux 已从 NoActivate 列表移除(走 fcitx5 auxDown 状态提示),测试断言
需同步更新为 FallbackShow。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 20:48:49 +08:00
aeoformandClaude Opus 4.7 57a4919712 feat(linux): fcitx5 候选框听写状态提示 + AppImage 插件自动安装 + 热键启动容错
- fcitx5 插件新增 SetAuxDown/ClearAuxDown DBus 接口,在候选词列表下方
  显示听写状态文字(收音中→识别中→润色中→已插入),切窗口自动跟随焦点
- 优先使用当前焦点 IC 展示 auxDown,失焦 IC 降级兜底,避免面板不渲染
- flushUI 排空旧事件后再设 auxDown,防止按键事件竞态覆盖状态文字
- start_dictation_signal_listener 启动时等待 fcitx5 最多 30s,监听
  NameOwnerChanged 在 fcitx5 重启后自动重新同步快捷键绑定
- AppImage 打包 libopenless.so 为资源,启动时检测缺失自动安装到
  ~/.local/lib/fcitx5/ 和 ~/.local/share/fcitx5/addon/
- Linux 胶囊窗口不在 Wayland/X11 显示,状态完全走 fcitx5 输入面板

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 20:40:40 +08:00
aeoformandClaude Opus 4.7 39ce12c8e9 Merge remote-tracking branch 'origin/beta' into beta — resolve coordinator.rs conflict
- Accept upstream's show_capsule_window_for_recording wrapper + CapsuleShowStrategy
  (our Linux fallback logic is subsumed by the upstream strategy pattern)
- Keep Linux on NoActivate strategy; show_capsule_window_no_activate returns true
  on Linux to suppress capsule window (no popup on Wayland/fcitx5)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 21:50:58 +08:00
aeoformandClaude Opus 4.7 f043176d19 fix(linux): correct Fn hotkey mapping from Super_L to RightControl
Fn key does not generate a standard X11 keysym on Linux. The previous
mapping to Super_L (0xffeb) was incorrect and would bind the
Windows/Super key instead. Map to RightControl (0xffe4) to match the
existing fallback convention used on Windows (VK_RCONTROL) and in the
coordinator's hotkey matching logic.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 11:03:46 +08:00
aeoformandClaude Opus 4.7 9cd8b9a8fc fix(linux): clear previous hotkey trigger when switching between custom combo and preset modifier
setHotkey/setHotkeyRaw now clear hasCustomDictationKey_ to prevent stale custom
combo from persisting after switching to a preset modifier. setCustomDictationTrigger
now persists TriggerRawSym=TriggerRawStates=0 to raw config so the old raw
trigger doesn't reload after fcitx5 restart.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 09:53:25 +08:00
aeoformandClaude Opus 4.7 416da6038c fix(linux): allow single-key custom triggers in fcitx5 plugin sync
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 09:45:57 +08:00
aeoformandClaude Opus 4.7 088e2ab3d9 fix(ci): derive RPM fcitx5 plugin path from cmake detection
Map Debian multiarch addon dir to /usr/lib64 for RPM packages.
Uses FCITX_RPM_ADDON_DIR derived from cmake output instead of
hardcoded paths.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 09:38:21 +08:00
aeoformandClaude Opus 4.7 60250c839d fix(linux): support custom combo hotkeys and surface fcitx5 errors
- Add SetCustomDictationTrigger(s) to plugin for custom key combos
- Add fcitx5 availability check before hotkey install, surface error
- Sync custom dictation combo to fcitx5 plugin from coordinator

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 09:32:12 +08:00
aeoformandClaude Opus 4.7 323dbed401 fix(linux): add QA and translation modifier hotkey support to fcitx5 plugin
Extend the fcitx5 plugin with SetQaHotkeyRaw/SetTranslationHotkeyRaw
DBus methods and corresponding signals, so that QA panel toggle and
translation modifier hotkeys work on Linux (not just the main dictation
hotkey). Built-in Shift key translation modifier also handled by the
plugin. Document DBus security model in plugin header.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 09:21:38 +08:00
aeoformandClaude Opus 4.7 b349a4dcba fix(linux): remove dead rdev code and leftover Wayland references
Remove 290 lines of unused rdev listener code from the Linux hotkey
platform module, drop the rdev dependency from Cargo.toml, and clean up
capsule_window_visible init leftover. Update doc comments and frontend
i18n to reflect the unified fcitx5-only path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 09:01:56 +08:00
aeoformandClaude Opus 4.7 acfdd39481 fix(linux): unify on fcitx5 for both Wayland and X11, drop enigo
fcitx5 插件 Wayland/X11 都可使用,不再为 X11 单独维护 enigo XTest。
Linux 统一走 fcitx5 CommitText 直写,插件不可用时降级到剪贴板拷贝。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 08:53:06 +08:00
aeoformandClaude Opus 4.7 dbae3b7a5f fix(linux): correct fcitx5 InputContext::destroyed signal connection syntax
ic->connect(ic->destroyed, ...) is invalid — InputContext has no two-arg
connect overload. Use ic->destroyed.connect(callback) directly, which
calls Signal<void()>::connect. Also simplified ScopedConnection storage
from unique_ptr to direct member (ScopedConnection is move-assignable).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 08:53:06 +08:00
aeoformandClaude Opus 4.7 07132c2087 fix(linux): track fcitx5 InputContext lifetime via destroyed signal
Prevents savedIc_ from becoming a dangling pointer by connecting to the
InputContext::destroyed signal when the IC is saved. On destruction the
pointer is cleared automatically, and commitText falls through to
foreachFocused for the current focused IC.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 08:53:06 +08:00
aeoformandClaude Opus 4.7 85c2cafcad fix(ci): use cmake-determined plugin install path in deb
FCITX_INSTALL_ADDONDIR varies by distro (multiarch Ubuntu →
/usr/lib/x86_64-linux-gnu/fcitx5/; Fedora → /usr/lib64/fcitx5/;
Arch → /usr/lib/fcitx5/). Extract from cmake cache at build time
via GITHUB_ENV instead of hardcoding.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 08:53:06 +08:00
aeoformandClaude Opus 4.7 dfced4ff1d fix(linux): sync fcitx5 plugin hotkey binding on update
When ensure_modifier_hotkey_monitor finds an existing monitor and
updates the rdev/CGEventTap binding, it must also sync the new binding
to the fcitx5 plugin on Wayland. Previously the early return skipped
this, leaving plugin and coordinator out of sync after a hotkey change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 08:53:06 +08:00
aeoformandClaude Opus 4.7 4f1e457cfa feat(ci): build fcitx5 plugin into Linux deb/rpm packages
- Add "Build fcitx5 plugin" step to release-tauri.yml: compiles
  the C++ plugin via cmake, copies .so + .conf to
  src-tauri/linux-fcitx5-plugin/ for the Tauri bundler.
- Override tauri build --config to include deb.files / rpm.files
  that place the plugin at /usr/lib/fcitx5/ so it's auto-detected
  after install.
- Add fcitx5, fcitx5-module-dbus as deb/rpm dependencies.
- Local builds unaffected (config is CI-only via --config flag).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 08:53:06 +08:00
aeoformandClaude Opus 4.7 a1b7a2a1f9 fix(linux): cfg-gate linux_fcitx module + skip capsule window on Wayland
- Add #[cfg(target_os = "linux")] to mod linux_fcitx to fix macOS/Windows
  CI compilation (dbus crate is Linux-only).
- Wayland: skip capsule window show/hide entirely in emit_capsule so the
  target app never loses keyboard focus. Text is committed via fcitx5
  plugin commit_string — no window means the compositor forwards the
  commit to the right app.
- X11 keeps existing behavior (show capsule window once per session).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 08:53:06 +08:00
aeoformandClaude Opus 4.7 2912aefed5 feat(linux): replace enigo with fcitx5 plugin for Wayland input
- fcitx5 C++ plugin (scripts/linux-fcitx5-plugin/) with DBus interface:
  CommitText, SetHotkey/SetHotkeyRaw, DictationKeyEvent signal
- linux_fcitx.rs: DBus client to call plugin from Rust
- coordinator/dictation.rs: Wayland insertion via fcitx5 commit_text,
  streaming insert enabled on Wayland
- insertion.rs: fcitx5 commit_text on Linux with clipboard fallback
- unicode_keystroke.rs: Linux path uses fcitx5 commit_text
- Capsule window show-once on Linux to avoid stealing focus

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 08:53:06 +08:00