🐛 fix(window): 修复 Windows 任务栏恢复最大化窗口后字体保持过大

- 问题根因:9848b8b2 禁用 maximised+restore 的 toggle 路径属于过度修复,导致从任务栏点击恢复最大化窗口时 viewport drift 无人修复
- maximised 状态下 Windows API 拒绝 SetSize nudge,唯一可行的修复是 Unmaximise → Maximise 切一次,此前被剪掉
- shouldToggleMaximisedWindowForScaleFix 在 restore + drift 时重新允许 toggle,注释说明去重保护链路
- 重复 toggle 由 inFlight 互斥 + 700ms 冷却 + ratio-change 在 minimisedSeen 上下文合并到 activationTimer 共同防御
- 拆分测试断言:shouldApplyWindowsScaleFix 与 shouldToggleMaximisedWindowForScaleFix 各自独立覆盖 restore 场景
This commit is contained in:
Syngnat
2026-05-14 12:31:19 +08:00
parent f94a0429d5
commit 235bc99846
2 changed files with 12 additions and 2 deletions

View File

@@ -20,7 +20,13 @@ describe('windowStateUi', () => {
it('applies the Windows scale fix when a minimized taskbar window is restored with viewport drift', () => {
expect(shouldApplyWindowsScaleFix('restore', true)).toBe(true);
expect(shouldApplyWindowsScaleFix('restore', false)).toBe(false);
expect(shouldToggleMaximisedWindowForScaleFix('restore', true)).toBe(false);
});
it('toggles maximised windows on restore so taskbar-restored fonts return to the correct size', () => {
// maximised 状态下 OS 拒绝 SetSize nudge唯一可行的修复是切一次 maximise
// 重复触发由 inFlight 互斥 + 700ms 冷却 + ratio-change 合并到 activationTimer 防御。
expect(shouldToggleMaximisedWindowForScaleFix('restore', true)).toBe(true);
expect(shouldToggleMaximisedWindowForScaleFix('restore', false)).toBe(false);
});
it('debounces resize-triggered Windows scale checks until window transitions settle', () => {

View File

@@ -8,10 +8,14 @@ export const shouldApplyWindowsScaleFix = (
hasViewportScaleDrift: boolean,
): boolean => (reason === 'ratio-change' || reason === 'restore') && hasViewportScaleDrift;
// maximised 窗口在 Windows 上无法通过 SetSize nudge 修复 viewport driftOS 拒绝 resize 已 maximized 窗口),
// 唯一能让 WebView2 重新计算缩放的办法是 Unmaximise → Maximise 切换一次。restore 场景(任务栏点击恢复)
// 必须允许这条路径,否则用户从最小化状态恢复后字体会保持错误大小。重复触发由 inFlight 互斥与 lastFixAt
// 冷却 + checkDevicePixelRatio 在 minimisedSeen 上下文转发到 activationTimer 共同防御,无需额外禁用 toggle。
export const shouldToggleMaximisedWindowForScaleFix = (
reason: WindowScaleFixReason,
hasViewportScaleDrift: boolean,
): boolean => reason === 'ratio-change' && hasViewportScaleDrift;
): boolean => (reason === 'ratio-change' || reason === 'restore') && hasViewportScaleDrift;
export const resolveWindowsScaleCheckDelayMs = (trigger: WindowsScaleCheckTrigger): number =>
trigger === 'resize' ? 240 : 0;