leftwm_core/models/
dto.rs

1use crate::state::State;
2use serde::{Deserialize, Serialize};
3
4use super::Handle;
5
6#[derive(Serialize, Deserialize, Debug, Clone)]
7pub struct Viewport {
8    pub id: usize,
9    pub output: String,
10    pub tag: String,
11    pub h: u32,
12    pub w: u32,
13    pub x: i32,
14    pub y: i32,
15    pub layout: String,
16}
17
18#[derive(Serialize, Deserialize, Debug, Clone)]
19pub struct ManagerState {
20    pub window_title: Option<String>,
21    pub desktop_names: Vec<String>,
22    pub viewports: Vec<Viewport>,
23    pub active_desktop: Vec<String>,
24    pub working_tags: Vec<String>,
25    pub urgent_tags: Vec<String>,
26}
27
28#[allow(clippy::struct_excessive_bools)]
29#[derive(Serialize, Deserialize, Debug, Clone)]
30pub struct TagsForWorkspace {
31    pub name: String,
32    pub index: usize,
33    pub mine: bool,
34    pub visible: bool,
35    pub focused: bool,
36    pub urgent: bool,
37    pub busy: bool,
38}
39#[derive(Serialize, Deserialize, Debug, Clone)]
40pub struct DisplayWorkspace {
41    pub id: usize,
42    pub output: String,
43    pub h: u32,
44    pub w: u32,
45    pub x: i32,
46    pub y: i32,
47    pub layout: String,
48    pub index: usize,
49    pub tags: Vec<TagsForWorkspace>,
50}
51#[derive(Serialize, Deserialize, Debug, Clone)]
52pub struct DisplayState {
53    pub window_title: String,
54    pub workspaces: Vec<DisplayWorkspace>,
55}
56
57impl From<ManagerState> for DisplayState {
58    fn from(m: ManagerState) -> Self {
59        let visible: Vec<String> = m.viewports.iter().map(|vp| vp.tag.clone()).collect();
60        let workspaces = m
61            .viewports
62            .iter()
63            .enumerate()
64            .map(|(i, vp)| {
65                viewport_into_display_workspace(
66                    &m.desktop_names,
67                    &m.active_desktop,
68                    &visible,
69                    &m.working_tags,
70                    &m.urgent_tags,
71                    vp,
72                    i,
73                )
74            })
75            .collect();
76        Self {
77            workspaces,
78            window_title: m.window_title.unwrap_or_default(),
79        }
80    }
81}
82
83fn viewport_into_display_workspace(
84    all_tags: &[String],
85    focused: &[String],
86    visible: &[String],
87    working_tags: &[String],
88    urgent_tags: &[String],
89    viewport: &Viewport,
90    ws_index: usize,
91) -> DisplayWorkspace {
92    let tags: Vec<TagsForWorkspace> = all_tags
93        .iter()
94        .enumerate()
95        .map(|(index, t)| TagsForWorkspace {
96            name: t.clone(),
97            index,
98            mine: viewport.tag == *t,
99            visible: visible.contains(t),
100            focused: focused.contains(t),
101            urgent: urgent_tags.contains(t),
102            busy: working_tags.contains(t),
103        })
104        .collect();
105    DisplayWorkspace {
106        id: viewport.id,
107        output: viewport.output.clone(),
108        tags,
109        h: viewport.h,
110        w: viewport.w,
111        x: viewport.x,
112        y: viewport.y,
113        index: ws_index,
114        layout: viewport.layout.clone(),
115    }
116}
117
118impl<H: Handle> From<&State<H>> for ManagerState {
119    fn from(state: &State<H>) -> Self {
120        let mut viewports: Vec<Viewport> = vec![];
121        // tags_len = if tags_len == 0 { 0 } else { tags_len - 1 };
122        let working_tags = state
123            .tags
124            .all()
125            .iter()
126            .filter(|tag| {
127                state
128                    .windows
129                    .iter()
130                    .any(|w| w.has_tag(&tag.id) && w.is_managed())
131            })
132            .map(|t| t.label.clone())
133            .collect();
134        let urgent_tags = state
135            .tags
136            .all()
137            .iter()
138            .filter(|tag| state.windows.iter().any(|w| w.has_tag(&tag.id) && w.urgent))
139            .map(|t| t.label.clone())
140            .collect();
141        for ws in &state.workspaces {
142            let tag_label = ws
143                .tag
144                .map(|tag_id| state.tags.get(tag_id).map(|tag| tag.label.clone()))
145                .unwrap()
146                .unwrap();
147
148            let layout_name: String = ws
149                .tag
150                .and_then(|tagid| state.layout_manager.layout_maybe(ws.id, tagid))
151                .map_or_else(|| String::from("N/A"), |layout| layout.name.clone());
152
153            let output = state
154                .screens
155                .iter()
156                .find(|s| s.id == Some(ws.id))
157                .map_or_else(
158                    || String::from("Not found (unreachable)"),
159                    |s| s.output.clone(),
160                );
161
162            viewports.push(Viewport {
163                id: ws.id,
164                output,
165                tag: tag_label,
166                x: ws.xyhw.x(),
167                y: ws.xyhw.y(),
168                h: ws.xyhw.h() as u32,
169                w: ws.xyhw.w() as u32,
170                layout: layout_name,
171            });
172        }
173        let active_desktop = match state.focus_manager.workspace(&state.workspaces) {
174            Some(ws) => ws
175                .tag
176                .iter()
177                .map(|&tag_id| state.tags.get(tag_id).unwrap().label.clone())
178                .collect(),
179            None => vec![], // todo ??
180        };
181        let window_title = match state.focus_manager.window(&state.windows) {
182            Some(win) => win.name.clone(),
183            None => None,
184        };
185        Self {
186            window_title,
187            desktop_names: state
188                .tags
189                .normal()
190                .iter()
191                .map(|t| t.label.clone())
192                .collect(),
193            viewports,
194            active_desktop,
195            urgent_tags,
196            working_tags,
197        }
198    }
199}