i3status_rs/blocks/focused_window/
sway_ipc.rs1use 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}