From 6004c1a2d39d8c1e5aefff4aa5f21735ea8fea4a Mon Sep 17 00:00:00 2001 From: stephen Date: Wed, 1 Jan 2025 18:24:26 +0000 Subject: [PATCH] panic if trying to enable a closed monitor --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/lib.rs | 52 ++++++++++++++++++++++++++++++++-------------------- src/main.rs | 4 +++- src/sway.rs | 4 ++++ 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d2f65d..928004c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,7 +192,7 @@ dependencies = [ [[package]] name = "swayout" -version = "1.2.0" +version = "1.2.1" dependencies = [ "kdl", "serde", diff --git a/Cargo.toml b/Cargo.toml index 475e5cf..f472479 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "swayout" -version = "1.2.0" +version = "1.2.1" edition = "2021" description = "A tool to configure sway outputs" authors = ["Stephen Byrne"] diff --git a/src/lib.rs b/src/lib.rs index 5615ac8..b429725 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -133,9 +133,12 @@ pub fn print_layout_names() { /// Apply the specified layout. /// layout_name may be the name of a layout in the config, the name of a monitor, /// or the name of an output. -pub fn apply_layout(layout_name: &String) { +/// Return true of any outputs were enabled. +/// Return false if there were no outputs to enable and thus nothing was done. +pub fn apply_layout(layout_name: &String) -> bool { let config = get_config(); let outputs = get_outputs(); + let monitor_states = get_monitor_states(&config, &outputs); // Map of output name to config for all outputs to enable. // (All outputs not in this map will be disabled.) @@ -147,55 +150,61 @@ pub fn apply_layout(layout_name: &String) { .iter() .find(|layout| &layout.name == layout_name) { - // The layout is defined in the rules. + // The layout is defined in the config. layout .outputs .iter() .for_each(|(monitor_name, output_config)| { - let monitor = &config - .monitors - .iter() - .find(|monitor| &monitor.name == monitor_name) - .unwrap(); + let monitor_state = get_monitor_state_by_name(&monitor_states, &monitor_name) + .unwrap_or_else(||panic!("Cannot find monitor '{}' for layout '{}'", monitor_name, layout_name)); + + if monitor_state.is_lid_closed { + panic!("Monitor '{}' is closed", monitor_name); + } // find the output for the monitor to get the output name. let output_opt = outputs .iter() - .find(|output| monitor_matches_output(monitor, output)); + .find(|output| monitor_matches_output(monitor_state.monitor, output)); if let Some(output) = output_opt { output_config_map.insert(&output.name, &output_config); } else { - panic!("Missing output for monitor {monitor_name}"); + panic!("Missing output for monitor '{monitor_name}'"); } }); } else { // The layout is not defined in the rules. // See if it is a monitor name... - if let Some(monitor) = config - .monitors - .iter() - .find(|monitor| &monitor.name == layout_name) - { + if let Some(monitor_state) = get_monitor_state_by_name(&monitor_states, &layout_name) { + if monitor_state.is_lid_closed { + panic!("Monitor '{}' is closed", &monitor_state.monitor.name); + } + // It is a monitor name. Find the matching output... if let Some(output) = outputs .iter() - .find(|output| monitor_matches_output(monitor, output)) + .find(|output| monitor_matches_output(monitor_state.monitor, output)) { output_config_map.insert(&output.name, &output.output_config); } else { - panic!("could not find output for monitor {layout_name}") + panic!("Could not find output for monitor '{layout_name}'") } } else { // See if it is an output name... if let Some(output) = outputs.iter().find(|output| &output.name == layout_name) { output_config_map.insert(&output.name, &output.output_config); } else { - panic!("could not find layout, monitor, or output {layout_name}") + panic!("Could not find layout, monitor, or output '{layout_name}'") } } } - apply_outputs(&outputs, &output_config_map); + if ! output_config_map.is_empty() { + apply_outputs(&outputs, &output_config_map); + true + } else { + false + } } /// Apply the first automatic layout for which all outputs are available. @@ -210,8 +219,11 @@ pub fn apply_automatic() -> Option { .iter() .find(|layout| layout.automatic) { - apply_layout(&layout.name); - Some(String::from(&layout.name)) + if apply_layout(&layout.name) { + Some(String::from(&layout.name)) + } else { + None + } } else { None } diff --git a/src/main.rs b/src/main.rs index 3f39f17..11da524 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,9 @@ fn main() { process::exit(2) } } else { - swayout::apply_layout(&args[1]); + if ! swayout::apply_layout(&args[1]) { + process::exit(3) + } } } else { eprintln!("Usage: {} [layout]", args[0].as_str()); diff --git a/src/sway.rs b/src/sway.rs index d7af4d3..f81bc75 100644 --- a/src/sway.rs +++ b/src/sway.rs @@ -84,6 +84,10 @@ pub fn apply_outputs(all_outputs: &Vec, outputs: &HashMap<&String, &Outp } }); + if enabled.is_empty() { + panic!("No enabled outputs!"); + } + let mut cmd = Command::new("swaymsg"); enabled.iter().for_each(|(output_name, output_config)| { cmd.arg("output");