fix(HDMI-Tool): 启动拓扑改智能判定 — 仅转接板(XLS)未激活时强制扩展, 家里仅第二屏零打扰

This commit is contained in:
2026-09-11 00:37:48 +08:00
parent 2459b33162
commit d9ecff4e49
4 changed files with 40 additions and 9 deletions
+5 -2
View File
@@ -60,8 +60,11 @@ HDMI-Tool/
5. **exe 自包含**:图标经 `--add-data` 内嵌(运行时从 `_MEIPASS` 读);内置五种图案
(红/绿/蓝/棋盘格/网格线)由程序绘制,运行时**不依赖** assets/solid/bw PNG 只服务自定义栏位。
6. **DPI 感知**:进程启动即 `SetProcessDpiAwareness(2)`,图案窗口按物理像素定位,勿移除。
7. **启动强制扩展拓扑**`SetDisplayConfig(SDC_TOPOLOGY_EXTEND|SDC_APPLY)`,静默容错
(失败不阻断启动)。动机:LT8619C 热插拔后 Windows 可能停留在"仅电脑屏幕"。
7. **智能显示拓扑(勿改回无条件扩展)**:启动时枚举"接入但不在桌面"的显示器,仅当其
EDID 厂商字节为转接板签名 `61 93`(压缩码 "XLS",上游 lt8619c_edid.c)时才
`SetDisplayConfig(SDC_TOPOLOGY_EXTEND|SDC_APPLY)` 拉回桌面,静默容错。动机:板卡
热插拔后 Windows 可能停留在"仅电脑屏幕"导致枚举不到板卡。用户主动选择的拓扑
(家里的"仅第二屏幕"等,未激活的是笔记本内屏,厂商非 XLS)一律不动。
8. **分辨率切换是临时的**:走 `CHANGEDISPLAYSETTINGS`(不写注册表),"恢复"用会话开始时快照。
9. **EDID 来源是注册表**`HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\...\Device Parameters\EDID`),
不是 WMI/DDCexe 的 noconsole 版无 stdout`--dump/--edid-fields` 只在源码/控制台版可用。
+1 -1
View File
@@ -21,7 +21,7 @@
| 分辨率切换 | "分辨率"下拉列出显卡按该屏 EDID 提供的全部模式;**应用**=临时切换(不写注册表,重启/恢复即还原),**恢复**=回到本次会话切改前的模式 |
| 测试图案投屏 | 全屏投到所选显示器,测试卡区域可选 `640x360 / 800x600 / full 铺满`;内置 纯红/纯绿/纯蓝/黑白棋盘格/网格线 + R/G/B 三行 55/AA/FF 纯色值按钮 + 3 个自定义图片栏位 |
| 光机控制 | RS485 → 板载 GD32E230 网关 → DLPC3421:开关光机(可定时)、设光强、查电流/温度/版本、TEC 控制、软件重启;收发日志带协议译码(见 §5) |
| 显示拓扑控制 | 启动时强制扩展显示拓扑(复制/仅第二屏等模式下保证 demo 板屏幕独立可控) |
| 智能显示拓扑 | 仅当检测到转接板(EDID 厂商 "XLS")接入但未进入桌面(Windows 卡在"仅电脑屏幕")时才强制扩展把它拉回;你主动选的"仅第二屏幕"等拓扑不会被改动 |
| 命令行模式 | 全部功能可脚本化调用,供自动化测试(见 §6、§7) |
| 波形分析脚本 | 逻辑分析仪 CSV 波形按占空比签名分段,输出行结构/占空比/消隐明细(见 §7.3) |
Binary file not shown.
+34 -6
View File
@@ -342,15 +342,43 @@ def apply_mode(device, dm):
def ensure_display_extend():
"""把 Windows 显示拓扑强制为"扩展"
"""仅当转接板显示器"已接入但未进入桌面"时, 才强制扩展拓扑
LT8619C 转接板热插拔后, 若 Windows 停留在"仅电脑屏幕"拓扑(会记住上次
场景: 板卡热插拔后, 若 Windows 停留在"仅电脑屏幕"拓扑(会记住上次
Win+P 的选择), 板卡的 EDID 虽已安装、GPU 也在按首选时序输出, 但桌面
并未扩展过去, get_displays() 就枚举不到这块"显示器"
并未扩展过去, get_displays() 就枚举不到这块"显示器" —— 此时才需要
强制扩展把它拉回桌面。
返回 SetDisplayConfig 的返回码(0=成功); 任何异常静默, 不影响工具启动。
用户主动选择的拓扑(家里的"仅第二屏幕"、手动关闭的显示器等)一律不动:
枚举"接入但不在桌面"的显示器, 只有其 EDID 厂商是转接板签名 "XLS"
(字节 0x61 0x93, 上游 lt8619c_edid.c) 时才扩展; 笔记本内屏等其它
厂商视为用户有意关闭, 不干预。
返回 SetDisplayConfig 的返回码(0=成功, -1=未触发, 其它=异常); 静默容错。
"""
try:
board_stuck = False
i = 0
while True:
dd = DISPLAY_DEVICEW()
dd.cb = ctypes.sizeof(dd)
if not user32.EnumDisplayDevicesW(None, i, ctypes.byref(dd), 0):
break
i += 1
j = 0
while True:
m = DISPLAY_DEVICEW()
m.cb = ctypes.sizeof(m)
if not user32.EnumDisplayDevicesW(dd.DeviceName, j, ctypes.byref(m), 0):
break
j += 1
if m.StateFlags & 0x1: # ATTACHED_TO_DESKTOP: 已在桌面
continue
raw = read_edid_from_registry(m.DeviceID)
if len(raw or ()) >= 10 and raw[8:10] == b'\x61\x93':
board_stuck = True # 转接板没进桌面 -> 需要拉回
if not board_stuck:
return -1
SDC_TOPOLOGY_EXTEND = 0x00000004
SDC_APPLY = 0x00000080
return ctypes.windll.user32.SetDisplayConfig(
@@ -1648,8 +1676,8 @@ def main():
help='RS485 发送光机命令(可多次), 如 --dlpc-cmd M730S0 --dlpc-cmd M999')
args = ap.parse_args()
# LT8619C 板卡热插拔后可能停留在"仅电脑屏幕"拓扑, 先强制扩展,
# 否则 get_displays() 枚举不到板卡的"显示器"(失败静默)
# LT8619C 板卡热插拔后可能停留在"仅电脑屏幕"拓扑: 仅当检测到转接板
# (EDID 厂商 XLS)接入但未进桌面时才强制扩展, 其余拓扑不动(失败静默)
ensure_display_extend()
if args.dump or args.edid_fields: