leftwm_core/models/
window_change.rs

1use super::Handle;
2use super::MaybeWindowHandle;
3use super::Window;
4use super::WindowHandle;
5use super::WindowState;
6use super::WindowType;
7use super::Xyhw;
8use crate::models::{Margins, XyhwChange};
9
10type MaybeName = Option<String>;
11
12#[derive(Debug, Clone)]
13pub struct WindowChange<H: Handle> {
14    pub handle: WindowHandle<H>,
15    pub transient: Option<MaybeWindowHandle<H>>,
16    pub never_focus: Option<bool>,
17    pub urgent: Option<bool>,
18    pub name: Option<MaybeName>,
19    pub r#type: Option<WindowType>,
20    pub floating: Option<XyhwChange>,
21    pub strut: Option<XyhwChange>,
22    pub requested: Option<Xyhw>,
23    pub states: Option<Vec<WindowState>>,
24}
25
26impl<H: Handle> WindowChange<H> {
27    #[must_use]
28    pub const fn new(h: WindowHandle<H>) -> Self {
29        Self {
30            handle: h,
31            transient: None,
32            never_focus: None,
33            name: None,
34            r#type: None,
35            urgent: None,
36            floating: None,
37            strut: None,
38            requested: None,
39            states: None,
40        }
41    }
42
43    pub fn update(self, window: &mut Window<H>, container: Option<Xyhw>) -> bool {
44        let mut changed = false;
45        if let Some(trans) = &self.transient {
46            let changed_trans = window.transient.is_none() || &window.transient != trans;
47            changed = changed || changed_trans;
48            window.transient = *trans;
49        }
50        if let Some(name) = &self.name {
51            let changed_name = window.name.is_none() || &window.name != name;
52            changed = changed || changed_name;
53            window.name = name.clone();
54        }
55        if let Some(nf) = self.never_focus {
56            let changed_nf = window.never_focus != nf;
57            changed = changed || changed_nf;
58            window.never_focus = nf;
59        }
60        if let Some(urgent) = self.urgent {
61            let changed_urgent = window.urgent != urgent;
62            changed = changed || changed_urgent;
63            // If the window is already visible, there is no need to mark it as urgent
64            window.urgent = urgent && !window.visible();
65        }
66        if let Some(mut floating_change) = self.floating {
67            // Reposition if dialog or modal.
68            if let Some(outer) = container {
69                let mut xyhw = Xyhw::default();
70                floating_change.update(&mut xyhw);
71                xyhw.center_relative(outer, window.border);
72                floating_change.x = Some(xyhw.x());
73                floating_change.y = Some(xyhw.y());
74            }
75            let changed_floating = floating_change.update_window_floating(window);
76            changed = changed || changed_floating;
77        }
78        if let Some(strut) = self.strut {
79            let changed_strut = strut.update_window_strut(window);
80            changed = changed || changed_strut;
81        }
82        if let Some(requested) = self.requested {
83            window.requested = Some(requested);
84        }
85        if let Some(r#type) = &self.r#type {
86            let changed_type = &window.r#type != r#type;
87            changed = changed || changed_type;
88            window.r#type = r#type.clone();
89            if !window.is_managed() {
90                window.border = 0;
91                window.margin = Margins::new(0);
92            }
93        }
94        if let Some(states) = self.states {
95            changed = true;
96            window.states = states;
97        }
98        changed
99    }
100}