From 8fe71be42451cdd78b0df03866525f78fb18071e Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Mon, 27 Jul 2026 23:39:49 +0200 Subject: [PATCH] fix(web): applying a saved preset kept switching the streamed screen off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `applyCustomPreset` builds a FRESH policy object instead of spreading the draft, so every field it doesn't name is dropped. `capture_monitor` was not named — so picking one of your own saved presets silently took a host that was mirroring a real monitor and put it back on a virtual display. The same omission in the Custom switch would have done it there too. Found on-glass against a running serve on .136: the PUT is whole-object, so the console is the only thing keeping the orthogonal axes alive, and these two sites were the ones building a policy from scratch rather than from what was already in force. Co-Authored-By: Claude Opus 5 (1M context) --- web/src/sections/Displays/DisplayCard.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/web/src/sections/Displays/DisplayCard.tsx b/web/src/sections/Displays/DisplayCard.tsx index 7772a882..2fae425a 100644 --- a/web/src/sections/Displays/DisplayCard.tsx +++ b/web/src/sections/Displays/DisplayCard.tsx @@ -189,6 +189,10 @@ const DisplayForm: FC<{ game_session: draft.game_session ?? "auto", ddc_power_off: draft.ddc_power_off ?? false, pnp_disable_monitors: draft.pnp_disable_monitors ?? false, + // Which screen we stream is not a display-behavior axis at all — swapping the + // streamed screen out from under the operator because they changed a preset would be + // the worst kind of surprise. + capture_monitor: draft.capture_monitor ?? null, }); } else { apply({ ...draft, preset: id as Preset }); @@ -206,6 +210,11 @@ const DisplayForm: FC<{ // The experimental axes aren't part of a preset — keep the current settings. ddc_power_off: draft.ddc_power_off ?? false, pnp_disable_monitors: draft.pnp_disable_monitors ?? false, + // Nor is the streamed screen: this builds a FRESH policy object rather than spreading + // the draft, so anything not named here is silently dropped — which is exactly how + // applying a saved preset used to switch a mirroring host back to a virtual display + // (found on-glass, .136). Every orthogonal axis has to be listed. + capture_monitor: draft.capture_monitor ?? null, }); // A custom card is "current" when the in-force policy is a Custom one whose fields + game-session