Repository navigation
Conversation
旧实现启动时对主屏做一次 BitBlt 快照(SM_CXSCREEN 尺寸 + 原点 (0,0)), 导致两个问题:副屏坐标落在缓冲区外,取色恒返回 #FFFFFF;快照停在 启动那一刻,宿主界面来不及隐藏的内容被采进结果。 - 改用 DXGI Desktop Duplication 逐帧实时采样:GPU 路径不碰 GDI 回读 (实测 BitBlt 回读闪光标、逐点 GetPixel 卡顿),桌面帧天然不含光标 - 9x9 采样区 CopySubresourceRegion 到 staging 后读取,不做整屏回读; 帧预算 33ms,WAIT_TIMEOUT 沿用上一帧,跨屏/ACCESS_LOST 自动重建 - 放大镜重绘改由帧泵循环驱动(画面更新或光标移动),替代 30FPS WM_TIMER;桌面静止时阻塞在 AcquireNextFrame 上,不空转 - 保留快照回退(Win7/RDP/旋转屏),尺寸与原点改为虚拟桌面 (SM_*VIRTUALSCREEN),回退模式下副屏同样可用 - 放大镜窗口按光标所在显示器钳位(旧实现按主屏尺寸算边界, 光标在左侧/上方副屏时窗口瞬移) - WM_PAINT 每帧创建/销毁 81 组画刷画笔改为 stock DC_BRUSH + 一遍网格线 - 新增验收脚本 test/verify-color-picker.js(Electron 宿主,运行时 探测副屏布局,断言副屏取色与实时取样) - binding.gyp 新增 d3d11.lib / dxgi.lib macOS 侧核对无需改动:取色器为逐帧 CGWindowListCreateImage 实时采样、 走 CG 全局坐标,不存在上述问题。
均为 GDI 渲染细节问题(旧实现即存在): - 网格最右/最下一条线画在 x/y=144,而客户区只有 144px(列 0~143), 整条线落在客户区外被裁掉,右/下边框消失。钳到 143 绘制 - 准心 2px 黑框:GDI 宽笔触居中渲染,被相邻 1px 白框盖掉内侧一半后 右/下只剩一丝。改为两条 1px 描边叠加,四侧厚度一致
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.
问题
#FFFFFF)原因
ColorPickerThreadFunc()在启动时对屏幕做一次BitBlt快照,缓冲区按主屏尺寸SM_CXSCREEN × SM_CYSCREEN分配、原点固定在(0, 0);而后续CapturePixelsAroundCursor()用GetCursorPos()返回的虚拟桌面坐标去索引这块缓冲区。GetPixel返回CLR_INVALID→ 表现为#FFFFFF方案
改用 DXGI Desktop Duplication 逐帧实时采样:
AcquireNextFrame取桌面帧,按鼠标当前所在显示器建立 duplicationCopySubresourceRegion拷到 CPU 可读的 staging 纹理后读取,不做整屏回读DXGI_ERROR_WAIT_TIMEOUT时沿用上一帧DXGI_ERROR_ACCESS_LOST时全量释放并重建 duplicationSetWindowDisplayAffinity(WDA_EXCLUDEFROMCAPTURE)排除取色器自身窗口DDA 的桌面帧不包含鼠标指针,采样结果因此不带光标像素。
重绘改由帧泵循环驱动(画面更新或光标移动时重绘,替代原 30 FPS
WM_TIMER):桌面静止时线程阻塞在AcquireNextFrame的帧预算上,不空转;首帧 / 跨屏 / 失效重建被同一阻塞语义自然覆盖,无特判。保留快照回退路径(DDA 初始化失败时启用,覆盖 Win7 / RDP / 旋转屏),并把快照的尺寸与原点一并改为虚拟桌面(
SM_*VIRTUALSCREEN),使副屏在回退模式下同样可用。会话启动时决定走哪条路径,中途 DDA 失效不会切回快照。顺带修复:
MonitorFromPoint)钳位。旧实现按主屏尺寸SM_CXSCREEN计算边界,光标在左侧/上方副屏时窗口会被钳回主屏边界瞬移走WM_PAINT每帧创建/销毁 81 组画刷画笔,改为 stockDC_BRUSH换色填充 + 一遍网格线(绘制结果不变)binding.gyp新增d3d11.lib/dxgi.lib。实现注记
帧副本纹理必须用最小化 desc 创建,不能沿用桌面纹理的
GetDesc():继承其MiscFlags等附加属性后,CopyResource会静默产出全黑帧(独立进程正常、宿主进程内必现),取色恒为#000000,且无任何 API 报错。平台范围
Windows。macOS 侧已核对:其取色器为逐帧
CGWindowListCreateImage实时采样、走 CG 全局坐标,不存在上述两类问题,未做改动。验收
新增
test/verify-color-picker.js:#FFFFFF,改后取到实际色值脚本在运行时探测显示器布局,无可用副屏时跳过对应断言并说明原因;主屏参照色块自检失败(锁屏 / 关屏)时以退出码 2 中止,避免给出无意义结果。
实测
物理替换安装目录下的
ztools_native.node后,本机双屏环境实测:副屏取色正常、实时取样正常、放大镜无闪烁无卡顿。