From 8d587dd4d52b42c499d389c640f2ee86e9f098e2 Mon Sep 17 00:00:00 2001 From: Stephan Date: Mon, 27 Jul 2026 12:28:01 -0700 Subject: [PATCH] Add statmon script and update configs --- btop/btop.conf | 2 +- hypr/hyprland/bindings.conf | 7 +- hypr/scripts/statmon/Cargo.lock | 721 +++++++++++++++++++++++++++++++ hypr/scripts/statmon/Cargo.toml | 9 + hypr/scripts/statmon/src/main.rs | 475 ++++++++++++++++++++ zsh/zsh_profile | 2 +- 6 files changed, 1213 insertions(+), 3 deletions(-) create mode 100644 hypr/scripts/statmon/Cargo.lock create mode 100644 hypr/scripts/statmon/Cargo.toml create mode 100644 hypr/scripts/statmon/src/main.rs diff --git a/btop/btop.conf b/btop/btop.conf index e60c01c..63bf0e7 100644 --- a/btop/btop.conf +++ b/btop/btop.conf @@ -61,7 +61,7 @@ graph_symbol_net = "default" graph_symbol_proc = "default" #* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace. -shown_boxes = "proc net" +shown_boxes = "proc mem net cpu" #* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs. update_ms = 1900 diff --git a/hypr/hyprland/bindings.conf b/hypr/hyprland/bindings.conf index db89b9d..17c7cfb 100644 --- a/hypr/hyprland/bindings.conf +++ b/hypr/hyprland/bindings.conf @@ -18,6 +18,7 @@ bind = $mainMod, L, exec, hyprlock bind = $mainMod, M, exit, bind = $mainMod, N, exec, swaync-client -t -sw bind = $mainMod, P, pseudo, # dwindle +bind = $mainMod, S, exec, $terminal -e ~/.config/hypr/scripts/statmon/target/release/statmon bind = $mainMod SHIFT, S, exec, hyprshot -m region --clipboard-only, bind = $mainMod, Q, exec, ~/.config/hypr/scripts/power-menu.sh bind = $mainMod, U, exec, ~/.config/hypr/scripts/update-sys.sh up @@ -96,4 +97,8 @@ bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%- bindl = , XF86AudioNext, exec, playerctl next bindl = , XF86AudioPause, exec, playerctl play-pause bindl = , XF86AudioPlay, exec, playerctl play-pause -bindl = , XF86AudioPrev, exec, playerctl previou +bindl = , XF86AudioPrev, exec, playerctl previous + +# --- Mouse Side Button Remaps --- +bind = , mouse:276, sendshortcut, , ESCAPE, active +bind = , mouse:275, sendshortcut, , RETURN, active diff --git a/hypr/scripts/statmon/Cargo.lock b/hypr/scripts/statmon/Cargo.lock new file mode 100644 index 0000000..fafcd1f --- /dev/null +++ b/hypr/scripts/statmon/Cargo.lock @@ -0,0 +1,721 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "cc" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "crossbeam-deque" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "either" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "futures-core" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" + +[[package]] +name = "futures-task" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" + +[[package]] +name = "futures-util" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "js-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "ntapi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" +dependencies = [ + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "statmon" +version = "0.1.0" +dependencies = [ + "chrono", + "crossterm", + "sysinfo", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sysinfo" +version = "0.30.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/hypr/scripts/statmon/Cargo.toml b/hypr/scripts/statmon/Cargo.toml new file mode 100644 index 0000000..18fffc9 --- /dev/null +++ b/hypr/scripts/statmon/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "statmon" +version = "0.1.0" +edition = "2024" + +[dependencies] +sysinfo = "0.30" +crossterm = "0.27" +chrono = "0.4" diff --git a/hypr/scripts/statmon/src/main.rs b/hypr/scripts/statmon/src/main.rs new file mode 100644 index 0000000..e573d04 --- /dev/null +++ b/hypr/scripts/statmon/src/main.rs @@ -0,0 +1,475 @@ +use chrono::Local; +use crossterm::{ + cursor, execute, + style::{Color, ResetColor, SetForegroundColor}, + terminal::{Clear, ClearType}, +}; +use std::{ + fs, + io::{stdout, Write}, + path::Path, + process::Command, + thread, + time::{Duration, Instant}, +}; +use sysinfo::{ + Components, CpuRefreshKind, MemoryRefreshKind, Networks, ProcessRefreshKind, + RefreshKind, System, +}; + +// --- BTOP Theme RGB Constants --- +const FG_MAIN: Color = Color::Rgb { r: 157, g: 132, b: 98 }; // #9d8462 +const ACCENT: Color = Color::Rgb { r: 255, g: 145, b: 0 }; // #ff9100 +const ALERT: Color = Color::Rgb { r: 255, g: 0, b: 0 }; // #ff0000 +const METER_BG: Color = Color::Rgb { r: 48, g: 51, b: 64 }; // #303340 + +fn send_notification(summary: &str, body: &str, urgency: &str) { + let _ = Command::new("notify-send") + .arg("-u") + .arg(urgency) + .arg("-a") + .arg("System Dashboard") + .arg(summary) + .arg(body) + .spawn(); +} + +fn make_bar(pct: f32, width: usize) -> String { + let clamped = pct.clamp(0.0, 100.0); + let filled = ((clamped / 100.0) * width as f32).round() as usize; + let empty = width.saturating_sub(filled); + format!("[{}{}]", "█".repeat(filled), "░".repeat(empty)) +} + +fn get_battery_info() -> (String, u32) { + let bat_paths = ["/sys/class/power_supply/BAT0", "/sys/class/power_supply/BAT1"]; + for path in bat_paths { + if Path::new(path).exists() { + let cap_str = fs::read_to_string(format!("{}/capacity", path)) + .unwrap_or_default() + .trim() + .to_string(); + let status = fs::read_to_string(format!("{}/status", path)) + .unwrap_or_default() + .trim() + .to_string(); + + if let Ok(cap) = cap_str.parse::() { + return (format!("{}% ({})", cap, status), cap); + } + } + } + ("N/A".to_string(), 100) +} + +fn get_mouse_battery() -> String { + if let Ok(entries) = fs::read_dir("/sys/class/power_supply") { + for entry in entries.flatten() { + let path = entry.path(); + let name = path.file_name().unwrap_or_default().to_string_lossy().to_string(); + + if name.starts_with("hid") || name.starts_with("mouse") { + let cap = fs::read_to_string(path.join("capacity")) + .unwrap_or_default() + .trim() + .to_string(); + let status = fs::read_to_string(path.join("status")) + .unwrap_or_default() + .trim() + .to_string(); + + if !cap.is_empty() { + let status_str = if status.is_empty() { "Wireless".to_string() } else { status }; + return format!("{}% ({})", cap, status_str); + } + } + } + } + "Not Connected / Unknown".to_string() +} + +fn get_cpu_temp(components: &Components) -> (String, f32) { + for comp in components { + let label = comp.label().to_lowercase(); + if label.contains("core") || label.contains("package") || label.contains("cpu") { + let temp = comp.temperature(); + return (format!("{:.0}°C", temp), temp); + } + } + + if let Ok(entries) = fs::read_dir("/sys/class/hwmon") { + for entry in entries.flatten() { + let path = entry.path(); + if let Ok(name) = fs::read_to_string(path.join("name")) { + if name.contains("coretemp") || name.contains("k10temp") || name.contains("cpu") { + if let Ok(temp_str) = fs::read_to_string(path.join("temp1_input")) { + if let Ok(temp_val) = temp_str.trim().parse::() { + let temp = temp_val / 1000.0; + return (format!("{:.0}°C", temp), temp); + } + } + } + } + } + } + + ("N/A".to_string(), 0.0) +} + +fn get_gpu_info() -> (String, f32) { + for card_num in 0..4 { + let card_path = format!("/sys/class/drm/card{}/device", card_num); + let path = Path::new(&card_path); + + if path.exists() { + let busy_file = if path.join("gpu_busy_percent").exists() { + Some(path.join("gpu_busy_percent")) + } else if path.join("load").exists() { + Some(path.join("load")) + } else { + None + }; + + if let Some(bf) = busy_file { + let busy_pct = fs::read_to_string(bf) + .unwrap_or_default() + .trim() + .parse::() + .unwrap_or(0.0); + + let vram_used = fs::read_to_string(path.join("mem_info_vram_used")) + .unwrap_or_default() + .trim() + .parse::() + .unwrap_or(0) / 1024 / 1024; + + let vram_total = fs::read_to_string(path.join("mem_info_vram_total")) + .unwrap_or_default() + .trim() + .parse::() + .unwrap_or(0) / 1024 / 1024; + + return if vram_total > 0 { + (format!("{} (VRAM: {}MB / {}MB)", make_bar(busy_pct, 16), vram_used, vram_total), busy_pct) + } else { + (format!("{} ({:.0}%)", make_bar(busy_pct, 16), busy_pct), busy_pct) + }; + } + } + } + ("N/A".to_string(), 0.0) +} + +fn get_nvme_temp() -> String { + if let Ok(entries) = fs::read_dir("/sys/class/hwmon") { + for entry in entries.flatten() { + let path = entry.path(); + if let Ok(name) = fs::read_to_string(path.join("name")) { + if name.trim() == "nvme" { + if let Ok(temp_str) = fs::read_to_string(path.join("temp1_input")) { + if let Ok(temp_val) = temp_str.trim().parse::() { + return format!("{:.0}°C", temp_val / 1000.0); + } + } + } + } + } + } + "N/A".to_string() +} + +fn get_disk_io(last_read_sectors: &mut u64, last_write_sectors: &mut u64, elapsed_secs: f32) -> String { + if let Ok(content) = fs::read_to_string("/proc/diskstats") { + let mut total_read = 0u64; + let mut total_write = 0u64; + + for line in content.lines() { + let parts: Vec<&str> = line.split_whitespace().collect(); + if parts.len() >= 10 { + let dev_name = parts[2]; + if dev_name.starts_with("nvme") && dev_name.ends_with("n1") || dev_name.starts_with("sd") && dev_name.len() == 3 { + let r_sectors: u64 = parts[5].parse().unwrap_or(0); + let w_sectors: u64 = parts[9].parse().unwrap_or(0); + total_read += r_sectors; + total_write += w_sectors; + } + } + } + + let read_mb = if *last_read_sectors > 0 && total_read >= *last_read_sectors { + ((total_read - *last_read_sectors) as f32 * 512.0) / (1024.0 * 1024.0 * elapsed_secs) + } else { + 0.0 + }; + + let write_mb = if *last_write_sectors > 0 && total_write >= *last_write_sectors { + ((total_write - *last_write_sectors) as f32 * 512.0) / (1024.0 * 1024.0 * elapsed_secs) + } else { + 0.0 + }; + + *last_read_sectors = total_read; + *last_write_sectors = total_write; + + format!("R: {:.1} MB/s W: {:.1} MB/s", read_mb, write_mb) + } else { + "N/A".to_string() + } +} + +fn get_systemd_failed() -> (String, u32) { + if let Ok(output) = Command::new("systemctl").args(["--failed", "--quiet"]).output() { + if output.status.success() { + if let Ok(stdout) = String::from_utf8(output.stdout) { + let lines: Vec<&str> = stdout.lines().filter(|l| !l.trim().is_empty()).collect(); + let count = lines.len() as u32; + if count == 0 { + return ("0 units".to_string(), 0); + } else { + return (format!("{} unit(s) failed", count), count); + } + } + } + } + ("0 units".to_string(), 0) +} + +fn print_line(stdout: &mut std::io::Stdout, label: &str, value: &str, val_color: Color) -> Result<(), Box> { + execute!(stdout, SetForegroundColor(FG_MAIN))?; + write!(stdout, " {:<14}: ", label)?; + execute!(stdout, SetForegroundColor(val_color))?; + writeln!(stdout, "{}", value)?; + Ok(()) +} + +fn main() -> Result<(), Box> { + let mut sys = System::new_with_specifics( + RefreshKind::new() + .with_cpu(CpuRefreshKind::everything()) + .with_memory(MemoryRefreshKind::everything()) + .with_processes(ProcessRefreshKind::everything()), + ); + + let mut networks = Networks::new_with_refreshed_list(); + let mut components = Components::new_with_refreshed_list(); + + let mut stdout = stdout(); + + let alert_threshold = Duration::from_secs(10); + let mut core_max_start: Option = None; + let mut core_max_alerted = false; + + let mut temp_high_start: Option = None; + let mut temp_high_alerted = false; + + let mut mem_high_start: Option = None; + let mut mem_high_alerted = false; + + let mut bat_notified_50 = false; + let mut bat_notified_25 = false; + + let mut last_read_sectors = 0u64; + let mut last_write_sectors = 0u64; + let mut last_tick = Instant::now(); + + thread::sleep(Duration::from_millis(1000)); + + loop { + let elapsed_secs = last_tick.elapsed().as_secs_f32(); + last_tick = Instant::now(); + + sys.refresh_all(); + networks.refresh(); + components.refresh(); + + let time_str = Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); + let (bat_str, bat_pct) = get_battery_info(); + let mouse_bat_str = get_mouse_battery(); + let (temp_str, temp_val) = get_cpu_temp(&components); + let (gpu_str, _) = get_gpu_info(); + let nvme_temp = get_nvme_temp(); + let disk_io = get_disk_io(&mut last_read_sectors, &mut last_write_sectors, elapsed_secs); + let (failed_sysd, failed_count) = get_systemd_failed(); + + // Memory Metrics + let total_mem = sys.total_memory() / 1024 / 1024; + let used_mem = sys.used_memory() / 1024 / 1024; + let mem_pct = if total_mem > 0 { (used_mem as f32 * 100.0) / total_mem as f32 } else { 0.0 }; + + let total_swap = sys.total_swap() / 1024 / 1024; + let used_swap = sys.used_swap() / 1024 / 1024; + let swap_pct = if total_swap > 0 { (used_swap as f32 * 100.0) / total_swap as f32 } else { 0.0 }; + + // CPU Metrics + let global_cpu = sys.global_cpu_info().cpu_usage(); + let cpus = sys.cpus(); + let num_cores = cpus.len() as f32; + + let mut has_core_at_100 = false; + let mut core_str = String::new(); + + for (i, cpu) in cpus.iter().enumerate() { + let usage = cpu.cpu_usage(); + if usage >= 99.0 { + has_core_at_100 = true; + } + if usage >= 80.0 { + core_str.push_str(&format!("C{}: {:.0}% | ", i, usage)); + } + } + + let (final_core_str, core_color) = if core_str.is_empty() { + ("All under 80%".to_string(), METER_BG) + } else { + if core_str.ends_with(" | ") { + core_str.truncate(core_str.len() - 3); + } + (core_str, ALERT) + }; + + // --- NOTIFICATIONS --- + if bat_pct <= 25 && !bat_notified_25 { + send_notification("Low Battery Warning", &format!("Battery is down to {}%!", bat_pct), "critical"); + bat_notified_25 = true; + } else if bat_pct <= 50 && bat_pct > 25 && !bat_notified_50 { + send_notification("Battery Notice", &format!("Battery dropped below 50% ({}%).", bat_pct), "normal"); + bat_notified_50 = true; + } else if bat_pct > 55 { + bat_notified_50 = false; + bat_notified_25 = false; + } + + if has_core_at_100 { + let start = core_max_start.get_or_insert_with(Instant::now); + if start.elapsed() >= alert_threshold && !core_max_alerted { + send_notification("CPU Warning", "A CPU core has been at 100% usage for over 10 seconds!", "critical"); + core_max_alerted = true; + } + } else { + core_max_start = None; + core_max_alerted = false; + } + + if temp_val >= 85.0 { + let start = temp_high_start.get_or_insert_with(Instant::now); + if start.elapsed() >= alert_threshold && !temp_high_alerted { + send_notification("High Temperature Alert", &format!("CPU Temperature is at {:.0}°C for over 10s!", temp_val), "critical"); + temp_high_alerted = true; + } + } else { + temp_high_start = None; + temp_high_alerted = false; + } + + if mem_pct >= 80.0 { + let start = mem_high_start.get_or_insert_with(Instant::now); + if start.elapsed() >= alert_threshold && !mem_high_alerted { + send_notification("High Memory Usage", &format!("RAM usage has been above 80% ({:.0}%) for over 10s!", mem_pct), "critical"); + mem_high_alerted = true; + } + } else { + mem_high_start = None; + mem_high_alerted = false; + } + + // Network Bandwidth Calculations + let mut rx_bytes = 0; + let mut tx_bytes = 0; + for (_iface, data) in &networks { + rx_bytes += data.received(); + tx_bytes += data.transmitted(); + } + let down_kb = ((rx_bytes / 1024) as f32 / elapsed_secs) as u64; + let up_kb = ((tx_bytes / 1024) as f32 / elapsed_secs) as u64; + + // --- Flat Process List Logic --- + let my_pid = std::process::id(); + let mut procs: Vec<_> = sys + .processes() + .values() + .filter(|p| p.pid().as_u32() != my_pid) + .collect(); + + // Sort by individual process CPU usage descending + procs.sort_by(|a, b| b.cpu_usage().partial_cmp(&a.cpu_usage()).unwrap_or(std::cmp::Ordering::Equal)); + let top_5 = procs.into_iter().take(5); + + // Render Screen + execute!(stdout, cursor::MoveTo(0, 0), Clear(ClearType::FromCursorDown))?; + + execute!(stdout, SetForegroundColor(FG_MAIN))?; + println!("================================================================================================"); + execute!(stdout, SetForegroundColor(ACCENT))?; + println!(" SYSTEM DASHBOARD "); + execute!(stdout, SetForegroundColor(FG_MAIN))?; + println!("================================================================================================"); + + print_line(&mut stdout, "Time", &time_str, ACCENT)?; + print_line(&mut stdout, "Laptop Bat", &bat_str, FG_MAIN)?; + print_line(&mut stdout, "Mouse Bat", &mouse_bat_str, FG_MAIN)?; + + let temp_color = if temp_val >= 85.0 { ALERT } else if temp_val >= 70.0 { ACCENT } else { FG_MAIN }; + print_line(&mut stdout, "CPU Temp", &temp_str, temp_color)?; + + let cpu_color = if global_cpu >= 85.0 { ALERT } else if global_cpu >= 60.0 { ACCENT } else { FG_MAIN }; + let cpu_bar_val = format!("{} {:.1}%", make_bar(global_cpu, 16), global_cpu); + print_line(&mut stdout, "CPU Usage", &cpu_bar_val, cpu_color)?; + + print_line(&mut stdout, "High Cores", &final_core_str, core_color)?; + + let mem_color = if mem_pct >= 90.0 { ALERT } else if mem_pct >= 70.0 { ACCENT } else { FG_MAIN }; + let mem_bar_val = format!("{} {:.0}% ({}MB / {}MB)", make_bar(mem_pct, 16), mem_pct, used_mem, total_mem); + print_line(&mut stdout, "Memory Usage", &mem_bar_val, mem_color)?; + + let swap_color = if swap_pct >= 70.0 { ALERT } else if swap_pct >= 30.0 { ACCENT } else { FG_MAIN }; + let swap_bar_val = format!("{} {:.0}% ({}MB / {}MB)", make_bar(swap_pct, 16), swap_pct, used_swap, total_swap); + print_line(&mut stdout, "Swap Usage", &swap_bar_val, swap_color)?; + + print_line(&mut stdout, "Radeon GPU", &gpu_str, ACCENT)?; + print_line(&mut stdout, "NVMe Temp", &nvme_temp, FG_MAIN)?; + print_line(&mut stdout, "Disk I/O", &disk_io, ACCENT)?; + print_line(&mut stdout, "Network", &format!("↓ {} KB/s ↑ {} KB/s", down_kb, up_kb), ACCENT)?; + + let sysd_color = if failed_count > 0 { ALERT } else { FG_MAIN }; + print_line(&mut stdout, "Systemd Units", &failed_sysd, sysd_color)?; + + // Render Top 5 Table + execute!(stdout, SetForegroundColor(FG_MAIN))?; + println!("------------------------------------------------------------------------------------------------"); + execute!(stdout, SetForegroundColor(ACCENT))?; + println!(" {:<8} {:<30} {:<12} {:<12}", "PID", "NAME", "CPU %", "MEM (MB)"); + execute!(stdout, SetForegroundColor(FG_MAIN))?; + println!("------------------------------------------------------------------------------------------------"); + + for p in top_5 { + let raw_name = p.name(); + let display_name = if raw_name.len() > 28 { + format!("{}...", &raw_name[..25]) + } else { + raw_name.to_string() + }; + + // Normalize individual process CPU % across logical cores + let cpu_normalized = p.cpu_usage() / num_cores; + // Direct KiB to MB conversion for single process memory + let mem_mb = p.memory() / 1024; + + let row_color = if cpu_normalized >= 25.0 { ALERT } else if cpu_normalized >= 10.0 { ACCENT } else { FG_MAIN }; + + execute!(stdout, SetForegroundColor(row_color))?; + println!(" {:<8} {:<30} {:<12.1} {:<12}", p.pid().as_u32(), display_name, cpu_normalized, mem_mb); + } + + execute!(stdout, SetForegroundColor(FG_MAIN))?; + println!("================================================================================================"); + + if global_cpu > 85.0 || mem_pct > 90.0 || temp_val > 85.0 { + execute!(stdout, SetForegroundColor(ALERT))?; + println!("\n WARNING: HIGH RESOURCE USAGE DETECTED! "); + } + + execute!(stdout, ResetColor)?; + stdout.flush()?; + thread::sleep(Duration::from_secs(2)); + } +} diff --git a/zsh/zsh_profile b/zsh/zsh_profile index 545d1be..aa0eb96 100644 --- a/zsh/zsh_profile +++ b/zsh/zsh_profile @@ -24,7 +24,7 @@ alias htb="sudo openvpn --config /etc/openvpn/client/htb.conf" alias osrs="flatpak run com.adamcake.Bolt" alias vwgermany="ssh -L 8080:localhost:4567 root@13.37.7.42" alias cleanup='sudo pacman -Rs $(pacman -Qdtq)' -alias network='sudo systemctl stop wpa_supplicant.service && sudo systemctl restart NetworkManager && sudo ip link set wlp2s0 up' +alias network='sudo ip link set enp99s0 down && sleep 2 && sudo ip link set enp99s0 up' # Navigation & listing alias ls='eza --icons --group-directories-first'