fix(desktop): 桌面客户端最大化窗口时光标卡死在 resize 形状prevent cursor stuck at resize shape when window is max… - #6610
Merged
SivanCola merged 2 commits intoJul 19, 2026
Conversation
…imized
When the Wails frameless window is restored maximized, the 6px edge-detection
zone in useWailsResizeFix coincides with the physical screen edges. Moving
the mouse to the top/right/top-right corner sets style.cursor to a resize
value that WebView2 never reliably reverts via style.cursor = "", leaving
the cursor stuck in resize shape until the app is restarted.
The fix adds a synchronous check at the top of the mousemove handler:
when outerDimensions ≈ screen.availDimensions (within 5px tolerance) the
window is maximised, so edge detection is skipped entirely and any stale
resize edge is cleared via removeProperty("cursor").
Fixes wailsapp/wails#1503 (same bug, project-specific manifestation).
Problem: Maximized Windows desktop windows could retain a resize cursor, while near-full normal windows could be misclassified as maximized by the size heuristic. Root cause: Cursor recovery was gated on Wails resizeEdge state, and maximization was inferred from outer and screen dimensions instead of the native window state. Fix: Share the native maximized state with the Windows controls, normalize stale resize cursors, preserve the remembered default cursor, and skip edge detection only for confirmed maximized windows. Add focused startup, transition, and near-full-size regression coverage. Verification: - pnpm exec tsx src/__tests__/wails-resize-fix.test.tsx - pnpm exec tsx src/__tests__/app-chrome-tabs.test.ts - pnpm run typecheck - pnpm test - pnpm run build - git diff --check Co-authored-by: SivanCola <32437197+SivanCola@users.noreply.github.com>
This was referenced Jul 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
修复:Wails 桌面客户端最大化窗口时光标卡死在 resize 形状
问题描述
当 Reasonix 桌面客户端(Wails v2.12 frameless 窗口)启动时恢复上次的最大化状态,且用户鼠标停留在屏幕顶部 / 右上角 / 右侧边缘时,光标会变为 resize 形状(
n-resize/ne-resize/e-resize),并且卡死在这个形状——移开鼠标后光标不会恢复到默认箭头。最小化再最大化也无法恢复。该问题只在 Reasonix 窗口内出现,其他应用正常。根因分析
触发条件(两层机制)
第一层 —— 原生 WM_NCHITTEST
Wails frameless 窗口保留了
WS_THICKFRAME样式以实现前端 resize。最大化后,原生WM_NCHITTEST经DefWindowProc在窗口边缘 6px 区域返回HTTOP/HTLEFT/HTRIGHT等 resize 命中码,Windows 将游标设为 resize 形状。这个操作发生在 JS 层加载之前。第二层 —— style.cursor = "" 无法触发 SetCursor 回退
useWailsResizeFixhook 的 mousemove handler 检测到鼠标处于边缘时,将document.documentElement.style.cursor设为"n-resize"等值;当鼠标离开边缘时,清除为""。但style.cursor = ""在<html>上留下cursor: ;(空值声明),Chromium/WebView2 的空值处理路径不触发SetCursor回退,导致原生 resize 游标残留。启动时卡死概率更高,因为 Vite 的 CSS
<link>异步加载期间html { cursor: default }(styles.css第 1890 行)可能尚未生效,清空内联样式后无规则兜底。影响范围
修复方案
只修改一个文件:
desktop/frontend/src/lib/useWailsResizeFix.ts在
onMouseMovehandler 的最开头添加最大化状态检测:为什么这样改
outerHeight/outerWidth ≈ availHeight/availWidthmonitorInfo.rcWork(见window.go第 272-283 行),outer 尺寸与工作区尺寸一致。同步检测,无 IPC 延迟,无竞态≤ 5px 容差removeProperty("cursor")style属性中删除 cursor 声明,强制 WebView2 重新走完整的 CSS 级联计算路径。与style.cursor = ""不同,removeProperty让 WebView2 正确触发SetCursor回退flags.resizeEdge = undefinedreturnstyle.cursor从头到尾不被设成 resize 值不变的部分
enableResize = false:继续禁用 Wails 内置 handler(其使用outerWidth存在 ZoomFactor 坐标不匹配问题)innerWidth/innerHeight边缘检测逻辑:修复 ZoomFactor ≠ 1 时的坐标不匹配flags和style.cursor改动量
desktop/frontend/src/lib/useWailsResizeFix.ts最终效果
本地验证(windows11)
pnpm build(前端) ✅ 4295 modules transformed, 8.75stsx前端单元测试(8 项) ✅ 8 passed, 0 failedwails build(桌面客户端) ✅ build/bin/reasonix-desktop.exe 生成成功