[Bug] Windows 10 开启亚克力背景模糊时拖拽窗口出现严重延迟卡顿 #3

Open
opened 2026-10-19 15:16:53 +00:00 by chino · 3 comments

运行环境

  • 操作系统:Windows 10
  • 版本:0.1.5。
  • 配置条件:默认配置开启了亚克力模糊(background_blur: true, background_opacity: 0.88)。

问题描述

在 Windows 10 下点击并拖拽标题栏或分栏顶部移动窗口时:

  • 窗口拖动出现明显的延迟与顿挫感。
  • 鼠标指针已经移动到目标位置,但窗口呈现“慢动作”缓缓追随,延迟可达数秒。
  • 若在配置中将 background_blur 设为 false 或将 background_opacity 设为 1.0,拖动立即恢复流畅。

示例视频


原因分析

  1. 系统机制与 API 差异:

    • Windows 11 对 DWM(桌面窗口管理器)的混成树管线进行了重构,亚克力与模态窗口移动完全解耦。
    • Windows 10(Build < 22000)下,GPUI 依赖未公开的私有 API SetWindowCompositionAttribute 开启亚克力模糊(ACCENT_ENABLE_ACRYLICBLURBEHIND,state 4)。
  2. DWM 模态移动循环性能瓶颈:

    • 当开始拖动窗口时,系统进入模态移动循环(WM_ENTERSIZEMOVE ~ WM_EXITSIZEMOVE)。
    • Windows 10 的 DWM 在模态移动期间,ACCENT_ENABLE_ACRYLICBLURBEHIND 会在每一个像素坐标变化时,强制同步抓取桌面背景、进行下采样高斯模糊与噪点计算。
    • 与此同时,GPUI 的 Windows 后端在模态循环期间启动了 10ms 频率的高频定时器(WM_TIMER),持续触发 DirectX Present 绘制。
    • 极高开销的同步模糊与高频重绘请求堆塞了 Win32 消息队列,导致窗口在拖动时严重滞后于鼠标。

建议修改方案

参考 Windows Terminal 以及各类 Win32 Fluent / Electron 亚克力应用的成熟实践:在模态移动/缩放循环期间临时降级模糊效果。

  1. 对 Windows 10 进行窗口过程子类化(Subclassing):
    • 通过 RtlGetVersion 判断系统版本,仅对 Windows 10(Build < 22000)启用该优化。
    • 监听 WM_ENTERSIZEMOVE(0x0231):如果当前启用了模糊,将 Accent 状态由 4(ACCENT_ENABLE_ACRYLICBLURBEHIND)临时切换为 2(ACCENT_ENABLE_TRANSPARENTGRADIENT)。此时窗口仍保持透明度与 DirectComposition 渲染,但 DWM 停止高开销的模糊采样,拖动恢复 100% 跟手。
    • 监听 WM_EXITSIZEMOVE(0x0232):拖拽结束释放鼠标时,将 Accent 状态恢复为 4,并通过 SetWindowPos(SWP_FRAMECHANGED) 通知 DWM 重新渲染亚克力模糊。
    • 在 WM_NCDESTROY 和析构时清理 Window Property 与 Hook。

修复效果验证

  • Windows 10 下拖动窗口完全跟手,达到显示器原生高刷新率无延迟。
  • 鼠标松开后亚克力模糊瞬间恢复,视觉过渡自然。
  • Windows 11、Linux 与 macOS 均保持原有逻辑,不受任何影响。

(由AI分析总结,并在本地验证可行。)

