Skip to content

WindowMark v0.4.9

Choose a tag to compare

@yakoye yakoye released this 08 Sep 08:35
· 52 commits to main since this release

rc1 说过「z 序没有根治,正式版会换掉底层模型」。换掉了。

边框不再和系统抢 z 序

以前每个窗口配一个边框窗口,各自调 SetWindowPos 往全局 z 序链表里插。那条链是全局
共享的、任何进程都能改的,调整还会静默失败——返回 TRUE、GetLastError() 为 0、状态
纹丝不动。后一个边框的插入打乱前一个刚排好的位置,窗口越多越乱,v0.4.5 到 v0.4.9-rc1
那几轮「边框不全」「切换时闪一下」全出在这里。

现在每块显示器一个透明画布,所有边框画在上面。「边框该排第几」这个时序问题变成了
「哪几段该画」的几何问题:非激活窗口的边框环减去排在它上面的窗口,剩下的才画。几何
计算不会失败,也没有竞争。

rc1 里那一整套 z 序操作——精确锚定、被拒后逐级退让、推不动就重建、守望轮询——全部删掉。

拖动跟手:CPU 从 98% 降到 20%

拖动窗口时边框落后十几个像素,还有近一半时间整条画不出来。量下来是一个核被占满:边框
每秒重画 30 次,每次 34ms。三处修,每处都先量后改:

  • 圆角自己栅格化,不再用 Direct2D。 原本每段可见部分都要把整个环的路径栅格化一遍,
    一个窗口每帧六段就是六遍,实测每段 2.15ms。改用圆角矩形的距离公式逐像素算,只碰环
    那一圈带子——每段降到 0.044ms。
  • 脏区只算变了的段。 原本取所有边框段的包围盒,拖一个窗口却要每帧重贴大半个屏幕
    (2.41 百万像素,屏幕总共 3.69 百万)。改成和上一帧比出增删——降到 0.68 百万。
  • 几何事件不再整取桌面快照。 每秒上百个事件,每个都遍历全部窗口、每个可见窗口两次
    跨进程 DWM 查询,实测每次 2.4ms。改成缓存快照、只刷新动了的那一条——每秒 260ms
    降到 28ms
    。

结果:边框重画频率 30 次/秒 → 125 次/秒(跟得上鼠标的报告率),实测滞后从中位 12px
降到 0px,「整条边框没画出来」的采样从 47% 降到 0%。

最大化的窗口不再画边框

它贴着工作区边缘,外面没有画边框的那几像素;夹回屏幕内之后边框和窗口边界完全重合,
实测四条边一个像素都露不出来。而它正是 v0.4.5–v0.4.8 那三轮「溢出到任务栏」「跨屏跑到
另一块屏」的源头——为一个看不见的东西修了三个版本。置顶窗口例外。

圆角

默认圆角,可选直角。直角走原来的像素填充,一个像素没动。圆角自己逐像素栅格化,抗锯齿
的过渡带宽度因此握在自己手里。设置里能调线宽增量和向窗口中心的偏移。

边框不对劲时,自己就能改

设置里「按类名调整」一组三个框,对应三种症状(类名用 WindowMarkInspect.exe 查):

症状 填哪个
这个窗口不该有边框却有 不画边框
该有边框却没有 强制画
它浮在上面,边框却盖了过去 视为置顶

另有一类:有些窗口把阴影画在自己的窗口矩形里,矩形比看得见的部分大一圈(实测 Windows 11
的托盘面板 15px,Qt 的贴图窗 14px,下边 32px),别人的边框就在它旁边多断那么宽。双击
measure_shadow_auto.bat,鼠标停在那个窗口上五秒,它自己量出来;加 --apply 直接写进
配置。

默认值换了一套

装上就有边框(以前默认关闭),线宽 3、偏移 -1、圆角自定义 12、圆角加宽 3。已有的
settings.conf 不受影响。

修复

  • 点一下桌面空白处,所有边框消失。 桌面窗口也能当前台,而它铺满整个虚拟桌面却
    谁都不挡——「前台盖住的地方不画别人的边框」这条推断遇到它就成了全屏遮挡。
  • 快速来回切换两个窗口后,别人的边框盖在最上面那个窗口上。 快照的遍历走的是活的
    z 序链表,途中有窗口被提到前面就再也遇不上——实测切七八次就能让前台窗口从快照里整个
    消失,而遮挡计算的两道保险都要按 hwnd 找到它。
  • MobaXterm 等 Delphi/VCL 程序的对话框被边框线切开。 事件层判断「是不是顶级窗口」
    只看 WS_CHILD,而这类对话框既带 WS_CHILD 又直接挂在桌面下,于是拖动它时一个事件
    都产生不了,遮挡计算还记着它的旧位置。
  • 边框和被它挡住的窗口之间有一像素的缝。 两块颜色正好齐平时,各自的抗锯齿边缘各占
    半像素,合起来就是一条缝。遮挡范围往里咬一像素,边框钻到对方边缘底下。
  • Word / Notepad++ 的查找对话框被边框横穿。
  • 切换窗口时重叠处的边框滞后。

完整清单见 CHANGELOG.md。