From 95353bb8d6eff752a430f9a6fb48c7d541a8b340 Mon Sep 17 00:00:00 2001 From: benstrb Date: Fri, 20 Mar 2026 23:01:18 +0100 Subject: [PATCH 1/9] muhehe --- .direnv/bin/nix-direnv-reload | 10 +++++----- .../774f2myazjrl15013q55gc6bibqnr8vr-source | 1 + .../f5cfz7byd8pwcv6dyg34b66fck7iqsc0-source | 1 - ...le-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa | 2 +- ...a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc | 14 ++++++-------- flake.nix | 3 +-- src/main.rs | 18 +++++++++++++----- 7 files changed, 27 insertions(+), 22 deletions(-) create mode 120000 .direnv/flake-inputs/774f2myazjrl15013q55gc6bibqnr8vr-source delete mode 120000 .direnv/flake-inputs/f5cfz7byd8pwcv6dyg34b66fck7iqsc0-source diff --git a/.direnv/bin/nix-direnv-reload b/.direnv/bin/nix-direnv-reload index 6f1652e..059b68b 100755 --- a/.direnv/bin/nix-direnv-reload +++ b/.direnv/bin/nix-direnv-reload @@ -1,19 +1,19 @@ #!/usr/bin/env bash set -e -if [[ ! -d "/mnt/removable/Projects/Rust/wayland_panel" ]]; then +if [[ ! -d "/home/benag/.nix-config/configuration/modules/dots/wayland_panel" ]]; then echo "Cannot find source directory; Did you move it?" - echo "(Looking for "/mnt/removable/Projects/Rust/wayland_panel")" + echo "(Looking for "/home/benag/.nix-config/configuration/modules/dots/wayland_panel")" echo 'Cannot force reload with this script - use "direnv reload" manually and then try again' exit 1 fi # rebuild the cache forcefully -_nix_direnv_force_reload=1 direnv exec "/mnt/removable/Projects/Rust/wayland_panel" true +_nix_direnv_force_reload=1 direnv exec "/home/benag/.nix-config/configuration/modules/dots/wayland_panel" true # Update the mtime for .envrc. # This will cause direnv to reload again - but without re-building. -touch "/mnt/removable/Projects/Rust/wayland_panel/.envrc" +touch "/home/benag/.nix-config/configuration/modules/dots/wayland_panel/.envrc" # Also update the timestamp of whatever profile_rc we have. # This makes sure that we know we are up to date. -touch -r "/mnt/removable/Projects/Rust/wayland_panel/.envrc" "/mnt/removable/Projects/Rust/wayland_panel/.direnv"/*.rc +touch -r "/home/benag/.nix-config/configuration/modules/dots/wayland_panel/.envrc" "/home/benag/.nix-config/configuration/modules/dots/wayland_panel/.direnv"/*.rc diff --git a/.direnv/flake-inputs/774f2myazjrl15013q55gc6bibqnr8vr-source b/.direnv/flake-inputs/774f2myazjrl15013q55gc6bibqnr8vr-source new file mode 120000 index 0000000..a772d6e --- /dev/null +++ b/.direnv/flake-inputs/774f2myazjrl15013q55gc6bibqnr8vr-source @@ -0,0 +1 @@ +/nix/store/774f2myazjrl15013q55gc6bibqnr8vr-source \ No newline at end of file diff --git a/.direnv/flake-inputs/f5cfz7byd8pwcv6dyg34b66fck7iqsc0-source b/.direnv/flake-inputs/f5cfz7byd8pwcv6dyg34b66fck7iqsc0-source deleted file mode 120000 index af3dc82..0000000 --- a/.direnv/flake-inputs/f5cfz7byd8pwcv6dyg34b66fck7iqsc0-source +++ /dev/null @@ -1 +0,0 @@ -/nix/store/f5cfz7byd8pwcv6dyg34b66fck7iqsc0-source \ No newline at end of file diff --git a/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa index 1196720..d8b34ee 120000 --- a/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa +++ b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa @@ -1 +1 @@ -/nix/store/sw4zwpy7r16mhiqlx6niqmrfa16niy10-nix-shell-env \ No newline at end of file +/nix/store/19sic4f4w000jj6fscbhz98zaib4f4ml-nix-shell-env \ No newline at end of file diff --git a/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc index 65e0266..e5832b6 100644 --- a/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc +++ b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc @@ -35,7 +35,7 @@ LD='ld' export LD LD_FOR_TARGET='ld' export LD_FOR_TARGET -LD_LIBRARY_PATH='/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib:/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib:/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib:/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib:/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib:/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib' +LD_LIBRARY_PATH='/run/opengl-driver/lib:/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib:/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib:/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib:/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib:/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib:/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib' export LD_LIBRARY_PATH LINENO='76' MACHTYPE='x86_64-pc-linux-gnu' @@ -47,7 +47,7 @@ NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu='1' export NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu NIX_BINTOOLS_WRAPPER_TARGET_TARGET_x86_64_unknown_linux_gnu='1' export NIX_BINTOOLS_WRAPPER_TARGET_TARGET_x86_64_unknown_linux_gnu -NIX_BUILD_CORES='16' +NIX_BUILD_CORES='4' export NIX_BUILD_CORES NIX_CC='/nix/store/kbw2j1vag664b3sj3rjwz9v53cqx87sb-gcc-wrapper-15.2.0' export NIX_CC @@ -57,7 +57,7 @@ NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu='1' export NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu NIX_CC_WRAPPER_TARGET_TARGET_x86_64_unknown_linux_gnu='1' export NIX_CC_WRAPPER_TARGET_TARGET_x86_64_unknown_linux_gnu -NIX_CFLAGS_COMPILE=' -frandom-seed=sw4zwpy7r1 -isystem /nix/store/d0irz6jq0d16h6iggq1mcwwvvxzi4lvy-gnumake-4.4.1/include -isystem /nix/store/d0irz6jq0d16h6iggq1mcwwvvxzi4lvy-gnumake-4.4.1/include -isystem /nix/store/blr5zdnxfckm1690cdx6anmh3s17sx5p-wayland-1.24.0-dev/include -isystem /nix/store/blr5zdnxfckm1690cdx6anmh3s17sx5p-wayland-1.24.0-dev/include -isystem /nix/store/ixxx8nb52qxl25lix063rb35lk94p7r8-libxkbcommon-1.11.0-dev/include -isystem /nix/store/ixxx8nb52qxl25lix063rb35lk94p7r8-libxkbcommon-1.11.0-dev/include -isystem /nix/store/jhb15l57qmqxck5ddd1dh2ys729vc8gb-glib-2.86.3-dev/include -isystem /nix/store/jhb15l57qmqxck5ddd1dh2ys729vc8gb-glib-2.86.3-dev/include -isystem /nix/store/87y9237m9c9m9mxk9ajwdfmn78vz6w2y-zlib-1.3.1-dev/include -isystem /nix/store/87y9237m9c9m9mxk9ajwdfmn78vz6w2y-zlib-1.3.1-dev/include -isystem /nix/store/xff3v3hj0slzkxhksrsrscva5scf35an-libffi-3.5.2-dev/include -isystem /nix/store/xff3v3hj0slzkxhksrsrscva5scf35an-libffi-3.5.2-dev/include -isystem /nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/include -isystem /nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/include -isystem /nix/store/p73x5sdhi1wgas4d6mm8yxbzawih2yp2-glibc-iconv-2.42/include -isystem /nix/store/p73x5sdhi1wgas4d6mm8yxbzawih2yp2-glibc-iconv-2.42/include -isystem /nix/store/3drkfkyzxfb9rcpnv1xy0nvdj78qngy8-libglvnd-1.7.0-dev/include -isystem /nix/store/3drkfkyzxfb9rcpnv1xy0nvdj78qngy8-libglvnd-1.7.0-dev/include -isystem /nix/store/d0irz6jq0d16h6iggq1mcwwvvxzi4lvy-gnumake-4.4.1/include -isystem /nix/store/d0irz6jq0d16h6iggq1mcwwvvxzi4lvy-gnumake-4.4.1/include -isystem /nix/store/blr5zdnxfckm1690cdx6anmh3s17sx5p-wayland-1.24.0-dev/include -isystem /nix/store/blr5zdnxfckm1690cdx6anmh3s17sx5p-wayland-1.24.0-dev/include -isystem /nix/store/ixxx8nb52qxl25lix063rb35lk94p7r8-libxkbcommon-1.11.0-dev/include -isystem /nix/store/ixxx8nb52qxl25lix063rb35lk94p7r8-libxkbcommon-1.11.0-dev/include -isystem /nix/store/jhb15l57qmqxck5ddd1dh2ys729vc8gb-glib-2.86.3-dev/include -isystem /nix/store/jhb15l57qmqxck5ddd1dh2ys729vc8gb-glib-2.86.3-dev/include -isystem /nix/store/87y9237m9c9m9mxk9ajwdfmn78vz6w2y-zlib-1.3.1-dev/include -isystem /nix/store/87y9237m9c9m9mxk9ajwdfmn78vz6w2y-zlib-1.3.1-dev/include -isystem /nix/store/xff3v3hj0slzkxhksrsrscva5scf35an-libffi-3.5.2-dev/include -isystem /nix/store/xff3v3hj0slzkxhksrsrscva5scf35an-libffi-3.5.2-dev/include -isystem /nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/include -isystem /nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/include -isystem /nix/store/p73x5sdhi1wgas4d6mm8yxbzawih2yp2-glibc-iconv-2.42/include -isystem /nix/store/p73x5sdhi1wgas4d6mm8yxbzawih2yp2-glibc-iconv-2.42/include -isystem /nix/store/3drkfkyzxfb9rcpnv1xy0nvdj78qngy8-libglvnd-1.7.0-dev/include -isystem /nix/store/3drkfkyzxfb9rcpnv1xy0nvdj78qngy8-libglvnd-1.7.0-dev/include' +NIX_CFLAGS_COMPILE=' -frandom-seed=19sic4f4w0 -isystem /nix/store/d0irz6jq0d16h6iggq1mcwwvvxzi4lvy-gnumake-4.4.1/include -isystem /nix/store/d0irz6jq0d16h6iggq1mcwwvvxzi4lvy-gnumake-4.4.1/include -isystem /nix/store/blr5zdnxfckm1690cdx6anmh3s17sx5p-wayland-1.24.0-dev/include -isystem /nix/store/blr5zdnxfckm1690cdx6anmh3s17sx5p-wayland-1.24.0-dev/include -isystem /nix/store/ixxx8nb52qxl25lix063rb35lk94p7r8-libxkbcommon-1.11.0-dev/include -isystem /nix/store/ixxx8nb52qxl25lix063rb35lk94p7r8-libxkbcommon-1.11.0-dev/include -isystem /nix/store/jhb15l57qmqxck5ddd1dh2ys729vc8gb-glib-2.86.3-dev/include -isystem /nix/store/jhb15l57qmqxck5ddd1dh2ys729vc8gb-glib-2.86.3-dev/include -isystem /nix/store/87y9237m9c9m9mxk9ajwdfmn78vz6w2y-zlib-1.3.1-dev/include -isystem /nix/store/87y9237m9c9m9mxk9ajwdfmn78vz6w2y-zlib-1.3.1-dev/include -isystem /nix/store/xff3v3hj0slzkxhksrsrscva5scf35an-libffi-3.5.2-dev/include -isystem /nix/store/xff3v3hj0slzkxhksrsrscva5scf35an-libffi-3.5.2-dev/include -isystem /nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/include -isystem /nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/include -isystem /nix/store/p73x5sdhi1wgas4d6mm8yxbzawih2yp2-glibc-iconv-2.42/include -isystem /nix/store/p73x5sdhi1wgas4d6mm8yxbzawih2yp2-glibc-iconv-2.42/include -isystem /nix/store/3drkfkyzxfb9rcpnv1xy0nvdj78qngy8-libglvnd-1.7.0-dev/include -isystem /nix/store/3drkfkyzxfb9rcpnv1xy0nvdj78qngy8-libglvnd-1.7.0-dev/include -isystem /nix/store/d0irz6jq0d16h6iggq1mcwwvvxzi4lvy-gnumake-4.4.1/include -isystem /nix/store/d0irz6jq0d16h6iggq1mcwwvvxzi4lvy-gnumake-4.4.1/include -isystem /nix/store/blr5zdnxfckm1690cdx6anmh3s17sx5p-wayland-1.24.0-dev/include -isystem /nix/store/blr5zdnxfckm1690cdx6anmh3s17sx5p-wayland-1.24.0-dev/include -isystem /nix/store/ixxx8nb52qxl25lix063rb35lk94p7r8-libxkbcommon-1.11.0-dev/include -isystem /nix/store/ixxx8nb52qxl25lix063rb35lk94p7r8-libxkbcommon-1.11.0-dev/include -isystem /nix/store/jhb15l57qmqxck5ddd1dh2ys729vc8gb-glib-2.86.3-dev/include -isystem /nix/store/jhb15l57qmqxck5ddd1dh2ys729vc8gb-glib-2.86.3-dev/include -isystem /nix/store/87y9237m9c9m9mxk9ajwdfmn78vz6w2y-zlib-1.3.1-dev/include -isystem /nix/store/87y9237m9c9m9mxk9ajwdfmn78vz6w2y-zlib-1.3.1-dev/include -isystem /nix/store/xff3v3hj0slzkxhksrsrscva5scf35an-libffi-3.5.2-dev/include -isystem /nix/store/xff3v3hj0slzkxhksrsrscva5scf35an-libffi-3.5.2-dev/include -isystem /nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/include -isystem /nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/include -isystem /nix/store/p73x5sdhi1wgas4d6mm8yxbzawih2yp2-glibc-iconv-2.42/include -isystem /nix/store/p73x5sdhi1wgas4d6mm8yxbzawih2yp2-glibc-iconv-2.42/include -isystem /nix/store/3drkfkyzxfb9rcpnv1xy0nvdj78qngy8-libglvnd-1.7.0-dev/include -isystem /nix/store/3drkfkyzxfb9rcpnv1xy0nvdj78qngy8-libglvnd-1.7.0-dev/include' export NIX_CFLAGS_COMPILE NIX_CFLAGS_COMPILE_FOR_TARGET=' -isystem /nix/store/d0irz6jq0d16h6iggq1mcwwvvxzi4lvy-gnumake-4.4.1/include -isystem /nix/store/blr5zdnxfckm1690cdx6anmh3s17sx5p-wayland-1.24.0-dev/include -isystem /nix/store/ixxx8nb52qxl25lix063rb35lk94p7r8-libxkbcommon-1.11.0-dev/include -isystem /nix/store/jhb15l57qmqxck5ddd1dh2ys729vc8gb-glib-2.86.3-dev/include -isystem /nix/store/87y9237m9c9m9mxk9ajwdfmn78vz6w2y-zlib-1.3.1-dev/include -isystem /nix/store/xff3v3hj0slzkxhksrsrscva5scf35an-libffi-3.5.2-dev/include -isystem /nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/include -isystem /nix/store/p73x5sdhi1wgas4d6mm8yxbzawih2yp2-glibc-iconv-2.42/include -isystem /nix/store/3drkfkyzxfb9rcpnv1xy0nvdj78qngy8-libglvnd-1.7.0-dev/include' export NIX_CFLAGS_COMPILE_FOR_TARGET @@ -65,7 +65,7 @@ NIX_ENFORCE_NO_NATIVE='1' export NIX_ENFORCE_NO_NATIVE NIX_HARDENING_ENABLE='bindnow format fortify fortify3 libcxxhardeningextensive libcxxhardeningfast pic relro stackclashprotection stackprotector strictoverflow zerocallusedregs' export NIX_HARDENING_ENABLE -NIX_LDFLAGS='-rpath /mnt/removable/Projects/Rust/wayland_panel/outputs/out/lib -L/nix/store/fv438zxk1mvcfi2sj20mgn4s91qpjdcd-rust-default-1.94.0/lib -L/nix/store/fv438zxk1mvcfi2sj20mgn4s91qpjdcd-rust-default-1.94.0/lib -L/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib -L/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib -L/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib -L/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib -L/nix/store/vl8jkqpr0l3fac3cxiy4nwc5paiww1lv-zlib-1.3.1/lib -L/nix/store/vl8jkqpr0l3fac3cxiy4nwc5paiww1lv-zlib-1.3.1/lib -L/nix/store/5mnq195cx3cagnpbbvf5ncbp4fjgy0sz-libffi-3.5.2/lib -L/nix/store/5mnq195cx3cagnpbbvf5ncbp4fjgy0sz-libffi-3.5.2/lib -L/nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/lib -L/nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/lib -L/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib -L/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib -L/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib -L/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib -L/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib -L/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib -L/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib -L/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib -L/nix/store/fv438zxk1mvcfi2sj20mgn4s91qpjdcd-rust-default-1.94.0/lib -L/nix/store/fv438zxk1mvcfi2sj20mgn4s91qpjdcd-rust-default-1.94.0/lib -L/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib -L/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib -L/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib -L/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib -L/nix/store/vl8jkqpr0l3fac3cxiy4nwc5paiww1lv-zlib-1.3.1/lib -L/nix/store/vl8jkqpr0l3fac3cxiy4nwc5paiww1lv-zlib-1.3.1/lib -L/nix/store/5mnq195cx3cagnpbbvf5ncbp4fjgy0sz-libffi-3.5.2/lib -L/nix/store/5mnq195cx3cagnpbbvf5ncbp4fjgy0sz-libffi-3.5.2/lib -L/nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/lib -L/nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/lib -L/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib -L/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib -L/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib -L/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib -L/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib -L/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib -L/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib -L/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib' +NIX_LDFLAGS='-rpath /home/benag/.nix-config/configuration/modules/dots/wayland_panel/outputs/out/lib -L/nix/store/fv438zxk1mvcfi2sj20mgn4s91qpjdcd-rust-default-1.94.0/lib -L/nix/store/fv438zxk1mvcfi2sj20mgn4s91qpjdcd-rust-default-1.94.0/lib -L/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib -L/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib -L/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib -L/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib -L/nix/store/vl8jkqpr0l3fac3cxiy4nwc5paiww1lv-zlib-1.3.1/lib -L/nix/store/vl8jkqpr0l3fac3cxiy4nwc5paiww1lv-zlib-1.3.1/lib -L/nix/store/5mnq195cx3cagnpbbvf5ncbp4fjgy0sz-libffi-3.5.2/lib -L/nix/store/5mnq195cx3cagnpbbvf5ncbp4fjgy0sz-libffi-3.5.2/lib -L/nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/lib -L/nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/lib -L/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib -L/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib -L/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib -L/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib -L/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib -L/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib -L/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib -L/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib -L/nix/store/fv438zxk1mvcfi2sj20mgn4s91qpjdcd-rust-default-1.94.0/lib -L/nix/store/fv438zxk1mvcfi2sj20mgn4s91qpjdcd-rust-default-1.94.0/lib -L/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib -L/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib -L/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib -L/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib -L/nix/store/vl8jkqpr0l3fac3cxiy4nwc5paiww1lv-zlib-1.3.1/lib -L/nix/store/vl8jkqpr0l3fac3cxiy4nwc5paiww1lv-zlib-1.3.1/lib -L/nix/store/5mnq195cx3cagnpbbvf5ncbp4fjgy0sz-libffi-3.5.2/lib -L/nix/store/5mnq195cx3cagnpbbvf5ncbp4fjgy0sz-libffi-3.5.2/lib -L/nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/lib -L/nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/lib -L/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib -L/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib -L/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib -L/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib -L/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib -L/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib -L/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib -L/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib' export NIX_LDFLAGS NIX_LDFLAGS_FOR_TARGET=' -L/nix/store/fv438zxk1mvcfi2sj20mgn4s91qpjdcd-rust-default-1.94.0/lib -L/nix/store/jcc9imfj4samq59gwsskxalcd9rjicip-wayland-1.24.0/lib -L/nix/store/k1gvr4prs9736r1lhqyy1plxrrvv9b4m-libxkbcommon-1.11.0/lib -L/nix/store/vl8jkqpr0l3fac3cxiy4nwc5paiww1lv-zlib-1.3.1/lib -L/nix/store/5mnq195cx3cagnpbbvf5ncbp4fjgy0sz-libffi-3.5.2/lib -L/nix/store/md592gfars4m9madyrpj9yrq5jhckgjf-gettext-0.26/lib -L/nix/store/1qm74vf93ik1xjrr9kl6qvjrklljlcqh-glib-2.86.3/lib -L/nix/store/1il4q8s87v0p8xp1g2q8mmbswbwkj23l-vulkan-loader-1.4.341.0/lib -L/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/lib -L/nix/store/wwckb31fcbwj479g7qwcb3b7cv6416pf-libglvnd-1.7.0/lib' export NIX_LDFLAGS_FOR_TARGET @@ -115,8 +115,6 @@ STRIP='strip' export STRIP STRIP_FOR_TARGET='strip' export STRIP_FOR_TARGET -VK_ICD_FILENAMES='/nix/store/g7wjwz546f510jv95318n23330c3ni7k-mesa-26.0.2/share/vulkan/icd.d/intel_icd.x86_64.json' -export VK_ICD_FILENAMES XDG_DATA_DIRS='/nix/store/590yx3aynyhs48jyk8ip37fk1mjqfhkb-patchelf-0.15.2/share' export XDG_DATA_DIRS __structuredAttrs='' @@ -178,7 +176,7 @@ name='nix-shell-env' export name nativeBuildInputs='' export nativeBuildInputs -out='/mnt/removable/Projects/Rust/wayland_panel/outputs/out' +out='/home/benag/.nix-config/configuration/modules/dots/wayland_panel/outputs/out' export out outputBin='out' outputDev='out' @@ -211,7 +209,7 @@ declare -a preFixupHooks=('_moveToShare' '_multioutDocs' '_multioutDevs' ) preInstallPhases=' glibPreInstallPhase' preferLocalBuild='1' export preferLocalBuild -prefix='/mnt/removable/Projects/Rust/wayland_panel/outputs/out' +prefix='/home/benag/.nix-config/configuration/modules/dots/wayland_panel/outputs/out' declare -a propagatedBuildDepFiles=('propagated-build-build-deps' 'propagated-native-build-inputs' 'propagated-build-target-deps' ) propagatedBuildInputs='' export propagatedBuildInputs diff --git a/flake.nix b/flake.nix index 19350f2..7f6c799 100644 --- a/flake.nix +++ b/flake.nix @@ -58,8 +58,7 @@ ] ++ runtimeLibs; - LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath runtimeLibs; - VK_ICD_FILENAMES = "${pkgs.mesa}/share/vulkan/icd.d/intel_icd.x86_64.json"; + LD_LIBRARY_PATH = "/run/opengl-driver/lib:${pkgs.lib.makeLibraryPath runtimeLibs}"; }; }; } diff --git a/src/main.rs b/src/main.rs index 6a2f76f..28a7691 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,7 +47,7 @@ impl Default for App { fn default() -> Self { let mut output = Self { popups: HashMap::new(), - power_off_widget: PowerOffWidget(None), + power_off_widget: PowerOffWidget(None, false), time_widget: Default::default(), battery_widget: Default::default(), }; @@ -64,7 +64,7 @@ impl App { fn close_popup(&mut self, id: iced::window::Id) -> Task { self.popups.remove(&id); - return Task::done(Message::RemoveWindow(id)); + Task::done(Message::RemoveWindow(id)) } fn view(&self, id: iced::window::Id) -> Element<'_, Message> { @@ -227,13 +227,21 @@ impl PanelWidget for TimeWidget { } #[derive(Default)] -struct PowerOffWidget(Option); +struct PowerOffWidget(Option, bool); impl PanelWidget for PowerOffWidget { - fn update(&mut self) {} + fn update(&mut self) { + self.1 = !self.1; + } fn view(&self) -> Element<'_, Message> { - button("⏻").on_press(Message::PowerOff).into() + button("⏻") + .on_press(if self.1 { + Message::PowerOffCancel + } else { + Message::PowerOff + }) + .into() } } From 9bf4c44aa2505f98ef252d8b36846eda2d251ca8 Mon Sep 17 00:00:00 2001 From: benstrb Date: Sat, 21 Mar 2026 00:24:18 +0100 Subject: [PATCH 2/9] =?UTF-8?q?=CE=A3:3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.rs | 3 +- src/main.rs | 243 ++-------------------------------- src/widgets/focused_window.rs | 30 +++++ src/widgets/mod.rs | 1 + 4 files changed, 41 insertions(+), 236 deletions(-) create mode 100644 src/widgets/focused_window.rs diff --git a/src/app.rs b/src/app.rs index 12a8041..ade6afd 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,9 +1,9 @@ use crate::widget::{Message, PanelWidget}; use crate::widgets::battery::BatteryWidget; use crate::widgets::clock::ClockWidget; +use crate::widgets::focused_window::FocusedWindowWidget; use crate::widgets::powerbutton::ShutdownWidget; use crate::widgets::spacer::Spacer; - use iced::Color; use iced::Element; use iced::Subscription; @@ -24,6 +24,7 @@ impl App { Box::new(ShutdownWidget::new()), Box::new(Spacer::new(iced::Length::Fill)), Box::new(BatteryWidget::new()), + Box::new(FocusedWindowWidget::new()), ], } } diff --git a/src/main.rs b/src/main.rs index 28a7691..3ca9b28 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,28 +1,22 @@ -use iced::Color; -use iced::Element; -use iced::Task; -use iced::widget::button; -use iced::widget::container; -use iced::widget::row; -use iced::widget::text; use iced_layershell::daemon; use iced_layershell::reexport::Anchor; -use iced_layershell::reexport::NewLayerShellSettings; use iced_layershell::settings::LayerShellSettings; use iced_layershell::settings::Settings; -use iced_layershell::to_layer_message; -use std::collections::HashMap; -use std::time::Duration; + +mod app; +mod widget; +mod widgets; +use app::App; pub fn main() -> Result<(), iced_layershell::Error> { - daemon(App::default, App::name, App::update, App::view) + daemon(App::new, App::name, App::update, App::view) .style(App::style) .theme(App::theme) .subscription(App::subscription) .settings(Settings { layer_settings: LayerShellSettings { - size: Some((0, 32)), - exclusive_zone: 32, + size: Some((0, App::WINDOW_HEIGHT)), + exclusive_zone: App::WINDOW_HEIGHT as i32, anchor: Anchor::Top | Anchor::Left | Anchor::Right, start_mode: iced_layershell::settings::StartMode::AllScreens, ..Default::default() @@ -32,224 +26,3 @@ pub fn main() -> Result<(), iced_layershell::Error> { .run() } -struct App { - popups: HashMap, - power_off_widget: PowerOffWidget, - time_widget: TimeWidget, - battery_widget: BatteryWidget, -} - -enum PopupKind { - PowerOff, -} - -impl Default for App { - fn default() -> Self { - let mut output = Self { - popups: HashMap::new(), - power_off_widget: PowerOffWidget(None, false), - time_widget: Default::default(), - battery_widget: Default::default(), - }; - let _ = output.update(Message::Clock); - - output - } -} - -impl App { - fn name() -> String { - "wayland_panel".into() - } - - fn close_popup(&mut self, id: iced::window::Id) -> Task { - self.popups.remove(&id); - Task::done(Message::RemoveWindow(id)) - } - - fn view(&self, id: iced::window::Id) -> Element<'_, Message> { - if let Some(kind) = self.popups.get(&id) { - return match kind { - PopupKind::PowerOff => container( - row![ - text("Shut down?"), - button("✓").on_press(Message::PowerOffConfirm), - button("✗").on_press(Message::PowerOffCancel), - ] - .spacing(8) - .align_y(iced::Alignment::Center), - ) - .center(iced::Length::Fill) - .into(), - }; - } - - // default: the bar - let content = row![ - self.time_widget.view(), - iced::widget::space().width(iced::Length::Fill), - self.power_off_widget.view(), - iced::widget::space().width(iced::Length::Fill), - self.battery_widget.view(), - ] - .padding(iced::Padding::from([0, 5])) - .height(iced::Length::Fill) - .width(iced::Length::Fill) - .align_y(iced::Alignment::Center); - - container(content).into() - } - - fn update(&mut self, message: Message) -> Task { - match message { - Message::Clock => { - self.time_widget.update(); - self.battery_widget.update(); - - Task::none() - } - Message::PowerOff => { - let id = iced::window::Id::unique(); - self.popups.insert(id, PopupKind::PowerOff); - - self.power_off_widget.0 = Some(id); - - Task::done(Message::NewLayerShell { - settings: NewLayerShellSettings { - size: Some((220, 40)), - anchor: Anchor::Top, - layer: iced_layershell::reexport::Layer::Overlay, - keyboard_interactivity: - iced_layershell::reexport::KeyboardInteractivity::OnDemand, - exclusive_zone: None, - ..Default::default() - }, - id, - }) - } - Message::PowerOffConfirm => { - std::process::Command::new("poweroff").spawn().ok(); - Task::none() - } - Message::PowerOffCancel => self.close_popup(self.power_off_widget.0.unwrap()), - _ => Task::none(), - } - } - - fn style(&self, theme: &iced::Theme) -> iced::theme::Style { - iced::theme::Style { - background_color: Color::TRANSPARENT, - text_color: theme.palette().text, - } - } - - fn theme(&self, _id: iced::window::Id) -> iced::Theme { - iced::Theme::GruvboxDark - } - - fn subscription(&self) -> iced::Subscription { - iced::time::every(Duration::from_secs(1)).map(|_| Message::Clock) - } -} - -trait PanelWidget { - fn update(&mut self); - fn view(&self) -> Element<'_, Message>; -} - -#[derive(Default)] -struct BatteryWidget { - battery: Option, -} - -impl PanelWidget for BatteryWidget { - fn update(&mut self) { - let file_content = std::fs::read_to_string(std::path::Path::new( - "/sys/class/power_supply/BAT0/capacity", - )); - - let Ok(file_string) = file_content else { - self.battery = None; - return; - }; - - let file_string = file_string.trim(); - - let Ok(value) = file_string.parse::() else { - self.battery = None; - return; - }; - - self.battery = Some(value); - } - - fn view(&self) -> Element<'_, Message> { - match self.battery { - Some(battery) => text!("{} {}", battery.to_string(), Self::get_icon(battery)), - None => text("󰂃"), - } - .into() - } -} - -impl BatteryWidget { - fn get_icon(battery: usize) -> &'static str { - match battery { - 0..6 => "󰂎", - 6..11 => "󰁺", - 11..21 => "󰁻", - 21..31 => "󰁼", - 31..41 => "󰁽", - 41..51 => "󰁾", - 51..61 => "󰁿", - 61..71 => "󰂀", - 71..81 => "󰂁", - 81..91 => "󰂂", - 91..101 => "󰁹", - _ => "󰂃", - } - } -} - -#[derive(Default)] -struct TimeWidget { - current_time: chrono::DateTime, -} - -impl PanelWidget for TimeWidget { - fn update(&mut self) { - self.current_time = chrono::Local::now(); - } - - fn view(&self) -> Element<'_, Message> { - text!("{}", self.current_time.format("%H:%m")).into() - } -} - -#[derive(Default)] -struct PowerOffWidget(Option, bool); - -impl PanelWidget for PowerOffWidget { - fn update(&mut self) { - self.1 = !self.1; - } - - fn view(&self) -> Element<'_, Message> { - button("⏻") - .on_press(if self.1 { - Message::PowerOffCancel - } else { - Message::PowerOff - }) - .into() - } -} - -#[to_layer_message(multi)] -#[derive(Debug, Clone)] -pub enum Message { - Clock, - PowerOff, - PowerOffConfirm, - PowerOffCancel, -} diff --git a/src/widgets/focused_window.rs b/src/widgets/focused_window.rs new file mode 100644 index 0000000..53d4c37 --- /dev/null +++ b/src/widgets/focused_window.rs @@ -0,0 +1,30 @@ +use iced::{Subscription, Task}; +use wayland_protocols_wlr::foreign_toplevel; + +use crate::widget::PanelWidget; + +pub struct FocusedWindowWidget { + focused_window: String, +} + +impl FocusedWindowWidget { + pub fn new() -> Self { + Self { + focused_window: foreign_toplevel::v1::client::zwlr_foreign_toplevel_manager_v1::Event, + } + } +} + +impl PanelWidget for FocusedWindowWidget { + fn update(&mut self, _message: &crate::widget::Message) -> iced::Task { + Task::none() + } + + fn subscribe(&self) -> iced::Subscription { + Subscription::none() + } + + fn view(&self, _id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> { + iced::widget::text!("{}", self.focused_window).into() + } +} diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index 22184f7..ae671a2 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -1,4 +1,5 @@ pub mod battery; pub mod clock; +pub mod focused_window; pub mod powerbutton; pub mod spacer; From 4895333ff1e6b2b9442a58a3c69dad96d7f3b8f3 Mon Sep 17 00:00:00 2001 From: benstrb Date: Sat, 21 Mar 2026 22:00:34 +0100 Subject: [PATCH 3/9] =?UTF-8?q?=CE=A3:3=20v2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 11 ++++++ Cargo.toml | 1 + flake.lock | 12 +++---- src/widget.rs | 1 + src/widgets/focused_window.rs | 64 ++++++++++++++++++++++++++++++----- 5 files changed, 75 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f563be..8f9ee3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1787,6 +1787,16 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "niri-ipc" +version = "25.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12bd9eb4e437f5282ce853cf66837658379cb537b4b6bae687da59246005329a" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -3310,6 +3320,7 @@ dependencies = [ "chrono", "iced", "iced_layershell", + "niri-ipc", "tokio", "winit", "zbus", diff --git a/Cargo.toml b/Cargo.toml index 539476c..ac9b81c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" chrono = "0.4.44" iced = { version = "0.14.0", default-features = false, features = ["wgpu", "wayland", "tokio"] } iced_layershell = { version = "0.15.0", default-features = false } +niri-ipc = "25.11.0" tokio = { version = "1.50.0", features = ["time"] } winit = { version = "0.30.12", default-features = false, features = ["wayland"] } zbus = "5.14.0" diff --git a/flake.lock b/flake.lock index fd1d531..beb223f 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1773579282, - "narHash": "sha256-LWvZj9Bvm1EuoO6zbX4yjZebwnZNfeTbmCJGS7RGQ3Y=", + "lastModified": 1773821835, + "narHash": "sha256-TJ3lSQtW0E2JrznGVm8hOQGVpXjJyXY2guAxku2O9A4=", "owner": "nixos", "repo": "nixpkgs", - "rev": "5a88de74db0e948139be4b46f9a94d64aa11391c", + "rev": "b40629efe5d6ec48dd1efba650c797ddbd39ace0", "type": "github" }, "original": { @@ -29,11 +29,11 @@ ] }, "locked": { - "lastModified": 1773630837, - "narHash": "sha256-zJhgAGnbVKeBMJOb9ctZm4BGS/Rnrz+5lfSXTVah4HQ=", + "lastModified": 1773975983, + "narHash": "sha256-zrRVwdfhDdohANqEhzY/ydeza6EXEi8AG6cyMRNYT9Q=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "f600ea449c7b5bb596fa1cf21c871cc5b9e31316", + "rev": "cc80954a95f6f356c303ed9f08d0b63ca86216ac", "type": "github" }, "original": { diff --git a/src/widget.rs b/src/widget.rs index 17beceb..9d89737 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -20,4 +20,5 @@ pub enum Message { Battery(Option), Time, ShutdownEvent(ShutdownEvents), + FocusChanged(Option), } diff --git a/src/widgets/focused_window.rs b/src/widgets/focused_window.rs index 53d4c37..e974cb9 100644 --- a/src/widgets/focused_window.rs +++ b/src/widgets/focused_window.rs @@ -1,7 +1,7 @@ -use iced::{Subscription, Task}; -use wayland_protocols_wlr::foreign_toplevel; +use iced::{Subscription, Task, futures::SinkExt}; +use niri_ipc::{Event, Request, socket::Socket}; -use crate::widget::PanelWidget; +use crate::widget::{Message, PanelWidget}; pub struct FocusedWindowWidget { focused_window: String, @@ -10,21 +10,69 @@ pub struct FocusedWindowWidget { impl FocusedWindowWidget { pub fn new() -> Self { Self { - focused_window: foreign_toplevel::v1::client::zwlr_foreign_toplevel_manager_v1::Event, + focused_window: "dsadsadsadas".into(), } } } impl PanelWidget for FocusedWindowWidget { - fn update(&mut self, _message: &crate::widget::Message) -> iced::Task { + fn update(&mut self, message: &Message) -> iced::Task { + let Message::FocusChanged(i) = message else { + return Task::none(); + }; + + self.focused_window = match i { + Some(id) => id.to_string(), + None => "None".into(), + }; + Task::none() } - fn subscribe(&self) -> iced::Subscription { - Subscription::none() + //ain't gonna lie, I got no idea wth is going on here, the issue was that, smth smth channel + //not filled, it was not working properly + //this is entirely vibecoded + fn subscribe(&self) -> Subscription { + Subscription::run_with("niri-focus-watcher", |_| { + iced::stream::channel(16, async |mut tx| { + let (btx, brx) = std::sync::mpsc::channel::(); + + std::thread::spawn(move || { + let mut socket = Socket::connect().expect("failed to connect"); + let _ = socket.send(Request::EventStream).expect("failed to send"); + let mut read_event = socket.read_events(); + loop { + match read_event() { + Ok(Event::WindowFocusChanged { id }) => { + if btx.send(Message::FocusChanged(id)).is_err() { + break; + } + } + Ok(_) => {} + Err(e) => { + eprintln!("{e}"); + break; + } + } + } + }); + + loop { + match brx.try_recv() { + Ok(msg) => { + let _ = tx.send(msg).await; + } + Err(std::sync::mpsc::TryRecvError::Empty) => { + tokio::time::sleep(std::time::Duration::from_millis(10)).await; + } + Err(std::sync::mpsc::TryRecvError::Disconnected) => break, + } + } + }) + }) } - fn view(&self, _id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> { + fn view(&self, _id: iced::window::Id) -> iced::Element<'_, Message> { iced::widget::text!("{}", self.focused_window).into() } } From 99b2e565b9c094d1b2f83b47aa5c03b2c71fad6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Maxmili=C3=A1n=20St=C5=99=C3=ADbrn=C3=BD?= Date: Sun, 22 Mar 2026 22:56:41 +0100 Subject: [PATCH 4/9] power management start --- Cargo.lock | 154 ++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/app.rs | 4 +- src/widget.rs | 2 + src/widgets/focused_window.rs | 69 ++++++++++++++ src/widgets/mod.rs | 1 + src/widgets/power_management.rs | 52 +++++++++++ 7 files changed, 281 insertions(+), 2 deletions(-) create mode 100644 src/widgets/focused_window.rs create mode 100644 src/widgets/power_management.rs diff --git a/Cargo.lock b/Cargo.lock index 6f563be..816b5e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,6 +67,56 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + [[package]] name = "anyhow" version = "1.0.102" @@ -418,6 +468,65 @@ dependencies = [ "windows-link", ] +[[package]] +name = "clap" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_complete" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19c9f1dde76b736e3681f28cec9d5a61299cbaae0fce80a68e43724ad56031eb" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_derive" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "clap_mangen" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e30ffc187e2e3aeafcd1c6e2aa416e29739454c0ccaa419226d5ecd181f2d78" +dependencies = [ + "clap", + "roff", +] + [[package]] name = "clipboard-win" version = "5.4.1" @@ -468,6 +577,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + [[package]] name = "combine" version = "4.6.7" @@ -1468,6 +1583,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + [[package]] name = "itoa" version = "1.0.17" @@ -2104,6 +2225,12 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + [[package]] name = "orbclient" version = "0.3.51" @@ -2261,6 +2388,20 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "ppd" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c9336eeb6b2ea4e61900f44b539ca0d095593a19ba8e831825c30e906aa475c" +dependencies = [ + "clap", + "clap_complete", + "clap_mangen", + "serde", + "thiserror 2.0.18", + "zbus", +] + [[package]] name = "presser" version = "0.3.1" @@ -2404,6 +2545,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "roff" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf2048e0e979efb2ca7b91c4f1a8d77c91853e9b987c94c555668a8994915ad" + [[package]] name = "roxmltree" version = "0.20.0" @@ -3000,6 +3147,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.22.0" @@ -3310,6 +3463,7 @@ dependencies = [ "chrono", "iced", "iced_layershell", + "ppd", "tokio", "winit", "zbus", diff --git a/Cargo.toml b/Cargo.toml index 539476c..c46a44f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" chrono = "0.4.44" iced = { version = "0.14.0", default-features = false, features = ["wgpu", "wayland", "tokio"] } iced_layershell = { version = "0.15.0", default-features = false } +ppd = "0.1.7" tokio = { version = "1.50.0", features = ["time"] } winit = { version = "0.30.12", default-features = false, features = ["wayland"] } zbus = "5.14.0" diff --git a/src/app.rs b/src/app.rs index 12a8041..b8ba2a1 100644 --- a/src/app.rs +++ b/src/app.rs @@ -19,9 +19,9 @@ impl App { pub fn new() -> Self { Self { widgets: vec![ - Box::new(ClockWidget::new()), - Box::new(Spacer::new(iced::Length::Fill)), Box::new(ShutdownWidget::new()), + Box::new(Spacer::new(iced::Length::Fixed(5.))), + Box::new(ClockWidget::new()), Box::new(Spacer::new(iced::Length::Fill)), Box::new(BatteryWidget::new()), ], diff --git a/src/widget.rs b/src/widget.rs index 17beceb..f200259 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -3,6 +3,7 @@ use iced::Subscription; use iced::Task; use iced_layershell::to_layer_message; +use crate::widgets::power_management::PowerManagement; use crate::widgets::powerbutton::ShutdownEvents; pub trait PanelWidget { @@ -20,4 +21,5 @@ pub enum Message { Battery(Option), Time, ShutdownEvent(ShutdownEvents), + PowerManagement(PowerManagement), } diff --git a/src/widgets/focused_window.rs b/src/widgets/focused_window.rs new file mode 100644 index 0000000..e4ffa18 --- /dev/null +++ b/src/widgets/focused_window.rs @@ -0,0 +1,69 @@ +use iced::{Subscription, Task, futures::SinkExt}; +use niri_ipc::{Event, Request, Response, Window, socket::Socket}; + +use crate::widget::{Message, PanelWidget}; + +pub struct FocusedWindowWidget { + focused_window: Option, +} + +impl FocusedWindowWidget { + pub fn new() -> Self { + Self { + focused_window: None, + } + } +} + +impl PanelWidget for FocusedWindowWidget { + fn update(&mut self, message: &Message) -> iced::Task { + let Message::FocusChanged(i) = message else { + return Task::none(); + }; + + self.focused_window = *i; + Task::none() + } + + fn subscribe(&self) -> Subscription { + Subscription::run(|| { + iced::stream::channel(16, async move |mut tx| { + use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; + use tokio::net::UnixStream; + + let socket_path = std::env::var("NIRI_SOCKET").unwrap(); + let mut stream = UnixStream::connect(socket_path).await.unwrap(); + + // Send the EventStream request as newline-delimited JSON + let request = serde_json::to_string(&niri_ipc::Request::EventStream).unwrap(); + stream + .write_all(format!("{request}\n").as_bytes()) + .await + .unwrap(); + + let mut reader = BufReader::new(stream); + let mut line = String::new(); + + loop { + line.clear(); + reader.read_line(&mut line).await.unwrap(); + + // First line back is the Reply, subsequent lines are Events + if let Ok(event) = serde_json::from_str::(line.trim()) + && let niri_ipc::Event::WindowFocusChanged { id } = event + { + let _ = tx.send(Message::FocusChanged(id)).await; + } + } + }) + }) + } + fn view(&self, _id: iced::window::Id) -> iced::Element<'_, Message> { + iced::widget::text!( + "{}", + self.focused_window + .map_or("None".into(), |f| format!("{}", f)) + ) + .into() + } +} diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index 22184f7..15c857e 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -1,4 +1,5 @@ pub mod battery; pub mod clock; +pub mod power_management; pub mod powerbutton; pub mod spacer; diff --git a/src/widgets/power_management.rs b/src/widgets/power_management.rs new file mode 100644 index 0000000..6c0615e --- /dev/null +++ b/src/widgets/power_management.rs @@ -0,0 +1,52 @@ +use iced::{Subscription, Task}; +use ppd::PpdProxy; +use zbus::connection::Connection; + +use crate::widget::{Message, PanelWidget}; + +pub struct PowerManagementWidget { + window: Option, + current_mode: usize, + names: Vec>, +} + +#[derive(Debug, Clone)] +pub enum PowerManagement { + ToggleWindow, + SetMode(SetMode), +} + +#[derive(Debug, Clone)] +pub enum SetMode { + Saver, + Medium, + Performant, +} + +impl PowerManagementWidget { + pub fn new() -> Self { + let conn = Connection::system().await.unwrap(); + } +} + +impl PanelWidget for PowerManagementWidget { + fn update(&mut self, message: &crate::widget::Message) -> iced::Task { + let Message::PowerManagement(msg) = message else { + return Task::none(); + }; + + Task::none() + } + + fn subscribe(&self) -> iced::Subscription { + Subscription::none() + } + + fn view(&self, id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> { + todo!() + } + + fn has_window(&self, id: iced::window::Id) -> bool { + self.window == Some(id) + } +} From 632a0abd105ca84fcbbc50cefed2f569e50d5fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Maxmili=C3=A1n=20St=C5=99=C3=ADbrn=C3=BD?= Date: Mon, 23 Mar 2026 22:59:17 +0100 Subject: [PATCH 5/9] power management new --- src/app.rs | 2 ++ src/widgets/power_management.rs | 47 ++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/app.rs b/src/app.rs index b8ba2a1..a452061 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,6 +1,7 @@ use crate::widget::{Message, PanelWidget}; use crate::widgets::battery::BatteryWidget; use crate::widgets::clock::ClockWidget; +use crate::widgets::power_management::PowerManagementWidget; use crate::widgets::powerbutton::ShutdownWidget; use crate::widgets::spacer::Spacer; @@ -24,6 +25,7 @@ impl App { Box::new(ClockWidget::new()), Box::new(Spacer::new(iced::Length::Fill)), Box::new(BatteryWidget::new()), + Box::new(PowerManagementWidget::new()), ], } } diff --git a/src/widgets/power_management.rs b/src/widgets/power_management.rs index 6c0615e..e59b8ac 100644 --- a/src/widgets/power_management.rs +++ b/src/widgets/power_management.rs @@ -1,35 +1,52 @@ +use std::ops::Index; + use iced::{Subscription, Task}; -use ppd::PpdProxy; -use zbus::connection::Connection; +use ppd::PpdProxyBlocking; +use zbus::blocking::Connection; use crate::widget::{Message, PanelWidget}; -pub struct PowerManagementWidget { +pub struct PowerManagementWidget<'a> { window: Option, current_mode: usize, - names: Vec>, + modes: Box<[Box]>, + proxy: PpdProxyBlocking<'a>, } #[derive(Debug, Clone)] pub enum PowerManagement { ToggleWindow, - SetMode(SetMode), + SetMode(String), } -#[derive(Debug, Clone)] -pub enum SetMode { - Saver, - Medium, - Performant, -} - -impl PowerManagementWidget { +impl PowerManagementWidget<'_> { pub fn new() -> Self { - let conn = Connection::system().await.unwrap(); + let conn = Connection::system().unwrap(); + let proxy = PpdProxyBlocking::new(&conn).unwrap(); + + let modes: Box<[Box]> = proxy + .profiles() + .unwrap() + .iter() + .map(|f| f.profile.clone().into_boxed_str()) + .collect(); + + let current_mode_str = proxy.active_profile().unwrap(); + let current_mode = modes + .iter() + .position(|m| m.as_ref() == current_mode_str.as_str()) + .unwrap(); + + Self { + window: None, + modes, + current_mode, + proxy, + } } } -impl PanelWidget for PowerManagementWidget { +impl PanelWidget for PowerManagementWidget<'_> { fn update(&mut self, message: &crate::widget::Message) -> iced::Task { let Message::PowerManagement(msg) = message else { return Task::none(); From 22670f6abdf25f7c904d1f82567b3eaaa9f43e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Maxmili=C3=A1n=20St=C5=99=C3=ADbrn=C3=BD?= Date: Mon, 23 Mar 2026 23:04:44 +0100 Subject: [PATCH 6/9] implemented really simple rendering --- src/widgets/power_management.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/widgets/power_management.rs b/src/widgets/power_management.rs index e59b8ac..eb2ff3a 100644 --- a/src/widgets/power_management.rs +++ b/src/widgets/power_management.rs @@ -1,6 +1,4 @@ -use std::ops::Index; - -use iced::{Subscription, Task}; +use iced::{Subscription, Task, widget::text}; use ppd::PpdProxyBlocking; use zbus::blocking::Connection; @@ -59,8 +57,8 @@ impl PanelWidget for PowerManagementWidget<'_> { Subscription::none() } - fn view(&self, id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> { - todo!() + fn view(&self, _id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> { + text!("{}", self.modes[self.current_mode]).into() } fn has_window(&self, id: iced::window::Id) -> bool { From c2c4881942baf48a68af38f6573057dbb03b888c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Maxmili=C3=A1n=20St=C5=99=C3=ADbrn=C3=BD?= Date: Tue, 24 Mar 2026 14:50:55 +0100 Subject: [PATCH 7/9] structural updates + power_management --- src/app.rs | 5 +- src/widget.rs | 6 +- src/widgets/battery.rs | 7 +- src/widgets/clock.rs | 4 +- src/widgets/power_management.rs | 112 ++++++++++++++++++++++++++------ src/widgets/powerbutton.rs | 38 ++++++----- src/widgets/spacer.rs | 4 +- 7 files changed, 125 insertions(+), 51 deletions(-) diff --git a/src/app.rs b/src/app.rs index a452061..f4f1958 100644 --- a/src/app.rs +++ b/src/app.rs @@ -38,13 +38,12 @@ impl App { if let Some(elem) = self .widgets .iter() - .find(|widget| widget.has_window(id)) - .map(|widget| widget.view(id)) + .find_map(|widget| widget.render_window(id)) { return elem; } - iced::widget::Row::with_children(self.widgets.iter().map(|widget| widget.view(id))) + iced::widget::Row::with_children(self.widgets.iter().filter_map(|widget| widget.view())) .padding(iced::Padding::from([0, 5])) .height(iced::Length::Fill) .width(iced::Length::Fill) diff --git a/src/widget.rs b/src/widget.rs index f200259..491de69 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -9,9 +9,9 @@ use crate::widgets::powerbutton::ShutdownEvents; pub trait PanelWidget { fn update(&mut self, message: &Message) -> Task; fn subscribe(&self) -> Subscription; - fn view(&self, id: iced::window::Id) -> Element<'_, Message>; - fn has_window(&self, _id: iced::window::Id) -> bool { - false + fn view(&self) -> Option>; + fn render_window(&self, _id: iced::window::Id) -> Option> { + None } } diff --git a/src/widgets/battery.rs b/src/widgets/battery.rs index bfe8ded..0d9bfa5 100644 --- a/src/widgets/battery.rs +++ b/src/widgets/battery.rs @@ -65,12 +65,11 @@ impl PanelWidget for BatteryWidget { }) } - fn view(&self, _id: iced::window::Id) -> Element<'_, Message> { + fn view(&self) -> Option> { match self.capacity { - Some(cap) => text!("{} {}", cap, Self::icon(cap)), - None => text!("󰂃"), + Some(cap) => Some(text!("{} {}", cap, Self::icon(cap)).into()), + None => None, } - .into() } } diff --git a/src/widgets/clock.rs b/src/widgets/clock.rs index d29f7d7..638410c 100644 --- a/src/widgets/clock.rs +++ b/src/widgets/clock.rs @@ -28,8 +28,8 @@ impl PanelWidget for ClockWidget { iced::time::every(Duration::from_secs(1)).map(|_| Message::Time) } - fn view(&self, _id: iced::window::Id) -> iced::Element<'_, Message> { + fn view(&self) -> Option> { let formatted_time = self.current_time.format("%H:%M"); - iced::widget::text!("{}", formatted_time).into() + Some(iced::widget::text!("{}", formatted_time).into()) } } diff --git a/src/widgets/power_management.rs b/src/widgets/power_management.rs index eb2ff3a..3724a2e 100644 --- a/src/widgets/power_management.rs +++ b/src/widgets/power_management.rs @@ -1,12 +1,20 @@ -use iced::{Subscription, Task, widget::text}; -use ppd::PpdProxyBlocking; +use iced::{ + Subscription, Task, + widget::{Column, button, text}, +}; +use iced_layershell::reexport::{Anchor, NewLayerShellSettings}; +use ppd::{PpdProxyBlocking, Result}; use zbus::blocking::Connection; use crate::widget::{Message, PanelWidget}; pub struct PowerManagementWidget<'a> { + connection: Option>, +} + +struct Connected<'a> { window: Option, - current_mode: usize, + current_mode: Box, modes: Box<[Box]>, proxy: PpdProxyBlocking<'a>, } @@ -19,28 +27,29 @@ pub enum PowerManagement { impl PowerManagementWidget<'_> { pub fn new() -> Self { + Self { + connection: Self::establish_connection().ok(), + } + } + + fn establish_connection<'a>() -> Result> { let conn = Connection::system().unwrap(); - let proxy = PpdProxyBlocking::new(&conn).unwrap(); + let proxy = PpdProxyBlocking::new(&conn)?; let modes: Box<[Box]> = proxy - .profiles() - .unwrap() + .profiles()? .iter() .map(|f| f.profile.clone().into_boxed_str()) .collect(); - let current_mode_str = proxy.active_profile().unwrap(); - let current_mode = modes - .iter() - .position(|m| m.as_ref() == current_mode_str.as_str()) - .unwrap(); + let current_mode = proxy.active_profile()?.into_boxed_str(); - Self { - window: None, - modes, + Ok(Connected { current_mode, + modes, proxy, - } + window: None, + }) } } @@ -50,18 +59,81 @@ impl PanelWidget for PowerManagementWidget<'_> { return Task::none(); }; - Task::none() + let Some(conn) = &mut self.connection else { + return Task::none(); + }; + + match msg { + PowerManagement::ToggleWindow => match conn.window { + Some(child) => { + conn.window = None; + Task::done(Message::RemoveWindow(child)) + } + None => { + let id = iced::window::Id::unique(); + conn.window = Some(id); + + Task::done(Message::NewLayerShell { + settings: NewLayerShellSettings { + size: Some((220, 400)), + anchor: Anchor::Top, + layer: iced_layershell::reexport::Layer::Overlay, + keyboard_interactivity: + iced_layershell::reexport::KeyboardInteractivity::OnDemand, + exclusive_zone: None, + ..Default::default() + }, + id, + }) + } + }, + + PowerManagement::SetMode(mode) => { + let _ = conn.proxy.set_active_profile(mode.into()); + + conn.current_mode = conn.proxy.active_profile().unwrap().into_boxed_str(); + Task::none() + } + } } fn subscribe(&self) -> iced::Subscription { Subscription::none() } - fn view(&self, _id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> { - text!("{}", self.modes[self.current_mode]).into() + fn view(&self) -> Option> { + let Some(conn) = &self.connection else { + return None; + }; + + let output = button(text!("{}", conn.current_mode)) + .on_press(Message::PowerManagement(PowerManagement::ToggleWindow)) + .into(); + + Some(output) } - fn has_window(&self, id: iced::window::Id) -> bool { - self.window == Some(id) + fn render_window( + &self, + id: iced::window::Id, + ) -> Option> { + let Some(conn) = &self.connection else { + return None; + }; + + if conn.window != Some(id) { + return None; + } + + let output = Column::with_children(conn.modes.iter().map(|f| { + button(text!("{}", f)) + .on_press(Message::PowerManagement(PowerManagement::SetMode( + f.clone().into_string(), + ))) + .into() + })) + .into(); + + Some(output) } } diff --git a/src/widgets/powerbutton.rs b/src/widgets/powerbutton.rs index 841d5c3..ce29027 100644 --- a/src/widgets/powerbutton.rs +++ b/src/widgets/powerbutton.rs @@ -1,6 +1,6 @@ use crate::widget::{Message, PanelWidget}; use iced::{ - Subscription, Task, + Element, Subscription, Task, widget::{button, row, text}, }; use iced_layershell::reexport::{Anchor, NewLayerShellSettings}; @@ -67,24 +67,28 @@ impl PanelWidget for ShutdownWidget { Subscription::none() } - fn has_window(&self, id: iced::window::Id) -> bool { - self.window == Some(id) + fn render_window(&self, id: iced::window::Id) -> Option> { + if self.window != Some(id) { + return None; + } + + let output = row![ + text("Shut down?"), + button("✓").on_press(Message::ShutdownEvent(ShutdownEvents::ShutdownConfirmed)), + button("✗").on_press(Message::ShutdownEvent(ShutdownEvents::ShutdownCanceled)), + ] + .spacing(8) + .align_y(iced::Alignment::Center) + .into(); + + Some(output) } - fn view(&self, id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> { - match self.window { - Some(child_id) if id == child_id => row![ - text("Shut down?"), - button("✓").on_press(Message::ShutdownEvent(ShutdownEvents::ShutdownConfirmed)), - button("✗").on_press(Message::ShutdownEvent(ShutdownEvents::ShutdownCanceled)), - ] - .spacing(8) - .align_y(iced::Alignment::Center) - .into(), + fn view(&self) -> Option> { + let output = button("⏻") + .on_press(Message::ShutdownEvent(ShutdownEvents::PowerButtonPressed)) + .into(); - _ => button("⏻") - .on_press(Message::ShutdownEvent(ShutdownEvents::PowerButtonPressed)) - .into(), - } + Some(output) } } diff --git a/src/widgets/spacer.rs b/src/widgets/spacer.rs index 68e720f..b0b9399 100644 --- a/src/widgets/spacer.rs +++ b/src/widgets/spacer.rs @@ -19,7 +19,7 @@ impl PanelWidget for Spacer { iced::Subscription::none() } - fn view(&self, _id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> { - iced::widget::space().width(self.space).into() + fn view(&self) -> Option> { + Some(iced::widget::space().width(self.space).into()) } } From 83b396ae3ec9b47d575b2bd8274684fed0acb19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Maxmili=C3=A1n=20St=C5=99=C3=ADbrn=C3=BD?= Date: Tue, 24 Mar 2026 15:14:18 +0100 Subject: [PATCH 8/9] bumped iced_layershell version --- Cargo.lock | 20 ++++++++++---------- Cargo.toml | 2 +- src/app.rs | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 816b5e4..4904171 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1371,9 +1371,9 @@ dependencies = [ [[package]] name = "iced_exdevtools" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd37abad853d711ca1197a01a1fac657dd225826faf68d23595ab0380aba25ed" +checksum = "79aa630d54ce3fd340bd2cf64faee63aa614f5fb19cf8158f98ecb289d5a7608" dependencies = [ "iced_debug", "iced_devtools", @@ -1418,9 +1418,9 @@ dependencies = [ [[package]] name = "iced_layershell" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b93788b3b04289379ab3ada875dd93139d9c871a1fbb99286355d2b517b02c7" +checksum = "22a8e513ce86c82210538861618b3e948bad9b82abc0d7e127f061371c989269" dependencies = [ "enumflags2", "futures", @@ -1443,9 +1443,9 @@ dependencies = [ [[package]] name = "iced_layershell_macros" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de12a0d2d2faabd9d6b49cd1621ae1b6d7e0f1365332c18673d810116e89675e" +checksum = "8625bb576fdb0438e85d8e57ac7229868dde8e410cf32c004fffd588a2777bee" dependencies = [ "darling", "manyhow", @@ -1666,9 +1666,9 @@ dependencies = [ [[package]] name = "layershellev" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a90cbea1375f775abb76c9f2fc7b475dd17d740936dfbeeb0026bd2f09ad5624" +checksum = "66e9699736661513c75de0cbc887aa4656823b8c22c4ac4a955cd2ddea63e1b1" dependencies = [ "bitflags 2.11.0", "calloop 0.14.4", @@ -3307,9 +3307,9 @@ dependencies = [ [[package]] name = "waycrate_xkbkeycode" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4865c30460c0d213dac0ea8a5eadb0d3b620e6154bd95ca058377e4c1873515" +checksum = "caa5bc93c1dfce7c8d9b4a864028c2d5f64625f249b08900805acdbe8619561d" dependencies = [ "bitflags 2.11.0", "calloop 0.14.4", diff --git a/Cargo.toml b/Cargo.toml index c46a44f..971025c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [dependencies] chrono = "0.4.44" iced = { version = "0.14.0", default-features = false, features = ["wgpu", "wayland", "tokio"] } -iced_layershell = { version = "0.15.0", default-features = false } +iced_layershell = { version = "0.16.0", default-features = false } ppd = "0.1.7" tokio = { version = "1.50.0", features = ["time"] } winit = { version = "0.30.12", default-features = false, features = ["wayland"] } diff --git a/src/app.rs b/src/app.rs index f4f1958..0e03d92 100644 --- a/src/app.rs +++ b/src/app.rs @@ -21,7 +21,6 @@ impl App { Self { widgets: vec![ Box::new(ShutdownWidget::new()), - Box::new(Spacer::new(iced::Length::Fixed(5.))), Box::new(ClockWidget::new()), Box::new(Spacer::new(iced::Length::Fill)), Box::new(BatteryWidget::new()), @@ -47,6 +46,7 @@ impl App { .padding(iced::Padding::from([0, 5])) .height(iced::Length::Fill) .width(iced::Length::Fill) + .spacing(5) .align_y(iced::Alignment::Center) .into() } From 524e6365ca4247ac557c343d9ea5332c4d3a0c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Maxmili=C3=A1n=20St=C5=99=C3=ADbrn=C3=BD?= Date: Thu, 2 Apr 2026 13:33:44 +0200 Subject: [PATCH 9/9] New pallete --- src/app.rs | 15 +++++-- src/widgets/focused_window.rs | 69 --------------------------------- src/widgets/power_management.rs | 7 ++-- 3 files changed, 15 insertions(+), 76 deletions(-) delete mode 100644 src/widgets/focused_window.rs diff --git a/src/app.rs b/src/app.rs index 0e03d92..f9d8e65 100644 --- a/src/app.rs +++ b/src/app.rs @@ -5,10 +5,10 @@ use crate::widgets::power_management::PowerManagementWidget; use crate::widgets::powerbutton::ShutdownWidget; use crate::widgets::spacer::Spacer; -use iced::Color; -use iced::Element; use iced::Subscription; use iced::Task; +use iced::{Color, Theme}; +use iced::{Element, color}; pub struct App { widgets: Vec>, @@ -68,7 +68,16 @@ impl App { } pub fn theme(&self, _id: iced::window::Id) -> iced::Theme { - iced::Theme::GruvboxDark + let palette = iced::theme::Palette { + background: color!(0x282828), // dark BG_0 + text: color!(0xfbf1c7), // dark FG0_29 + primary: color!(0x8A493B), // dark BLUE_4 + success: color!(0x98971a), // dark GREEN_2 + warning: color!(0xd79921), // dark YELLOW_3 + danger: color!(0xcc241d), // dark RED_1 + }; + + Theme::custom("Better gruvbox", palette) } pub fn subscription(&self) -> iced::Subscription { diff --git a/src/widgets/focused_window.rs b/src/widgets/focused_window.rs deleted file mode 100644 index e4ffa18..0000000 --- a/src/widgets/focused_window.rs +++ /dev/null @@ -1,69 +0,0 @@ -use iced::{Subscription, Task, futures::SinkExt}; -use niri_ipc::{Event, Request, Response, Window, socket::Socket}; - -use crate::widget::{Message, PanelWidget}; - -pub struct FocusedWindowWidget { - focused_window: Option, -} - -impl FocusedWindowWidget { - pub fn new() -> Self { - Self { - focused_window: None, - } - } -} - -impl PanelWidget for FocusedWindowWidget { - fn update(&mut self, message: &Message) -> iced::Task { - let Message::FocusChanged(i) = message else { - return Task::none(); - }; - - self.focused_window = *i; - Task::none() - } - - fn subscribe(&self) -> Subscription { - Subscription::run(|| { - iced::stream::channel(16, async move |mut tx| { - use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; - use tokio::net::UnixStream; - - let socket_path = std::env::var("NIRI_SOCKET").unwrap(); - let mut stream = UnixStream::connect(socket_path).await.unwrap(); - - // Send the EventStream request as newline-delimited JSON - let request = serde_json::to_string(&niri_ipc::Request::EventStream).unwrap(); - stream - .write_all(format!("{request}\n").as_bytes()) - .await - .unwrap(); - - let mut reader = BufReader::new(stream); - let mut line = String::new(); - - loop { - line.clear(); - reader.read_line(&mut line).await.unwrap(); - - // First line back is the Reply, subsequent lines are Events - if let Ok(event) = serde_json::from_str::(line.trim()) - && let niri_ipc::Event::WindowFocusChanged { id } = event - { - let _ = tx.send(Message::FocusChanged(id)).await; - } - } - }) - }) - } - fn view(&self, _id: iced::window::Id) -> iced::Element<'_, Message> { - iced::widget::text!( - "{}", - self.focused_window - .map_or("None".into(), |f| format!("{}", f)) - ) - .into() - } -} diff --git a/src/widgets/power_management.rs b/src/widgets/power_management.rs index 3724a2e..889c3a2 100644 --- a/src/widgets/power_management.rs +++ b/src/widgets/power_management.rs @@ -55,14 +55,13 @@ impl PowerManagementWidget<'_> { impl PanelWidget for PowerManagementWidget<'_> { fn update(&mut self, message: &crate::widget::Message) -> iced::Task { - let Message::PowerManagement(msg) = message else { - return Task::none(); - }; - let Some(conn) = &mut self.connection else { return Task::none(); }; + let Message::PowerManagement(msg) = message else { + return Task::none(); + }; match msg { PowerManagement::ToggleWindow => match conn.window { Some(child) => {