fix(host): preserve a physical monitor's refresh when adding a virtual display

Connecting reset an existing physical monitor's refresh (e.g. 120->60 Hz)
because the topology code read the physical's mode AFTER the virtual output
perturbed the compositor layout — by which point it had already been
downgraded. Read/preserve each physical's mode from a pre-connect snapshot.

- Mutter: build_primary_keeping_physicals takes the pre-virtual snapshot and
  preserves each physical's real mode (pick_keep_mode, unit-tested)
- KWin: capture each output's mode when disabling for exclusive, re-assert it
  on re-enable (a bare enable defaulted to ~60 Hz)
- Windows: skip the refresh-resetting SDC_TOPOLOGY_EXTEND when a physical is
  already active

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 10:33:30 +00:00
parent 79c4f4cbc1
commit 7257bcb6a6
4 changed files with 269 additions and 37 deletions
@@ -384,8 +384,10 @@ unsafe fn query_active_config() -> Option<SavedConfig> {
}
/// Count currently-ACTIVE display paths whose target id != `keep_target_id` — i.e. displays that would
/// still be lit besides the virtual one. `None` on query failure. Used to VERIFY isolation actually took.
unsafe fn count_other_active(keep_target_id: u32) -> Option<u32> {
/// still be lit besides the virtual one. `None` on query failure. Used to VERIFY isolation actually
/// took, and (in the `primary` topology) to detect a physical that is ALREADY active so we can skip a
/// force-EXTEND that would reset its refresh.
pub(crate) unsafe fn count_other_active(keep_target_id: u32) -> Option<u32> {
let (paths, _) = query_active_config()?;
Some(
paths