libawm/contrib/
actions.rs1use crate::{
3 core::{
4 bindings::KeyEventHandler,
5 client::Client,
6 data_types::RelativePosition,
7 helpers::{spawn, spawn_for_output},
8 layout::Layout,
9 manager::WindowManager,
10 ring::Selector,
11 workspace::Workspace,
12 xconnection::XConn,
13 },
14 Result,
15};
16
17pub fn create_or_switch_to_workspace<X: XConn>(
27 get_name: fn() -> Option<String>,
28 layouts: Vec<Layout>,
29) -> KeyEventHandler<X> {
30 Box::new(move |wm: &mut WindowManager<X>| {
31 if let Some(s) = get_name() {
32 let name = &s;
33 let cond = |ws: &Workspace| ws.name() == name;
34 let sel = Selector::Condition(&cond);
35 if wm.workspace(&sel).is_none() {
36 wm.push_workspace(Workspace::new(name, layouts.clone()))?;
37 }
38 wm.focus_workspace(&sel)
39 } else {
40 Ok(())
41 }
42 })
43}
44
45pub fn focus_or_spawn<X: XConn>(
53 class: impl Into<String>,
54 command: impl Into<String>,
55) -> KeyEventHandler<X> {
56 let (class, command) = (class.into(), command.into());
57
58 Box::new(move |wm: &mut WindowManager<X>| {
59 let cond = |c: &Client| c.class() == class;
60 if let Some(client) = wm.client(&Selector::Condition(&cond)) {
61 let workspace = client.workspace();
62 wm.focus_workspace(&Selector::Index(workspace))
63 } else {
64 spawn(&command)
65 }
66 })
67}
68
69pub fn update_monitors_via_xrandr(
80 primary: &str,
81 secondary: &str,
82 position: RelativePosition,
83) -> Result<()> {
84 let raw = spawn_for_output("xrandr")?;
85 let secondary_line = raw
86 .lines()
87 .find(|line| line.starts_with(secondary))
88 .ok_or_else(|| perror!("unable to find secondary monitor in xrandr output"))?;
89 let status = secondary_line
90 .split(' ')
91 .nth(1)
92 .ok_or_else(|| perror!("unexpected xrandr output"))?;
93
94 let position_flag = match position {
95 RelativePosition::Left => "--left-of",
96 RelativePosition::Right => "--right-of",
97 RelativePosition::Above => "--above",
98 RelativePosition::Below => "--below",
99 };
100
101 spawn(format!("xrandr --output {} --primary --auto", primary))?;
103
104 match status {
105 "disconnected" => spawn(format!("xrandr --output {} --off", secondary)),
106 "connected" => spawn(format!(
107 "xrandr --output {} --auto {} {}",
108 secondary, position_flag, primary
109 )),
110 _ => Ok(()),
111 }
112}