fix(windows): 恢复胶囊四边 clamp + 工作区定位,修被回退的 #470 (#689)#690
Conversation
#470 曾用 fab9651(+4824080 防溢出)加入「四边 clamp + 工作区(rcWork,避开任务栏) 定位」,被 Android 移植 commit 1ea467a 回退:ForegroundMonitor 丢了 work_* 字段、 position_capsule_bottom_center 退回只夹上边 `y.max(mon.top)`(x/下/右不夹、不避任务栏)、 clamp_to_monitor 沦为死码、专用单测被删。多显示器/负坐标/异常 DPI 下胶囊可能被算到 屏幕外或压在任务栏上。 - ForegroundMonitor 重新加回 work_left/top/right/bottom,foreground_window_monitor 从 mi.rcWork 填充; - position_capsule_bottom_center 改回用 clamp_to_monitor 四边夹工作区(取不到 rcWork 退回整屏); - 恢复 clamp_to_monitor 的 3 个纯函数单测(on-screen 不动 / 右下溢出收回 / 右缘内溢收回)。 clamp_to_monitor 本体一直在(含 saturating_sub 防溢出),只是没被调用。Windows 结构 + rcWork 由 CI 编译验证;需 Windows 真机确认多屏下胶囊不再出屏/压任务栏。
|
Claude finished @appergb's task in 2m 29s —— View job Code Review: 恢复胶囊四边 clamp + 工作区定位 (#470 回退修复)Todo List
(1)
|
| 情形 | 条件值 | 行为 |
|---|---|---|
| 正常填充(rcWork 有效) | true |
使用工作区,避开任务栏 ✓ |
Default::default() 零初始化未被覆盖(理论上不可能) |
0 > 0 = false |
退回整屏 ✓ |
| 任务栏自动隐藏 / 无任务栏(rcWork == rcMonitor) | true |
使用 rcWork(等价整屏)✓ |
| 极端异常(rcWork 为负或倒置矩形) | false |
退回整屏 ✓ |
clamp_to_monitor 本身还用 saturating_sub 防止区域比窗口更小时的减法溢出(lib.rs:1835-1836),双重保护。
测试用例
3 个纯函数测试覆盖了核心分支,且三平台均可运行:
| 测试 | 输入 | 期望 | 逻辑覆盖 |
|---|---|---|---|
leaves_on_screen_position_untouched |
(800,900) in 1920×1040 | (800,900) | 无需 clamp |
pulls_back_off_screen_right_and_bottom |
(2000,1200) | (1656,914) | 右+下都溢出 |
pulls_back_when_right_edge_overflows_inside_area |
(1800,500) | (1656,500) | 左上在内但右缘溢出 |
缺少的测试场景(不影响本 PR 合并,仅供参考):
- 负坐标显示器(
area_left < 0),如左侧副屏 - 工作区比胶囊更窄时
max(area_left)分支(面积极小退化情形)
总体评价
✅ 可以合并(待 Windows CI 绿灯)
三个审核点均无问题:
rcWork由GetMonitorInfoW一次调用填充,字段访问正确。- X 居中用
rcMonitor、Y/全局 clamp 用rcWork是合理的策略,与 [Windows] [bug] 语音输入不显示录音胶囊 #470 原意一致。 - 兜底逻辑(空矩形检测 + 退回整屏)健壮,
saturating_sub防溢出已到位。
代码改动极小(恢复已有函数的调用,新增 4 个结构体字段),改动风险低,单测清晰。唯一外部依赖是 Windows 真机验证多屏/负坐标场景,这在 PR 描述中已说明。
PR Reviewer Guide 🔍(Review updated until commit 68b3111)Here are some key observations to aid the review process:
|
审核指出原 fab9651 的 5 个 clamp 单测只恢复了 3 个,漏掉的恰是本 PR 主打的两类 场景:负原点多显示器(左侧副屏)与工作区避让任务栏。补回这两个纯函数单测。
|
Persistent review updated to latest commit 68b3111 |
User description
关联 issue
Closes #689(#470 的四边 clamp 回退)
问题
多显示器 / 负坐标 / 异常 DPI 下,Windows 胶囊可能被定位到屏幕外或压在任务栏上。#470 曾用
fab9651(+4824080防溢出)加入「四边 clamp + 工作区(rcWork)定位」,被 Android 移植 commit1ea467a回退:ForegroundMonitor丢失work_*字段;position_capsule_bottom_center退回只夹上边y.max(mon.top)(x/下/右不夹、不避任务栏);clamp_to_monitor沦为死码(本体仍在lib.rs:1823,仅 test import 引用),单测被删。改动(恢复 fab9651,单一职责)
ForegroundMonitor加回work_left/top/right/bottom,foreground_window_monitor从mi.rcWork填充;position_capsule_bottom_center改回用clamp_to_monitor四边夹工作区(取不到 rcWork 退回整屏矩形);clamp_to_monitor的 3 个纯函数单测。clamp_to_monitor本体(含saturating_sub防溢出)一直在,只是没被调用。测试
本地 macOS 只能编译非 Windows 分支;
ForegroundMonitor.work_*+rcWork是 Windows-only 代码,由 CI 的 Windows 构建编译验证,并需 Windows 真机确认多屏下胶囊不再出屏/压任务栏。PR Type
Bug fix, Tests
Description
Restored work_* fields in ForegroundMonitor from rcWork for taskbar avoidance
Used clamp_to_monitor with work area to prevent capsule positioning off-screen
Restored 5 unit tests covering negative origin multi-monitor and taskbar avoidance
Diagram Walkthrough
File Walkthrough
lib.rs
Restore capsule clamp to work area with unit testsopenless-all/app/src-tauri/src/lib.rs
ForegroundMonitor
work area
negative origin, taskbar)