From 6d859b8b9b33c11edb13728016d461db74c044b9 Mon Sep 17 00:00:00 2001 From: stephen Date: Mon, 30 Dec 2024 03:36:05 +0000 Subject: [PATCH] separate sway module --- src/lib.rs | 119 ++-------------------------------------------------- src/sway.rs | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 116 deletions(-) create mode 100644 src/sway.rs diff --git a/src/lib.rs b/src/lib.rs index c2c825d..8d5f0c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,73 +1,10 @@ -use serde_json::{from_str, Value}; use std::collections::HashMap; -use std::process::Command; -use std::str; - -pub mod config; +mod config; use crate::config::{get_config,OutputConfig}; -/// An output, as returned by `swaymsg -t get_outputs`. -struct Output { - /// output name, according to sway - name: String, - make: String, - model: String, - serial: String, - output_config: OutputConfig, -} - -/// Get all outputs currently available, according to `swaymsg -t get_outputs`. -fn get_outputs() -> Vec { - let output = Command::new("swaymsg") - .arg("-t") - .arg("get_outputs") - .output() - .expect("swaymsg -t get_outputs failed"); - let json_string = str::from_utf8(&output.stdout).unwrap(); - let json = from_str(json_string).unwrap(); - - if let Value::Array(outputs) = json { - outputs - .iter() - .map(|output_json| Output { - name: String::from(output_json["name"].as_str().unwrap()), - make: String::from(output_json["make"].as_str().unwrap()), - model: String::from(output_json["model"].as_str().unwrap()), - serial: String::from(output_json["serial"].as_str().unwrap()), - output_config: OutputConfig { - mode: get_mode(output_json), - scale: String::from("1.0"), - x: 0, - y: 0, - transform: String::from("normal"), - }, - }) - .collect() - } else { - panic!("outputs json was not an array"); - } -} - -/// Parse the mode from the output JSON into a string suitable for the mode param for sway-output. -/// 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() { - let width = mode["width"].as_i64().unwrap().to_string(); - let height = mode["height"].as_i64().unwrap().to_string(); - let mut out: String = String::new(); - out.push_str(&width); - out.push_str("x"); - out.push_str(&height); - out - } else { - panic!("no modes") - } - } else { - panic!("modes not an array") - } -} +mod sway; +use crate::sway::{apply_outputs,get_outputs}; /// Determine the available layout names. /// Return one layout for each layout defined in the configuration file @@ -182,53 +119,3 @@ pub fn apply_layout(layout_name: &String) { apply_outputs(&outputs, &output_config_map); } - -/// Apply the specified outputs. Enable all outputs in [outputs], disable others. -fn apply_outputs(all_outputs: &Vec, outputs: &HashMap<&String, &OutputConfig>) { - - // 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| { - if let Some(output_config) = outputs.get(&output.name) { - enabled.insert(&output.name, &output_config); - } else { - disabled.push(&output.name); - } - }); - - let mut cmd = Command::new("swaymsg"); - enabled.iter().for_each(|(output_name,output_config)| { - cmd.arg("output"); - cmd.arg(&output_name); - cmd.arg("enable"); - cmd.arg("mode"); - cmd.arg(&output_config.mode); - cmd.arg("scale"); - cmd.arg(&output_config.scale); - cmd.arg("pos"); - cmd.arg(&output_config.x.to_string()); - cmd.arg(&output_config.y.to_string()); - cmd.arg("transform"); - cmd.arg(&output_config.transform); - cmd.arg(","); - }); - - disabled.iter().for_each(|output_name| { - cmd.arg("output"); - cmd.arg(&output_name); - cmd.arg("disable"); - cmd.arg(","); - }); - - // print what we are about to do. - cmd.get_args() - .for_each(|arg| print!("{} ", arg.to_str().unwrap())); - - cmd.output().expect("swaymsg output failed"); -} \ No newline at end of file diff --git a/src/sway.rs b/src/sway.rs new file mode 100644 index 0000000..261941a --- /dev/null +++ b/src/sway.rs @@ -0,0 +1,117 @@ +use std::collections::HashMap; +use std::process::Command; +use std::str::from_utf8; +use serde_json::{from_str, Value}; +use crate::config::OutputConfig; + +/// An output, as returned by `swaymsg -t get_outputs`. +pub struct Output { + /// output name, according to sway + pub name: String, + pub make: String, + pub model: String, + pub serial: String, + pub output_config: OutputConfig, +} + +/// Get all outputs currently available, according to `swaymsg -t get_outputs`. +pub fn get_outputs() -> Vec { + let output = Command::new("swaymsg") + .arg("-t") + .arg("get_outputs") + .output() + .expect("swaymsg -t get_outputs failed"); + let json_string = from_utf8(&output.stdout).unwrap(); + let json = from_str(json_string).unwrap(); + + if let Value::Array(outputs) = json { + outputs + .iter() + .map(|output_json| Output { + name: String::from(output_json["name"].as_str().unwrap()), + make: String::from(output_json["make"].as_str().unwrap()), + model: String::from(output_json["model"].as_str().unwrap()), + serial: String::from(output_json["serial"].as_str().unwrap()), + output_config: OutputConfig { + mode: get_mode(output_json), + scale: String::from("1.0"), + x: 0, + y: 0, + transform: String::from("normal"), + }, + }) + .collect() + } else { + panic!("outputs json was not an array"); + } +} + +/// Parse the mode from the output JSON into a string suitable for the mode param for sway-output. +/// 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() { + let width = mode["width"].as_i64().unwrap().to_string(); + let height = mode["height"].as_i64().unwrap().to_string(); + let mut out: String = String::new(); + out.push_str(&width); + out.push_str("x"); + out.push_str(&height); + out + } else { + panic!("no modes") + } + } else { + panic!("modes not an array") + } +} + +/// Apply the specified outputs. Enable all outputs in [outputs], disable others. +pub fn apply_outputs(all_outputs: &Vec, outputs: &HashMap<&String, &OutputConfig>) { + + // 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| { + if let Some(output_config) = outputs.get(&output.name) { + enabled.insert(&output.name, &output_config); + } else { + disabled.push(&output.name); + } + }); + + let mut cmd = Command::new("swaymsg"); + enabled.iter().for_each(|(output_name,output_config)| { + cmd.arg("output"); + cmd.arg(&output_name); + cmd.arg("enable"); + cmd.arg("mode"); + cmd.arg(&output_config.mode); + cmd.arg("scale"); + cmd.arg(&output_config.scale); + cmd.arg("pos"); + cmd.arg(&output_config.x.to_string()); + cmd.arg(&output_config.y.to_string()); + cmd.arg("transform"); + cmd.arg(&output_config.transform); + cmd.arg(","); + }); + + disabled.iter().for_each(|output_name| { + cmd.arg("output"); + cmd.arg(&output_name); + cmd.arg("disable"); + cmd.arg(","); + }); + + // print what we are about to do. + cmd.get_args() + .for_each(|arg| print!("{} ", arg.to_str().unwrap())); + + cmd.output().expect("swaymsg output failed"); +}