docs and renames

This commit is contained in:
2024-12-12 03:21:05 +00:00
parent ea5ae5968a
commit dd2c80224f

View File

@@ -5,30 +5,42 @@ use std::env;
use std::process::Command;
use std::{fs, str};
// parse the config to this
/// Configuration for swayout.
#[derive(Serialize, Deserialize, Debug)]
struct Rules {
struct Config {
/// Monitor name is independent of output name. It can be anything.
monitors: HashMap<String, Monitor>,
// Map of layout name to : map of monitor name to output config
/// Definition of layouts: a map of the layout name to the outputs.
/// The outputs is a map of the monitor name (in `monitors`) to the configuration
/// of that monitor for this layout.
/// Available outputs that do not match a monitor in the map are disabled.
layouts: HashMap<String, HashMap<String, OutputConfig>>,
}
/// Defines a monitor by make, model, and serial.
#[derive(Serialize, Deserialize, Debug)]
struct Monitor {
make: String,
model: String,
serial: String,
}
/// Configuration for an enabled output.
#[derive(Serialize, Deserialize, Debug)]
struct OutputConfig {
/// mode. See man 5 sway-output
mode: String,
/// scale. See man 5 sway-output
scale: String,
/// x value for position. See man 5 sway-output
x: u16,
/// y value for position. See man 5 sway-output
y: u16,
/// transform. See man 5 sway-output
transform: String,
}
// parse output of swaymsg -t get_outputs to this
/// An output, as returned by `swaymsg -t get_outputs`.
struct Output {
/// output name, according to sway
name: String,
make: String,
model: String,
@@ -48,9 +60,8 @@ fn main() {
}
}
/// Get all outputs currently available
/// Get all outputs currently available, according to `swaymsg -t get_outputs`.
fn get_outputs() -> Vec<Output> {
// call `swaymsg -t get_outputs` to get outputs
let output = Command::new("swaymsg")
.arg("-t")
.arg("get_outputs")
@@ -82,7 +93,7 @@ fn get_outputs() -> Vec<Output> {
}
/// Parse the mode from the output JSON into a string suitable for the mode param for sway-output.
/// This will go into OutputConfig.mode
/// This will go into `OutputConfig.mode`.
fn get_mode(output: &Value) -> String {
if let Value::Array(modes) = &output["modes"] {
if let Some(mode) = modes.first() {
@@ -101,15 +112,16 @@ fn get_mode(output: &Value) -> String {
}
}
/// Get the rules from ~/.config/swayout/config.toml
fn get_rules() -> Rules {
/// Get a `Config` from ~/.config/swayout/config.toml.
/// (It really uses XDG config dirs.)
fn get_config() -> Config {
let xdg_dirs = xdg::BaseDirectories::with_prefix("swayout").unwrap();
if let Some(path) = xdg_dirs.find_config_file("config.toml") {
let toml = fs::read_to_string(path).expect("error reading file");
toml::from_str(&toml).expect("toml parse error")
} else {
// no config files, use an empty rules
Rules {
Config {
monitors: HashMap::new(),
layouts: HashMap::new(),
}
@@ -118,17 +130,16 @@ fn get_rules() -> Rules {
/// Determine the available layout names.
/// Return one layout for each layout defined in the configuration file
/// (for which all outputs are available),
/// one for each monitor defined in the configuration file
/// (for using just that monitor),
/// for which all outputs are available,
/// one for each monitor defined in the configuration file (for using just that monitor),
/// and one for each available output that is not a configured monitor (for using just that output).
fn get_layouts() -> Vec<String> {
let available_outputs = get_outputs();
let rules = get_rules();
let rules = get_config();
let mut layout_names: Vec<String> = Vec::new();
// Get the names of monitors that are available (that match a current output)
// Get the names of monitors that are available (that match an available output)
let available_monitor_names:Vec<&String> = rules.monitors.iter()
.filter(|(_monitor_name,monitor)|
available_outputs.iter().any(|output|
@@ -175,9 +186,10 @@ fn print_layout_names() {
}
/// Apply the specified layout.
/// layout_name may be the name of a layout rule, the name of a monitor, or the name of an output.
/// layout_name may be the name of a layout in the config, the name of a monitor,
/// or the name of an output.
fn apply_layout(layout_name: &String) {
let rules = get_rules();
let rules = get_config();
let outputs = get_outputs();
// Map of output name to config for all outputs to enable.
@@ -192,7 +204,6 @@ fn apply_layout(layout_name: &String) {
let monitor = &rules.monitors[monitor_name];
// find the output for the monitor to get the output name.
// (You can allegedly use "<make> <model> <serial>" instead of output name.)
let output_opt = outputs.iter().find(|output| {
output.make == monitor.make
&& output.model == monitor.model
@@ -210,8 +221,7 @@ fn apply_layout(layout_name: &String) {
if let Some(monitor) = rules.monitors.get(layout_name) {
// It is a monitor name. Find the matching output...
if let Some(output) = outputs.iter().find(|output| {
output.make == monitor.make
&& output.model == monitor.model
output.make == monitor.make && output.model == monitor.model
&& output.serial == monitor.serial
}) {
output_config_map.insert(&output.name, &output.output_config);
@@ -234,12 +244,13 @@ fn apply_layout(layout_name: &String) {
/// Apply the specified outputs. Enable all outputs in [outputs], disable others.
fn apply_outputs(all_outputs: &Vec<Output>, outputs: &HashMap<&String, &OutputConfig>) {
let mut cmd = Command::new("swaymsg");
// enabled first, then disabled.
// That way if some work before an error, you at least have one output enabled.
// set enabled outputs first, then set disabled outputs.
// That way if some work before an error, you have at least one output enabled.
// for outputs to be enabled: map of output name to config
let mut enabled: HashMap<&String,&OutputConfig> = HashMap::new();
// for outputs to be disabled: output names
let mut disabled: Vec<&String> = Vec::new();
all_outputs.iter().for_each(|output| {
@@ -250,6 +261,7 @@ fn apply_outputs(all_outputs: &Vec<Output>, outputs: &HashMap<&String, &OutputCo
}
});
let mut cmd = Command::new("swaymsg");
enabled.iter().for_each(|(output_name,output_config)| {
cmd.arg("output");
cmd.arg(&output_name);
@@ -273,6 +285,7 @@ fn apply_outputs(all_outputs: &Vec<Output>, outputs: &HashMap<&String, &OutputCo
cmd.arg(",");
});
// print what we are about to do.
cmd.get_args()
.for_each(|arg| print!("{} ", arg.to_str().unwrap()));