Skip to content

fix: make mouse-triggered wheel actions follow the trigger window safely - #181

Merged
SoftBlack42 merged 1 commit into
mainfrom
codex/pr178-wheel-focus
Oct 3, 2026
Merged

SoftBlack42 merged 1 commit into
mainfrom
codex/pr178-wheel-focus

Conversation

@SoftBlack42

@SoftBlack42 SoftBlack42 commented Oct 3, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

本 PR 是对 PR #178(原作者提交)的安全修订与完整收口版本,旨在解决鼠标在后台窗口 B 上触发手势轮盘时,确保使用窗口 B 的配置,并将窗口动作安全定向至窗口 B;在动作执行前对目标窗口与前台焦点进行多层校验,若目标失效或焦点离开则安全取消,避免误发给此前的前台旧窗口 A。

本提交保留了原 PR 的核心交互意图,同时修复了原方案中暴露的竞态、会话漂移和焦点一致性缺陷。

核心变更与修复细节

  1. 会话目标快照与一次性解析贯穿:

    • 鼠标按下时按呼出点物理坐标解析顶层目标窗口快照(TargetWindowInfo 与 WheelFocusSession);
    • 在手势划动、轮盘展示和松手派发过程中维持同一快照,消除多次解析的不一致。
  2. 快速松手与 UI 排队竞态保护:

    • 松手时若轮盘展示回调尚未执行或因快速松手跳过,在动作入队前独立确认目标并完成对齐;
    • 若窗口对齐未成功,安全取消并丢弃动作,不降级回前台旧窗口 A 执行。
  3. 目标保护延伸至队列消费入口:

    • ActionExecutor 消费动作时(执行前)核验执行上下文有效性;
    • 实时读取 Win32 PID(绕过 150ms 缓存)与前台 HWND,焦点已切走或 PID 改变时安全取消,不强行抢回焦点。
  4. 入队动作快照不可变性:

    • 入队时克隆 action.Clone() 快照,用户或 UI 在队列等待期间修改动作或子动作不影响已提交执行内容。
  5. 鼠标触发与键盘触发严格隔离:

    • 键盘长按与非鼠标触发入口显式清理并隔离鼠标目标快照,完全保留原键盘长按逻辑,不继承鼠标悬停目标。
  6. 宿主暂停与会话失效关联:

    • 提取生产与测试共用的 App.ApplyPauseStateTransition,在暂停时同步调用 GestureController.OnHostPaused(),永久作废已排队会话;恢复后旧动作不复活,新合法动作正常执行。
  7. 无副作用测试套件:

    • 在 scratch/test_wheel_focus 中提供 18 项行为场景自动化验证;
    • 全程使用 Mock 隔离 SendInput、按键释放、音效与窗口激活,并加入 --test-instance 与独立临时 LOCALAPPDATA 守卫。

影响范围与兼容性说明

边界与实机验证注意

  • Win32 跨进程焦点受 UIPI、操作系统限制(如 LockSetForegroundWindow)及窗口权限约束。本修订采用保守激活机制(不注入 Alt、不篡改 Topmost),在执行前核验目标有效性与前台焦点对齐状态;当系统拒绝激活、焦点发生变化或会话失效时安全取消并丢弃动作,不进行无限重试,亦不强行抢回焦点。
  • 用户已在实机上对 R3 候选完成人工验收。主分支在基准上无新增提交,交互逻辑与 R3 严格一致,但涉及跨进程焦点的最终体验仍建议以实机验收为准。

预期变动文件 (Changed Files: 15)

  • CHANGELOG.md
  • WinPieGestures/ActionExecutor.cs
  • WinPieGestures/ActiveWindowHelper.cs
  • WinPieGestures/App.xaml.cs
  • WinPieGestures/GestureController.cs
  • WinPieGestures/MouseEventArgs.cs
  • WinPieGestures/MouseHook.cs
  • WinPieGestures/RawMouseEventArgs.cs
  • WinPieGestures/WheelFocusSwitcher.cs
  • WinPieGestures/WinPieGestures.csproj
  • WinPieGestures/WindowTaskbarHelper.cs
  • scratch/Directory.Build.props
  • scratch/test_wheel_focus/Program.cs
  • scratch/test_wheel_focus/README.md
  • scratch/test_wheel_focus/test_wheel_focus.csproj

- Switch foreground focus to mouse-hover target window safely before dispatching actions
- Verify target window existence, visibility, foreground alignment, and real PID at queue consumption
- Guarantee enqueued action snapshot immutability via cloning
- Invalidate pending execution session on gesture cancellation, disposal, new trigger, and host pause
- Isolate mouse wheel sessions from keyboard long-press trigger flows
- Add mock-isolated automated test suite in scratch/test_wheel_focus covering 18 scenarios
@SoftBlack42
SoftBlack42 merged commit de9dca9 into main Oct 3, 2026
1 check passed
@SoftBlack42 SoftBlack42 added the enhancement New feature or request label Oct 4, 2026
@ztzpro
ztzpro deleted the codex/pr178-wheel-focus branch October 11, 2026 03:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant