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 18 commits into
Conversation
PR Reviewer Guide 🔍(Review updated until commit 53450fc)Here are some key observations to aid the review process:
|
|
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 那条补个测试。
|
Persistent review updated to latest commit 60672bf |
|
Persistent review updated to latest commit df02187 |
|
Persistent review updated to latest commit 645b35b |
|
Persistent review updated to latest commit 2135949 |
|
Persistent review updated to latest commit 1bf48fe |
|
@Felix201209 已按 review 处理,请 re-review 🙏 HIGH(持握中禁用鼠标听写)
TOCTOU + debounce
其它
CI 请在 GitHub 上确认。 |
|
Persistent review updated to latest commit a841adc |
|
Persistent review updated to latest commit e866c41 |
|
Persistent review updated to latest commit f718636 |
|
Persistent review updated to latest commit 02a3b6f |
|
Persistent review updated to latest commit c85b192 |
|
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 仍需他来点。
appergb
left a comment
There was a problem hiding this comment.
Review note: this PR was previously approved and CI is green, but it is currently marked CONFLICTING against beta after related hotkey changes landed. It needs a rebase/conflict resolution before it can be merged.
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>
Co-authored-by: Cursor <cursoragent@cursor.com>
- 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>
…ents Co-authored-by: Cursor <cursoragent@cursor.com>
…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>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…nc to avoid nested runtime in tests
…ock_on to avoid nested runtime
…okio worker thread
Co-authored-by: Cursor <cursoragent@cursor.com>
8027eca to
5dc5b50
Compare
|
Persistent review updated to latest commit 5dc5b50 |
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit 98f90d1 |
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit 53450fc |
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 with independent prefs
Implement HoldSourceTracker for multi-source hold release refcount
Integrate with Win/macOS platform hooks and coordinator
Add i18n and UI toggles for mouse dictation
Include mobile stubs and tests
Diagram Walkthrough
File Walkthrough
3 files
Add mouse dictation refresh mockAdd mouse dictation fields to mock settingsAdd mouse dictation fields to test prefs11 files
Add refresh_mouse_dictation to settings persistenceIntegrate mouse_dictation and hold_sources into coordinatorRefactor pressed/released edge to accept TriggerSourceAdd mouse dictation supervisor, bridge, hold source releaseImplement HoldSourceTracker with refcount logicDispatch mouse events on macOS event tapRegister mouse_dictation module and start listenerProvide mobile stub for mouse dictationImplement global mouse dictation monitor (Win/macOS)Add mouse dictation fields to UserPreferencesAdd mouse dictation toggle UI1 files
Add mouse_middle/side_button_dictation prefs5 files
Add English i18n for mouse dictation togglesAdd Japanese i18n for mouse dictation togglesAdd Korean i18n for mouse dictation togglesAdd Simplified Chinese i18n for mouse dictation togglesAdd Traditional Chinese i18n for mouse dictation toggles