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
|
use std::process::Stdio;
use i3blocks_mpris::{
i3bar::{Block, Click},
listener::listeners,
Blocks,
};
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
#[tokio::main]
async fn main() -> Result<(), main_error::MainError> {
let args = std::env::args().skip(1).collect::<Vec<_>>();
let mut child = tokio::process::Command::new("i3blocks")
.args(args)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
let mut stdout = tokio::io::stdout();
let mut stdin = BufReader::new(tokio::io::stdin()).lines();
let mut child_stdin = child.stdin.take().unwrap();
let mut child_stdout = BufReader::new(child.stdout.take().unwrap()).lines();
let blocks: Blocks = Blocks::default();
let blocks2 = blocks.clone();
tokio::spawn(async move {
blocks2.value.write().await[0] = Some(Block {
name: Some("mpris-icon".into()),
full_text: " ".into(),
separator: Some(false),
separator_block_width: Some(0),
..Default::default()
});
blocks2.notify.notify_one();
});
tokio::spawn(listeners(blocks.clone()));
let mut mpris_blocks = String::new();
let mut other_blocks = String::new();
loop {
tokio::select! {
_ = blocks.notify.notified() => {
mpris_blocks = blocks
.value
.read()
.await
.iter()
.map(serde_json::to_string)
.collect::<Result<Vec<_>, _>>()?
.join(",");
}
Ok(Some(line)) = child_stdout.next_line() => other_blocks = line,
Ok(Some(line)) = stdin.next_line() => match serde_json::from_str::<Click>(&line) {
Err(_) => continue,
Ok(Click { name: Some(name), button, .. }) if name.starts_with("mpris-") => println!("{name}, {button}"),
Ok(click) => {
let mut s = serde_json::to_vec(&click)?;
s.push(b'\n');
child_stdin.write_all(&s).await?;
}
},
else => break,
}
let mut output = other_blocks.replace(r#"{"name":"mpris","full_text":""}"#, &mpris_blocks);
output.push('\n');
stdout.write_all(output.as_bytes()).await?;
}
Ok(())
}
|