From 0cb887c4b52336c2f0a827907139bde18982aa31 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 18 Mar 2026 12:54:03 +0100 Subject: [PATCH] control-center: handle outputs without unique names --- src/control_center/cc_outputs.rs | 79 +++++++++++++++++--------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/src/control_center/cc_outputs.rs b/src/control_center/cc_outputs.rs index c0f2697b..d5027777 100644 --- a/src/control_center/cc_outputs.rs +++ b/src/control_center/cc_outputs.rs @@ -25,9 +25,10 @@ use { }, ahash::AHashMap, egui::{ - Align, Button, Checkbox, Color32, ComboBox, DragValue, EventFilter, FontId, Frame, Grid, - Id, Key, Layout, PointerButton, Rect, ScrollArea, Sense, Shadow, Stroke, StrokeKind, Style, - TextFormat, Ui, UiBuilder, Vec2, Widget, WidgetText, emath, pos2, text::LayoutJob, vec2, + Align, Button, Checkbox, CollapsingHeader, Color32, ComboBox, DragValue, EventFilter, + FontId, Frame, Grid, Id, Key, Layout, PointerButton, Rect, ScrollArea, Sense, Shadow, + Stroke, StrokeKind, Style, TextFormat, Ui, UiBuilder, Vec2, Widget, WidgetText, emath, + pos2, text::LayoutJob, vec2, }, egui_tiles::{ Behavior, Container, Linear, LinearDir, ResizeState, SimplificationOptions, Tile, TileId, @@ -68,6 +69,7 @@ enum Pane { struct CompleteHead { id: ConnectorId, name: HeadName, + pretty_name: Rc, live_state: ReadOnlyHeadState, changed_state: Option, z: u64, @@ -123,9 +125,9 @@ pub enum View { #[derive(Error, Debug)] enum HeadTransactionError { #[error("The connector {} has been removed", .0)] - HeadRemoved(ConnectorId), + HeadRemoved(Rc), #[error("The display connected to connector {} has changed", .0)] - MonitorChanged(ConnectorId), + MonitorChanged(Rc), #[error(transparent)] Backend(#[from] BackendConnectorTransactionError), } @@ -811,10 +813,12 @@ impl OutputsPaneInner { continue; }; let Some(connector) = self.state.connectors.get(&head.id) else { - return Err(HeadTransactionError::HeadRemoved(head.id)); + return Err(HeadTransactionError::HeadRemoved(head.pretty_name.clone())); }; if head.live_state.borrow().monitor_info != desired.monitor_info { - return Err(HeadTransactionError::MonitorChanged(head.id)); + return Err(HeadTransactionError::MonitorChanged( + head.pretty_name.clone(), + )); } let old = connector.state.borrow().clone(); let mut new = old.clone(); @@ -894,6 +898,7 @@ impl OutputsPaneInner { self.heads.entry(mgrs.name).or_insert_with(|| CompleteHead { id: connector.id, name: mgrs.name, + pretty_name: connector.name.clone(), live_state: mgrs.state(), changed_state: None, z: 0, @@ -946,36 +951,38 @@ fn show_connector(state: &State, settings: &Settings, head: &mut CompleteHead, u ..Default::default() }, ); - ui.collapsing(layout_job, |ui| { - grid(ui, ("settings", head.name), |ui| { - let mut diff = false; - show_serial_number(ui, m); - diff |= show_enablement(ui, m, t); - diff |= show_position(ui, m, t); - diff |= show_scale(ui, m, t); - diff |= show_mode(ui, m, t); - diff |= show_size(ui, m, t); - diff |= show_transform(ui, m, t); - diff |= show_brightness(ui, m, t); - diff |= show_color_space(ui, m, t); - diff |= show_eotf(ui, m, t); - diff |= show_format(ui, m, t); - diff |= show_tearing(ui, m, t); - diff |= show_vrr(ui, m, t); - diff |= show_non_desktop(ui, m, t); - diff |= show_blend_space(ui, m, t); - diff |= show_use_native_gamut(ui, m, t); - show_native_gamut(ui, m); - diff |= show_cursor_hz(ui, m, t); - show_flip_margin(state, ui, m, t, head.id); - if diff { - let ui = &mut *ui.row(); - ui.label(""); - ui.label(""); - ui.label("^ current"); - } + CollapsingHeader::new(layout_job) + .id_salt(("connector", head.name)) + .show(ui, |ui| { + grid(ui, ("settings", head.name), |ui| { + let mut diff = false; + show_serial_number(ui, m); + diff |= show_enablement(ui, m, t); + diff |= show_position(ui, m, t); + diff |= show_scale(ui, m, t); + diff |= show_mode(ui, m, t); + diff |= show_size(ui, m, t); + diff |= show_transform(ui, m, t); + diff |= show_brightness(ui, m, t); + diff |= show_color_space(ui, m, t); + diff |= show_eotf(ui, m, t); + diff |= show_format(ui, m, t); + diff |= show_tearing(ui, m, t); + diff |= show_vrr(ui, m, t); + diff |= show_non_desktop(ui, m, t); + diff |= show_blend_space(ui, m, t); + diff |= show_use_native_gamut(ui, m, t); + show_native_gamut(ui, m); + diff |= show_cursor_hz(ui, m, t); + show_flip_margin(state, ui, m, t, head.id); + if diff { + let ui = &mut *ui.row(); + ui.label(""); + ui.label(""); + ui.label("^ current"); + } + }); }); - }); } fn show_serial_number(ui: &mut Ui, m: &HeadState) {