### 运行环境 - **操作系统**:Windows 10 - **版本**:0.1.5。 - **配置条件**:默认配置开启了亚克力模糊(`background_blur: true`, `background_opacity: 0.88`)。 ### 问题描述 在 Windows 10 下点击并拖拽标题栏或分栏顶部移动窗口时: - 窗口拖动出现明显的延迟与顿挫感。 - 鼠标指针已经移动到目标位置,但窗口呈现“慢动作”缓缓追随,延迟可达数秒。 - 若在配置中将 `background_blur` 设为 `false` 或将 `background_opacity` 设为 `1.0`,拖动立即恢复流畅。 ### 示例视频 <video src="attachments/706c9759-3fde-4254-9223-2f6206295fe7" title="Screen Video.mp4" controls></video> --- ### 原因分析 1. **系统机制与 API 差异**: - Windows 11 对 DWM(桌面窗口管理器)的混成树管线进行了重构,亚克力与模态窗口移动完全解耦。 - Windows 10(Build < 22000)下,GPUI 依赖未公开的私有 API `SetWindowCompositionAttribute` 开启亚克力模糊(`ACCENT_ENABLE_ACRYLICBLURBEHIND`,state 4)。 2. **DWM 模态移动循环性能瓶颈**: - 当开始拖动窗口时,系统进入模态移动循环(`WM_ENTERSIZEMOVE` ~ `WM_EXITSIZEMOVE`)。 - Windows 10 的 DWM 在模态移动期间,`ACCENT_ENABLE_ACRYLICBLURBEHIND` 会在每一个像素坐标变化时,强制同步抓取桌面背景、进行下采样高斯模糊与噪点计算。 - 与此同时,GPUI 的 Windows 后端在模态循环期间启动了 10ms 频率的高频定时器(`WM_TIMER`),持续触发 DirectX `Present` 绘制。 - 极高开销的同步模糊与高频重绘请求堆塞了 Win32 消息队列,导致窗口在拖动时严重滞后于鼠标。 --- ### 建议修改方案 参考 Windows Terminal 以及各类 Win32 Fluent / Electron 亚克力应用的成熟实践:**在模态移动/缩放循环期间临时降级模糊效果**。 1. **对 Windows 10 进行窗口过程子类化(Subclassing)**: - 通过 `RtlGetVersion` 判断系统版本,仅对 Windows 10(`Build < 22000`)启用该优化。 - 监听 `WM_ENTERSIZEMOVE`(0x0231):如果当前启用了模糊,将 Accent 状态由 `4`(`ACCENT_ENABLE_ACRYLICBLURBEHIND`)临时切换为 `2`(`ACCENT_ENABLE_TRANSPARENTGRADIENT`)。此时窗口仍保持透明度与 DirectComposition 渲染,但 DWM 停止高开销的模糊采样,拖动恢复 100% 跟手。 - 监听 `WM_EXITSIZEMOVE`(0x0232):拖拽结束释放鼠标时,将 Accent 状态恢复为 `4`,并通过 `SetWindowPos(SWP_FRAMECHANGED)` 通知 DWM 重新渲染亚克力模糊。 - 在 `WM_NCDESTROY` 和析构时清理 Window Property 与 Hook。 ### 修复效果验证 - Windows 10 下拖动窗口完全跟手,达到显示器原生高刷新率无延迟。 - 鼠标松开后亚克力模糊瞬间恢复,视觉过渡自然。 - Windows 11、Linux 与 macOS 均保持原有逻辑,不受任何影响。 (由AI分析总结,并在本地验证可行。)
Owner

那我知道问题了。没有对10做优化。api接口不一样。我看看怎么更新。

那我知道问题了。没有对10做优化。api接口不一样。我看看怎么更新。
Owner

Fixed in 0.1.7: https://github.com/ELY-Open-Source/ELYTerminal/releases/tag/v0.1.7

On Windows 10 (builds below 22000), when a blurred window starts to move or size, ELYTerminal switches it to the clear accent, and back to acrylic when it rests, as you proposed. Windows 11 keeps acrylic throughout. I tested the switch on Windows 11 with the check forced; I had no Windows 10 machine. If dragging still lags, tell me here.

已在 0.1.7 修复:https://github.com/ELY-Open-Source/ELYTerminal/releases/tag/v0.1.7

Windows 10(build 22000 以下)开启模糊时,窗口开始移动或缩放即切换为透明 accent,停下后恢复亚克力,按你的方案实现;Windows 11 保持不变。我在 Windows 11 上强制验证了切换,手边没有 Windows 10 实机。如果拖动仍然卡顿,请在这里告诉我。

The project now lives on GitHub / 项目已迁至 GitHub:https://github.com/ELY-Open-Source/ELYTerminal

Fixed in 0.1.7: https://github.com/ELY-Open-Source/ELYTerminal/releases/tag/v0.1.7 On Windows 10 (builds below 22000), when a blurred window starts to move or size, ELYTerminal switches it to the clear accent, and back to acrylic when it rests, as you proposed. Windows 11 keeps acrylic throughout. I tested the switch on Windows 11 with the check forced; I had no Windows 10 machine. If dragging still lags, tell me here. 已在 0.1.7 修复:https://github.com/ELY-Open-Source/ELYTerminal/releases/tag/v0.1.7 Windows 10(build 22000 以下)开启模糊时,窗口开始移动或缩放即切换为透明 accent,停下后恢复亚克力,按你的方案实现;Windows 11 保持不变。我在 Windows 11 上强制验证了切换,手边没有 Windows 10 实机。如果拖动仍然卡顿,请在这里告诉我。 The project now lives on GitHub / 项目已迁至 GitHub:https://github.com/ELY-Open-Source/ELYTerminal
Author

没有问题了,感谢作者

没有问题了,感谢作者
Sign in to join this conversation.
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ZacharyZhang-NY/ELYTerminal#3