Config access refactoring

timeout_old
Tassilo Horn 3 years ago
parent a29b24fc4d
commit 247f7835c1
  1. 62
      src/con.rs
  2. 118
      src/config.rs
  3. 21
      src/demon.rs
  4. 23
      src/layout.rs
  5. 16
      src/util.rs

@ -210,42 +210,21 @@ fn maybe_html_escape(do_it: bool, text: &str) -> String {
impl<'a> DisplayFormat for Window<'a> { impl<'a> DisplayFormat for Window<'a> {
fn format_for_display(&self, cfg: &cfg::Config) -> String { fn format_for_display(&self, cfg: &cfg::Config) -> String {
let default_format = cfg::Format::default(); let window_format = cfg.get_format_window_format();
let fmt = cfg let urgency_start = cfg.get_format_urgency_start();
.format let urgency_end = cfg.get_format_urgency_end();
.as_ref() let html_escape = cfg.get_format_html_escape();
.and_then(|f| f.window_format.as_ref()) let icon_dirs = cfg.get_format_icon_dirs();
.unwrap_or_else(|| default_format.window_format.as_ref().unwrap());
let urgency_start = cfg
.format
.as_ref()
.and_then(|f| f.urgency_start.as_ref())
.unwrap_or_else(|| default_format.urgency_start.as_ref().unwrap());
let urgency_end = cfg
.format
.as_ref()
.and_then(|f| f.urgency_end.as_ref())
.unwrap_or_else(|| default_format.urgency_end.as_ref().unwrap());
let html_escape = cfg
.format
.as_ref()
.and_then(|f| f.html_escape)
.unwrap_or_else(|| default_format.html_escape.unwrap());
let icon_dirs = cfg
.format
.as_ref()
.and_then(|f| f.icon_dirs.as_ref())
.unwrap_or_else(|| default_format.icon_dirs.as_ref().unwrap());
// fallback_icon has no default value. // fallback_icon has no default value.
let fallback_icon: Option<&String> = let fallback_icon = cfg.get_format_fallback_icon();
cfg.format.as_ref().and_then(|f| f.fallback_icon.as_ref());
// Some apps report, e.g., Gimp-2.10 but the icon is still named // Some apps report, e.g., Gimp-2.10 but the icon is still named
// gimp.png. // gimp.png.
let app_name_no_version = let app_name_no_version =
APP_NAME_AND_VERSION_RX.replace(self.get_app_name(), "$1"); APP_NAME_AND_VERSION_RX.replace(self.get_app_name(), "$1");
fmt.replace("{id}", format!("{}", self.get_id()).as_str()) window_format
.replace("{id}", format!("{}", self.get_id()).as_str())
.replace( .replace(
"{urgency_start}", "{urgency_start}",
if self.is_urgent() { if self.is_urgent() {
@ -279,15 +258,17 @@ impl<'a> DisplayFormat for Window<'a> {
) )
.replace( .replace(
"{app_icon}", "{app_icon}",
util::get_icon(self.get_app_name(), icon_dirs) util::get_icon(self.get_app_name(), &icon_dirs)
.or_else(|| util::get_icon(&app_name_no_version, icon_dirs)) .or_else(|| {
util::get_icon(&app_name_no_version, &icon_dirs)
})
.or_else(|| { .or_else(|| {
util::get_icon( util::get_icon(
&app_name_no_version.to_lowercase(), &app_name_no_version.to_lowercase(),
icon_dirs, &icon_dirs,
) )
}) })
.or_else(|| fallback_icon.map(|f| f.to_string())) .or(fallback_icon)
.unwrap_or_else(String::new) .unwrap_or_else(String::new)
.as_str(), .as_str(),
) )
@ -482,19 +463,8 @@ impl PartialOrd for Workspace<'_> {
impl<'a> DisplayFormat for Workspace<'a> { impl<'a> DisplayFormat for Workspace<'a> {
fn format_for_display(&self, cfg: &cfg::Config) -> String { fn format_for_display(&self, cfg: &cfg::Config) -> String {
let default_format = cfg::Format::default(); let fmt = cfg.get_format_workspace_format();
let fmt = cfg let html_escape = cfg.get_format_html_escape();
.format
.as_ref()
.and_then(|f| f.workspace_format.as_ref())
.unwrap_or_else(|| {
default_format.workspace_format.as_ref().unwrap()
});
let html_escape = cfg
.format
.as_ref()
.and_then(|f| f.html_escape)
.unwrap_or_else(|| default_format.html_escape.unwrap());
fmt.replace("{id}", format!("{}", self.get_id()).as_str()) fmt.replace("{id}", format!("{}", self.get_id()).as_str())
.replace("{name}", &maybe_html_escape(html_escape, self.get_name())) .replace("{name}", &maybe_html_escape(html_escape, self.get_name()))

@ -25,32 +25,122 @@ use std::path::Path;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Config { pub struct Config {
pub menu: Option<Menu>, menu: Option<Menu>,
pub format: Option<Format>, format: Option<Format>,
pub layout: Option<Layout>, layout: Option<Layout>,
}
impl Config {
pub fn get_menu_executable(&self) -> String {
self.menu
.as_ref()
.and_then(|m| m.executable.clone())
.or_else(|| Menu::default().executable)
.expect("No menu.executable defined!")
}
pub fn get_menu_args(&self) -> Vec<String> {
self.menu
.as_ref()
.and_then(|m| m.args.clone())
.or_else(|| Menu::default().args)
.expect("No menu.args defined.")
}
pub fn get_format_window_format(&self) -> String {
self.format
.as_ref()
.and_then(|f| f.window_format.clone())
.or_else(|| Format::default().window_format)
.expect("No format.window_format defined.")
}
pub fn get_format_workspace_format(&self) -> String {
self.format
.as_ref()
.and_then(|f| f.workspace_format.clone())
.or_else(|| Format::default().workspace_format)
.expect("No format.workspace_format defined.")
}
pub fn get_format_urgency_start(&self) -> String {
self.format
.as_ref()
.and_then(|f| f.urgency_start.clone())
.or_else(|| Format::default().urgency_start)
.expect("No format.urgency_start defined.")
}
pub fn get_format_urgency_end(&self) -> String {
self.format
.as_ref()
.and_then(|f| f.urgency_end.clone())
.or_else(|| Format::default().urgency_end)
.expect("No format.urgency_end defined.")
}
pub fn get_format_html_escape(&self) -> bool {
self.format
.as_ref()
.and_then(|f| f.html_escape)
.or_else(|| Format::default().html_escape)
.expect("No format.html_escape defined.")
}
pub fn get_format_icon_dirs(&self) -> Vec<String> {
self.format
.as_ref()
.and_then(|f| f.icon_dirs.clone())
.or_else(|| Format::default().icon_dirs)
.expect("No format.icon_dirs defined.")
}
pub fn get_format_fallback_icon(&self) -> Option<String> {
self.format
.as_ref()
.and_then(|f| f.fallback_icon.clone())
.or_else(|| Format::default().fallback_icon)
}
pub fn is_layout_auto_tile(&self) -> bool {
self.layout
.as_ref()
.and_then(|l| l.auto_tile)
.or_else(|| Layout::default().auto_tile)
.expect("No layout.auto_tile defined.")
}
pub fn get_layout_auto_tile_min_window_width_per_output_width_as_map(
&self,
) -> HashMap<i32, i32> {
self.layout.as_ref()
.and_then(|l|l.auto_tile_min_window_width_per_output_width_as_map())
.or_else(|| Layout::default().auto_tile_min_window_width_per_output_width_as_map())
.expect("No layout.auto_tile_min_window_width_per_output_width defined.")
}
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Menu { pub struct Menu {
pub executable: Option<String>, executable: Option<String>,
pub args: Option<Vec<String>>, args: Option<Vec<String>>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Format { pub struct Format {
pub window_format: Option<String>, window_format: Option<String>,
pub workspace_format: Option<String>, workspace_format: Option<String>,
pub urgency_start: Option<String>, urgency_start: Option<String>,
pub urgency_end: Option<String>, urgency_end: Option<String>,
pub html_escape: Option<bool>, html_escape: Option<bool>,
pub icon_dirs: Option<Vec<String>>, icon_dirs: Option<Vec<String>>,
pub fallback_icon: Option<String>, fallback_icon: Option<String>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Layout { pub struct Layout {
pub auto_tile: Option<bool>, auto_tile: Option<bool>,
pub auto_tile_min_window_width_per_output_width: Option<Vec<[i32; 2]>>, auto_tile_min_window_width_per_output_width: Option<Vec<[i32; 2]>>,
} }
impl Layout { impl Layout {

@ -50,7 +50,6 @@ pub fn monitor_sway_events(
extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>,
) { ) {
let config = config::load_config(); let config = config::load_config();
let layout = config.layout.unwrap_or_else(config::Layout::default);
'reset: loop { 'reset: loop {
println!("Connecting to sway for subscribing to events..."); println!("Connecting to sway for subscribing to events...");
@ -70,7 +69,7 @@ pub fn monitor_sway_events(
handled = handle_window_event( handled = handle_window_event(
win_ev, win_ev,
extra_props_clone, extra_props_clone,
&layout, &config,
); );
} }
s::Event::Workspace(ws_ev) => { s::Event::Workspace(ws_ev) => {
@ -103,43 +102,35 @@ pub fn monitor_sway_events(
} }
} }
fn maybe_auto_tile(layout: &config::Layout) {
if layout.auto_tile == Some(true) {
println!("\nauto_tile: start");
layout::auto_tile(layout);
println!("auto_tile: end\n");
}
}
fn handle_window_event( fn handle_window_event(
ev: Box<s::WindowEvent>, ev: Box<s::WindowEvent>,
extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>,
layout: &config::Layout, config: &config::Config,
) -> bool { ) -> bool {
let s::WindowEvent { let s::WindowEvent {
change, container, .. change, container, ..
} = *ev; } = *ev;
match change { match change {
s::WindowChange::Focus => { s::WindowChange::Focus => {
maybe_auto_tile(layout); layout::maybe_auto_tile(config);
update_last_focus_time(container.id, extra_props); update_last_focus_time(container.id, extra_props);
println!("Handled window event type {:?}", change); println!("Handled window event type {:?}", change);
true true
} }
s::WindowChange::New => { s::WindowChange::New => {
maybe_auto_tile(layout); layout::maybe_auto_tile(config);
update_last_focus_time(container.id, extra_props); update_last_focus_time(container.id, extra_props);
println!("Handled window event type {:?}", change); println!("Handled window event type {:?}", change);
true true
} }
s::WindowChange::Close => { s::WindowChange::Close => {
remove_extra_props(container.id, extra_props); remove_extra_props(container.id, extra_props);
maybe_auto_tile(layout); layout::maybe_auto_tile(config);
println!("Handled window event type {:?}", change); println!("Handled window event type {:?}", change);
true true
} }
s::WindowChange::Move | s::WindowChange::Floating => { s::WindowChange::Move | s::WindowChange::Floating => {
maybe_auto_tile(layout); layout::maybe_auto_tile(config);
println!("Handled window event type {:?}", change); println!("Handled window event type {:?}", change);
false // We don't affect the extra_props state here. false // We don't affect the extra_props state here.
} }

@ -20,14 +20,12 @@ use crate::con::NodeMethods;
use crate::config; use crate::config;
use swayipc as s; use swayipc as s;
pub fn auto_tile(layout: &config::Layout) { pub fn auto_tile(cfg: &config::Config) {
if let Ok(mut con) = s::Connection::new() { if let Ok(mut con) = s::Connection::new() {
if let Ok(tree) = con.get_tree() { if let Ok(tree) = con.get_tree() {
let config_map = let config_map = cfg
layout.auto_tile_min_window_width_per_output_width_as_map(); .get_layout_auto_tile_min_window_width_per_output_width_as_map(
let default_map = config::Layout::default() );
.auto_tile_min_window_width_per_output_width_as_map()
.unwrap();
for output in &tree.nodes { for output in &tree.nodes {
println!("output: {:?}", output.name); println!("output: {:?}", output.name);
@ -41,10 +39,7 @@ pub fn auto_tile(layout: &config::Layout) {
} }
let output_width = output.rect.width; let output_width = output.rect.width;
let min_window_width = &config_map let min_window_width = &config_map.get(&output_width);
.as_ref()
.unwrap_or(&default_map)
.get(&output_width);
if let Some(min_window_width) = min_window_width { if let Some(min_window_width) = min_window_width {
for container in for container in
@ -115,3 +110,11 @@ pub fn auto_tile(layout: &config::Layout) {
eprintln!("Couldn't get connection for auto_tile"); eprintln!("Couldn't get connection for auto_tile");
} }
} }
pub fn maybe_auto_tile(config: &config::Config) {
if config.is_layout_auto_tile() {
println!("\nauto_tile: start");
auto_tile(config);
println!("auto_tile: end\n");
}
}

@ -212,27 +212,19 @@ where
map.insert(s, c); map.insert(s, c);
} }
let menu_default = cfg::Menu::default(); let menu_exec = cfg.get_menu_executable();
let menu_exec = cfg
.menu
.as_ref()
.and_then(|l| l.executable.as_ref())
.unwrap_or_else(|| menu_default.executable.as_ref().unwrap());
let args: Vec<String> = cfg let args: Vec<String> = cfg
.menu .get_menu_args()
.as_ref()
.and_then(|l| l.args.as_ref())
.unwrap_or_else(|| menu_default.args.as_ref().unwrap())
.iter() .iter()
.map(|a| a.replace("{prompt}", prompt)) .map(|a| a.replace("{prompt}", prompt))
.collect(); .collect();
let mut menu = proc::Command::new(menu_exec) let mut menu = proc::Command::new(&menu_exec)
.args(args) .args(args)
.stdin(proc::Stdio::piped()) .stdin(proc::Stdio::piped())
.stdout(proc::Stdio::piped()) .stdout(proc::Stdio::piped())
.spawn() .spawn()
.expect(&("Error running ".to_owned() + menu_exec)); .expect(&("Error running ".to_owned() + &menu_exec));
{ {
let stdin = menu let stdin = menu

Loading…
Cancel
Save