1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use super::{Manager, Screen, Workspace};
use crate::config::Config;
use crate::display_servers::DisplayServer;
use crate::models::Tag;

impl<C: Config, SERVER: DisplayServer> Manager<C, SERVER> {
    /// Process a collection of events, and apply them changes to a manager.
    ///
    /// Returns `true` if changes need to be rendered.
    pub fn screen_create_handler(&mut self, screen: Screen) -> bool {
        let tag_index = self.state.workspaces.len();

        let mut workspace = Workspace::new(
            screen.wsid,
            screen.bbox,
            self.state.tags.clone(),
            self.state.layout_manager.new_layout(),
            screen
                .max_window_width
                .or_else(|| self.state.config.max_window_width()),
        );
        if workspace.id.is_none() {
            workspace.id = Some(
                self.state
                    .workspaces
                    .iter()
                    .map(|ws| ws.id.unwrap_or(-1))
                    .max()
                    .unwrap_or(-1)
                    + 1,
            );
        }
        if workspace.id.unwrap_or(0) as usize >= self.state.tags.len() {
            dbg!("Workspace ID needs to be less than or equal to the number of tags available.");
        }
        workspace.update_for_theme(&self.state.config);
        //make sure are enough tags for this new screen
        if self.state.tags.len() <= tag_index {
            let id = (tag_index + 1).to_string();
            self.state
                .tags
                .push(Tag::new(&id, self.state.layout_manager.new_layout()));
        }
        let next_tag = self.state.tags[tag_index].clone();
        self.focus_workspace(&workspace);
        self.focus_tag(&next_tag.id);
        workspace.show_tag(&next_tag);
        self.state.workspaces.push(workspace.clone());
        self.state.workspaces.sort_by(|a, b| a.id.cmp(&b.id));
        self.state.screens.push(screen);
        self.focus_workspace(&workspace);
        false
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn creating_two_screens_should_tag_them_with_first_and_second_tags() {
        let mut manager = Manager::new_test(vec!["1".to_string(), "2".to_string()]);
        manager.screen_create_handler(Screen::default());
        manager.screen_create_handler(Screen::default());
        assert!(manager.state.workspaces[0].has_tag("1"));
        assert!(manager.state.workspaces[1].has_tag("2"));
    }

    #[test]
    fn should_be_able_to_add_screens_with_preexisting_tags() {
        let mut manager = Manager::new_test(vec![
            "web".to_string(),
            "console".to_string(),
            "code".to_string(),
        ]);
        manager.screen_create_handler(Screen::default());
        manager.screen_create_handler(Screen::default());
        assert!(manager.state.workspaces[0].has_tag("web"));
        assert!(manager.state.workspaces[1].has_tag("console"));
    }
}