diff --git a/Cargo.lock b/Cargo.lock index 0be5f80..6f7092e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,9 +148,9 @@ version = "0.1.0" name = "bar-ws-monitor" version = "0.1.0" dependencies = [ + "niri-ipc", "serde", "serde_json", - "swayipc", ] [[package]] @@ -864,6 +864,16 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "niri-ipc" +version = "25.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01515d0a7e73f1f3bd0347100542c4c3f6ebc280688add12e7ed2af4c35af4fb" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -994,9 +1004,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -1289,18 +1299,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1309,9 +1319,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -1448,33 +1458,11 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "swayipc" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa5d19f881f372e225095e297072e2e3ee1c4e9e3a46cafe5f5cf70f1313f29" -dependencies = [ - "serde", - "serde_json", - "swayipc-types", -] - -[[package]] -name = "swayipc-types" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e487a656336f74341c70a73a289f68d9ba3cab579ba776352ea0c6cdf603fcda" -dependencies = [ - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "syn" -version = "2.0.65" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", diff --git a/common.nix b/common.nix index c72d791..9c8005f 100644 --- a/common.nix +++ b/common.nix @@ -42,7 +42,7 @@ with builtins; { prusa-slicer wget git - neofetch + hyfetch pciutils zip unzip diff --git a/modules/desktop-environment/home/niri/binds.nix b/modules/desktop-environment/home/niri/binds.nix index 0dd7e0c..563a4dc 100644 --- a/modules/desktop-environment/home/niri/binds.nix +++ b/modules/desktop-environment/home/niri/binds.nix @@ -67,7 +67,8 @@ "Mod+BracketLeft".action.consume-or-expel-window-left = []; "Mod+BracketRight".action.consume-or-expel-window-right = []; "Mod+F".action.maximize-column = []; - "Mod+Shift+F".action.fullscreen-window = []; + "Mod+Shift+F".action.expand-column-to-available-width = []; + "Mod+Ctrl+F".action.fullscreen-window = []; "Mod+C".action.center-column = []; "Mod+Minus".action.set-column-width = "-5%"; "Mod+Equal".action.set-column-width = "+5%"; diff --git a/modules/desktop-environment/home/niri/default.nix b/modules/desktop-environment/home/niri/default.nix index 7dea436..27f6645 100644 --- a/modules/desktop-environment/home/niri/default.nix +++ b/modules/desktop-environment/home/niri/default.nix @@ -28,17 +28,9 @@ window-rules = [ # TODO: privacy screen rules - # { - # geometry-corner-radius = let val = 1.; in { - # bottom-left = val; - # bottom-right = val; - # top-left = val; - # top-right = val; - # }; - # clip-to-geometry = true; - # } ]; + # fix electron apps not doing wayland environment.ELECTRON_OZONE_PLATFORM_HINT = "auto"; }; } diff --git a/modules/desktop-environment/home/niri/style.nix b/modules/desktop-environment/home/niri/style.nix index 538a7e4..d9d9a61 100644 --- a/modules/desktop-environment/home/niri/style.nix +++ b/modules/desktop-environment/home/niri/style.nix @@ -36,8 +36,9 @@ hide-when-single-tab = true; active.color = "#5bcefa"; inactive.color = "#3c3836"; - gap = 1; - width = 3; + gap = 2; + width = 5; + corner-radius= 3; position = "left"; gaps-between-tabs = 0; }; diff --git a/modules/desktop-environment/home/panels/eww/configDir/bottomBar/workspaces.yuck b/modules/desktop-environment/home/panels/eww/configDir/bottomBar/workspaces.yuck index 4c5495f..96e37a5 100644 --- a/modules/desktop-environment/home/panels/eww/configDir/bottomBar/workspaces.yuck +++ b/modules/desktop-environment/home/panels/eww/configDir/bottomBar/workspaces.yuck @@ -3,9 +3,10 @@ :class "workspaces" (for workspace in workspaces (button - :class "${workspace.urgent ? "urgent" : ""} ${workspace.focused ? "focused" : 0}" + :style "border-bottom: 4px solid ${workspace.color}" + :class "${workspace.active ? "focused" : 0}" :onclick "swaymsg workspace ${workspace.name}" - (label :text "${workspace.name}") + (label :text "${workspace.idx}") ) ) ) diff --git a/programs/bar-ws-monitor/Cargo.toml b/programs/bar-ws-monitor/Cargo.toml index 5c1a1f6..f7c7ec4 100644 --- a/programs/bar-ws-monitor/Cargo.toml +++ b/programs/bar-ws-monitor/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" [dependencies] serde = { version = "1.0.209", features = [ "derive" ] } serde_json = "1.0.127" -swayipc = "3.0.2" +niri-ipc = "25.2.0" diff --git a/programs/bar-ws-monitor/src/main.rs b/programs/bar-ws-monitor/src/main.rs index b911272..23cfb6e 100644 --- a/programs/bar-ws-monitor/src/main.rs +++ b/programs/bar-ws-monitor/src/main.rs @@ -1,28 +1,87 @@ use core::panic; +use std::{collections::HashMap, io::Write}; +use niri_ipc::{ + socket::Socket, + state::{EventStreamState, EventStreamStatePart}, + Request, Response, Workspace, +}; use serde::Serialize; -use swayipc::{Connection, Event, EventType, Fallible, Workspace, WorkspaceChange}; -fn main() -> Fallible<()> { - let mut con = Connection::new()?; - let mut workspaces: Vec = con - .get_workspaces()? - .into_iter() - .map(|ws| ws.into()) - .collect(); - println!("{}", serde_json::ser::to_string(&workspaces).unwrap()); +// 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 +]; - for ev in con.subscribe([EventType::Workspace])? { - // the lazy/ugly solution! - // we create a new connection and request workspaces again and again and again - // TODO: properly handle events one by one - let mut con = Connection::new()?; - workspaces = con - .get_workspaces()? - .into_iter() - .map(|ws| ws.into()) - .collect(); - println!("{}", serde_json::ser::to_string(&workspaces).unwrap()); +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::>(); + 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::>(); + + let results = workspaces + .iter() + .map(|ws| WsData { + color: output_colors_lut[&ws.output.clone().expect("unreachable")] + [if ws.is_active { 1 } else { 0 }], + idx: ws.idx, + focused: ws.is_focused, + active: ws.is_active, + }) + .collect::>(); + + println!("{}", serde_json::to_string(&results).unwrap()); + } } Ok(()) @@ -30,24 +89,8 @@ fn main() -> Fallible<()> { #[derive(Debug, Serialize)] struct WsData { - name: String, + color: &'static str, + idx: u8, focused: bool, - urgent: bool, -} - -impl From for WsData { - fn from( - Workspace { - name, - focused, - urgent, - .. - }: Workspace, - ) -> Self { - WsData { - name, - focused, - urgent, - } - } + active: bool, }