i3status_rs/blocks/focused_window/
sway_ipc.rs

1use super::{Backend, Info};
2use crate::blocks::prelude::*;
3use swayipc_async::{Connection, Event, EventStream, EventType, WindowChange, WorkspaceChange};
4
5pub(super) struct SwayIpc {
6    events: EventStream,
7    info: Info,
8}
9
10impl SwayIpc {
11    pub(super) async fn new() -> Result<Self> {
12        Ok(Self {
13            events: Connection::new()
14                .await
15                .error("failed to open connection with swayipc")?
16                .subscribe(&[EventType::Window, EventType::Workspace])
17                .await
18                .error("could not subscribe to window events")?,
19            info: default(),
20        })
21    }
22}
23
24#[async_trait]
25impl Backend for SwayIpc {
26    async fn get_info(&mut self) -> Result<Info> {
27        loop {
28            let event = self
29                .events
30                .next()
31                .await
32                .error("swayipc channel closed")?
33                .error("bad event")?;
34            match event {
35                Event::Window(e) => match e.change {
36                    WindowChange::Mark => {
37                        self.info.marks = e.container.marks;
38                    }
39                    WindowChange::Focus => {
40                        self.info.title.clear();
41                        if let Some(new_title) = &e.container.name {
42                            self.info.title.push_str(new_title);
43                        }
44                        self.info.marks = e.container.marks;
45                    }
46                    WindowChange::Title => {
47                        if e.container.focused {
48                            self.info.title.clear();
49                            if let Some(new_title) = &e.container.name {
50                                self.info.title.push_str(new_title);
51                            }
52                        } else {
53                            continue;
54                        }
55                    }
56                    WindowChange::Close => {
57                        self.info.title.clear();
58                        self.info.marks.clear();
59                    }
60                    _ => continue,
61                },
62                Event::Workspace(e) if e.change == WorkspaceChange::Init => {
63                    self.info.title.clear();
64                    self.info.marks.clear();
65                }
66                _ => continue,
67            }
68
69            return Ok(self.info.clone());
70        }
71    }
72}