feat(dictation): mouse middle/side buttons with Hold refcount (split from #724)#727
feat(dictation): mouse middle/side buttons with Hold refcount (split from #724)#727HKLHaoBin wants to merge 15 commits into
Conversation
Split from Open-Less#724: Win/macOS global mouse hooks, prefs toggles, HoldSourceTracker for multi-source hold release. Linux evdev path deferred to PR3. Fixes Open-Less#718 (partial: mouse triggers). Co-authored-by: Cursor <cursoragent@cursor.com>
PR Reviewer Guide 🔍(Review updated until commit 8027eca)Here are some key observations to aid the review process:
|
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit 71787ba |
|
稍等,我处理一下ci问题。 |
Felix201209
left a comment
There was a problem hiding this comment.
方向对、拆得也清楚,但有一个会影响使用的 HIGH bug 必须先修,所以暂时 request changes 🙏
🔴 HIGH:按住鼠标键时禁用鼠标听写 → 听写卡死直到重启
mouse_dictation.rs + coordinator/hotkey_loops.rs(update_mouse_dictation_binding_now)
复现(Hold 模式):
- 按住鼠标中键 →
Pressed→hold_sources.press(MouseMiddle)→ count=1 → 听写开始; - 此时在设置里把"中键听写"关掉;
update_mouse_dictation_binding_nowdrop 掉 monitor(ACTIVE_MOUSE=None),但从不重置hold_sources;- 物理松开按键时
handle_button已经收不到事件了 →handle_released_edge永不触发 →active_count永远停在 1; - 听写会话一直跑到 app 重启。
修法(二选一):update_mouse_dictation_binding_now 在禁用分支返回前调用 inner.hold_sources.reset();或 update_config 清 middle_held/side_held 之前,对当前仍持握的源补发合成 HotkeyEvent::Released。
🟠 与 #726 必然冲突(已批准,建议本 PR rebase 去重)
本 PR 在 types.ts 给 HotkeyTrigger 加了 leftCommand/leftShift/rightShift,并在 5 个语言文件加了对应文案——#726 在同样位置加了同样的行。#726 已经 approve、排在前面合并,所以本 PR 需要 rebase 到最新 beta 并删掉这几处重复新增,否则二合一时会冲突。
其它(不阻断,建议一并处理)
- 并发 press 的 TOCTOU(
coordinator/dictation.rs):press()后又单独读active_count(),键鼠几乎同时按下时两边都读到 2、都提前 return,begin_session漏调。建议直接用fetch_add的返回旧值判断"是否首次按下"。 - Linux 上鼠标听写 UI 可设但无效:
mouse_dictation.rs没有 Linux 平台实现,但RecordingInputSection.tsx在 Linux 仍显示开关。建议 toggle 加os !== 'linux'或start()在 Linux 返回错误(Linux 的鼠标触发本就归 #728 的 evdev)。 - dead i18n:
mouseMiddleDesc/mouseSideDesc五语言都翻译了,但SettingRow没传description,要么接上要么删掉。
测试缺口
hold_source_tracker / coordinator 的 happy path 测得不错,但缺:①上面"持握中禁用→卡死"的回归测试;②并发同时按下的 TOCTOU。建议至少给 HIGH 那条补个测试。
- Fix hold-mode tests to pass TriggerSource::KeyboardDictation - Hide mouse toggles on Linux until PR3 evdev - Remove PR1 side-modifier type/i18n/mock remnants - Complete mouse pref wire/deserialize/default in types.rs Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit 60672bf |
|
Persistent review updated to latest commit df02187 |
…ents Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit 645b35b |
…d source On update_config disable or Drop, swap held flags and send Released events so HoldSourceTracker does not retain stale mouse sources after prefs refresh. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit 2135949 |
|
Persistent review updated to latest commit 1bf48fe |
|
@Felix201209 已按 review 处理,请 re-review 🙏 HIGH(持握中禁用鼠标听写)
TOCTOU + debounce
其它
CI 请在 GitHub 上确认。 |
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit a841adc |
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit e866c41 |
|
Persistent review updated to latest commit f718636 |
|
Persistent review updated to latest commit 02a3b6f |
…nc to avoid nested runtime in tests
|
Persistent review updated to latest commit c85b192 |
…ock_on to avoid nested runtime
|
Persistent review updated to latest commit 0abc2c0 |
|
Persistent review updated to latest commit ed339a1 |
…okio worker thread
|
Persistent review updated to latest commit 8027eca |
|
@Felix201209 感谢 review 🙏 针对 review #4539504044 里的各点,最新 head 🔴 HIGH:持握中禁用鼠标听写 → 卡死采用你建议的「补发合成
🟠 与 #726 重复
其它建议
测试
CI 侧 nested-runtime 问题也已修完(f7186364 → 8027eca),Windows / macOS / Linux / Android check 均 pass。 方便的话请再扫一眼,谢谢! |
Felix201209
left a comment
There was a problem hiding this comment.
响应得又快又到位 👍 重新逐条核对后,上一轮提的问题全部解决,改判 approve ✅
- 🔴 HIGH 卡死 bug — 已解决:monitor drop(
mouse_dictation.rs的Drop→release_held_sources)、disable(sync_release_mouse_hold_sources先清零再.take())、rebind mid-hold(update_hotkey_binding首步调clear_active_hold_sources_on_hotkey_rebind)三条路径都会补发 Released / 重置 refcount,且有状态机 + 幂等保护,不会再卡。 - 🟠 与 #726 的冲突 — 已解决:
types.ts和五个语言文件里重复的leftCommand/leftShift/rightShift已移除,本 PR 现在只加mouseMiddle*/mouseSide*,#726 先合后不会冲突。 - 并发 press TOCTOU — 已解决:改用
swap(true)闩 +fetch_add返回旧值(prev_count==0才是首次按下),不再有单独active_count()读的竞态。 - 测试 — 已补齐:
hold_mode_*(含 disable-mid-hold、rebind-mid-hold、键鼠重叠)四个集成测试 +update_config/Drop两个单测,正好覆盖之前的缺口。CI 四平台全绿。
一个 LOW nit,留作后续即可、不拦合并:coordinator/hotkey_loops.rs 的 mouse_dictation_supervisor_loop 里那对互补 #[cfg(not(linux))] / #[cfg(linux)] 块体一样、等价于无 cfg,是重构残留,可直接去掉 cfg。
合并顺序提醒:本 PR 依赖 #726 的类型定义,请先合 #726 再合本 PR。另:beta 的 ruleset 只有 @jiangmuran 能 bypass,最终 merge 仍需他来点。
User description
摘要
Fixes #718(部分:鼠标触发)。
由已关闭的 #724 拆分而来(第 2/3 部分):独立 prefs 开关;Win/macOS 全局鼠标 hook;Hold 模式
HoldSourceTracker多源 refcount。Linux 输入走 PR3 evdev。可与 #726 并行审查/合并。关联:#718、#724。
修复 / 新增 / 改进
mouse_dictation+hold_source_trackerrefresh_mouse_dictation兼容
side_aware_combo、侧向录制 UI、Linux evdev测试计划
本地实机验证(回应 @jiangmuran CHANGES_REQUESTED):
cargo metadata --filter-platform aarch64-linux-android(stub 编译)npm run build请维护者:在真机验证鼠标触发;Linux 需 PR3 合并后复测。
PR Type
Enhancement, Tests
Description
Add mouse middle/side button dictation triggers
Track multiple Hold sources with refcount
Integrate into coordinator and settings
Add UI toggles and i18n for mouse buttons
Diagram Walkthrough
File Walkthrough
13 files
Implement HoldSourceTracker for multi-source holdAdd global mouse button dictation monitorIntegrate mouse dictation and hold sourcesHandle pressed/released edges with trigger sourceAdd mouse dictation bridge and supervisor loopsHook macOS mouse events for dictationRegister mouse_dictation module and start listenerAdd mobile stub for mouse dictationAdd mouse dictation preference fieldsAdd refresh_mouse_dictation to SettingsWriterPersist mouse dictation changes and call refreshAdd mouse dictation preference typesAdd mouse middle/side button toggle UI4 files
Add mouse_dictation_refreshes to test mockAdd hold mode integration testsAdd mouse dictation defaults to mock settingsAdd mouse dictation fields to test prefs5 files
Add English i18n for mouse dictation togglesAdd Japanese i18n for mouse dictation togglesAdd Korean i18n for mouse dictation togglesAdd Chinese i18n for mouse dictation togglesAdd Traditional Chinese i18n for mouse dictation toggles1 files