From fed7db4fbc527bd5613f02961fa495cdac25a7c9 Mon Sep 17 00:00:00 2001 From: kenji Date: Fri, 26 Dec 2025 16:09:12 -0600 Subject: [PATCH] add: screensaver --- modules/home/waybar.nix | 1 + modules/system/hyprland.nix | 1 + modules/system/scripts.nix | 1 - scripts/hakase-screensaver.nix | 143 +++++++++++++++++++++++++++++ scripts/hakase-top-right-popup.nix | 2 +- 5 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 scripts/hakase-screensaver.nix diff --git a/modules/home/waybar.nix b/modules/home/waybar.nix index 48fb840..4c6688e 100644 --- a/modules/home/waybar.nix +++ b/modules/home/waybar.nix @@ -2,5 +2,6 @@ imports = [ ../../apps/waybar/home.nix ../../apps/waybar/deps.nix + ../../scripts/hakase-top-right-popup.nix ]; } diff --git a/modules/system/hyprland.nix b/modules/system/hyprland.nix index 2a59ce4..043f548 100644 --- a/modules/system/hyprland.nix +++ b/modules/system/hyprland.nix @@ -1,5 +1,6 @@ { imports = [ ../../apps/hyprland/default.nix + ../../scripts/hakase-screensaver.nix ]; } diff --git a/modules/system/scripts.nix b/modules/system/scripts.nix index 775c338..f7e9be4 100644 --- a/modules/system/scripts.nix +++ b/modules/system/scripts.nix @@ -1,5 +1,4 @@ { imports = [ - ../../scripts/hakase-top-right-popup.nix ]; } diff --git a/scripts/hakase-screensaver.nix b/scripts/hakase-screensaver.nix new file mode 100644 index 0000000..3cd2f8e --- /dev/null +++ b/scripts/hakase-screensaver.nix @@ -0,0 +1,143 @@ +# In home.nix or a separate module +{ + pkgs, + lib, + ... +}: let + # Define the script package + hakase-cmd-screensaver = pkgs.writeShellScriptBin "hakase-cmd-screensaver" '' + export PATH="${lib.makeBinPath [ + pkgs.coreutils + pkgs.procps # pkill, pgrep + pkgs.jq + pkgs.hyprland # hyprctl + pkgs.terminaltexteffects # tte + ]}:$PATH" + + screensaver_in_focus() { + hyprctl activewindow -j | jq -e '.class == "org.hakase.screensaver"' >/dev/null 2>&1 + } + + exit_screensaver() { + hyprctl keyword cursor:invisible false + pkill -x tte 2>/dev/null + pkill -f org.hakase.screensaver 2>/dev/null + exit 0 + } + + trap exit_screensaver SIGINT SIGTERM SIGHUP SIGQUIT + + printf '\e[?1000h\e[?1003h' + while read -rsn1 -t 0.1; do :; done + + printf '\033]11;rgb:00/00/00\007' # Black background + hyprctl keyword cursor:invisible true &>/dev/null + + # Note: ''${variable} is how we escape bash variables in Nix + tty=$(tty 2>/dev/null) + + while true; do + tte -i "$HOME/.config/hakase/branding/screensaver.txt" \ + --frame-rate 120 \ + --canvas-width 0 \ + --canvas-height 0 \ + --reuse-canvas \ + --anchor-canvas c \ + --anchor-text c \ + --random-effect \ + --exclude-effects dev_worm \ + --no-eol \ + --no-restore-cursor & + + while pgrep -t "''${tty#/dev/}" -x tte >/dev/null; do + if read -rsn1 -t 1 || ! screensaver_in_focus; then + exit_screensaver + fi + done + done + ''; + hakase-launch-screensaver = pkgs.writeShellScriptBin "hakase-launch-screensaver" '' + # 1. Path Setup + # We include necessary utils. + # NOTE: We assume 'hakase-cmd-screensaver', 'walker', and your terminals + # are already installed in your system/home profile. + export PATH="${lib.makeBinPath [ + pkgs.coreutils + pkgs.procps # pgrep + pkgs.jq + pkgs.hyprland # hyprctl + pkgs.libnotify # notify-send + pkgs.xdg-terminal-exec + pkgs.terminaltexteffects # tte + ]}:$PATH" + + if ! command -v tte &>/dev/null; then + exit 1 + fi + + pgrep -f org.hakase.screensaver && exit 0 + + if [[ -f "$HOME/.local/state/hakase/toggles/screensaver-off" ]] && [[ "$1" != "force" ]]; then + exit 1 + fi + + if command -v walker &>/dev/null; then + walker -q + fi + + focused=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true).name') + terminal=$(xdg-terminal-exec --print-id) + + # 4. Launch loop + for m in $(hyprctl monitors -j | jq -r '.[] | .name'); do + hyprctl dispatch focusmonitor "$m" + + case "$terminal" in + *Alacritty*) + hyprctl dispatch exec -- \ + alacritty --class=org.hakase.screensaver \ + --config-file "$HOME/.config/alacritty/screensaver.toml" \ + -e hakase-cmd-screensaver + ;; + *ghostty*) + hyprctl dispatch exec -- \ + ghostty --class=org.hakase.screensaver \ + --config-file="$HOME/.config/ghostty/screensaver" \ + --font-size=18 \ + -e hakase-cmd-screensaver + ;; + *kitty*) + hyprctl dispatch exec -- \ + kitty --class=org.hakase.screensaver \ + --override font_size=18 \ + --override window_padding_width=0 \ + -e hakase-cmd-screensaver + ;; + *) + notify-send "✋ Screensaver only runs in Alacritty, Ghostty, or Kitty" + ;; + esac + done + + # 5. Restore focus + hyprctl dispatch focusmonitor "$focused" + ''; + hakase-toggle-screensaver = pkgs.writeShellScriptBin "hakase-toggle-screensaver" '' + STATE_FILE="$HOME/.local/state/omarchy/toggles/screensaver-off" + + if [[ -f "$STATE_FILE" ]]; then + rm -f "$STATE_FILE" + ${pkgs.libnotify}/bin/notify-send "󱄄 Screensaver enabled" + else + mkdir -p "$(dirname "$STATE_FILE")" + touch "$STATE_FILE" + ${pkgs.libnotify}/bin/notify-send "󱄄 Screensaver disabled" + fi + ''; +in { + environment.systemPackages = with pkgs; [ + hakase-launch-screensaver + hakase-cmd-screensaver + hakase-toggle-screensaver + ]; +} diff --git a/scripts/hakase-top-right-popup.nix b/scripts/hakase-top-right-popup.nix index f544db4..1bfefbd 100644 --- a/scripts/hakase-top-right-popup.nix +++ b/scripts/hakase-top-right-popup.nix @@ -146,7 +146,7 @@ exec hakase-launch-popup 800 300 wiremix ''; in { - environment.systemPackages = [ + home.packages = [ pkgs.jq pkgs.socat # Required for the socket listener pkgs.util-linux