nix-configs/programs/bar-ws-monitor/src/main.rs

105 lines
3.1 KiB
Rust

use core::panic;
use std::{collections::HashMap, io::Write};
use niri_ipc::{
socket::Socket,
state::{EventStreamState, EventStreamStatePart},
Request, Response, Workspace,
};
use serde::Serialize;
// gruvbox colors
const COLORS: [[&str; 2]; 7] = [
["#458588", "#83a598"], // blue
["#b16286", "#d3869b"], // purple
["#689d6a", "#8ec07c"], // aqua
["#97971a", "#b8bb26"], // green
["#d79921", "#fabd2f"], // yellow
["#d65d0e", "#fe8019"], // orange
["#cc241d", "#fb4934"], // red
];
fn main() -> Result<(), std::io::Error> {
let mut state = EventStreamState::default();
let sock = Socket::connect()?;
let mut func = sock.send(Request::EventStream).and_then(|it| match it {
(Ok(Response::Handled), func) => Ok(func),
_ => unreachable!(),
})?;
while let Ok(ev) = (func)() {
// check only relevant later, only done here to avoid a clone
let ev_is_ws_related = matches!(
&ev,
niri_ipc::Event::WorkspacesChanged { .. }
| niri_ipc::Event::WorkspaceActivated { .. }
| niri_ipc::Event::WorkspaceActiveWindowChanged { .. }
);
// apply event to state
state.apply(ev);
if ev_is_ws_related {
let mut workspaces = state
.workspaces
.workspaces
.values()
.map(|it| it.clone())
.collect::<Vec<Workspace>>();
workspaces.sort_by(|a, b| a.idx.cmp(&b.idx));
workspaces.sort_by(|a, b| {
a.output
.clone()
.expect("unreachable")
.to_lowercase()
.cmp(&b.output.clone().expect("unreachable").to_lowercase())
});
let output_colors_lut = workspaces
.iter()
.map(|it| it.output.clone().expect("unreachable"))
.fold(Vec::new(), |mut acc, it| {
if !acc.contains(&it) {
acc.push(it);
}
acc
})
.into_iter()
.enumerate()
.map(|(idx, val)| (val, &COLORS[idx]))
.collect::<HashMap<String, &[&str; 2]>>();
let results = workspaces
.iter()
.map(
|Workspace {
idx,
output,
is_active,
is_focused,
..
}| WsData {
color: output_colors_lut[&output.clone().expect("unreachable")]
[if *is_active { 1 } else { 0 }],
idx: *idx,
focused: *is_focused,
active: *is_active,
},
)
.collect::<Vec<_>>();
println!("{}", serde_json::to_string(&results).unwrap());
}
}
Ok(())
}
#[derive(Debug, Serialize)]
struct WsData {
color: &'static str,
idx: u8,
focused: bool,
active: bool,
}