ooknet/modules/home/workstation/tools/ookpower.nix
2025-01-19 14:04:54 +11:00

177 lines
4.6 KiB
Nix

{
lib,
config,
pkgs,
...
}: let
inherit (lib) mkIf;
inherit (config.programs) rofi;
powermenu = pkgs.writeShellApplication {
name = "powermenu";
runtimeInputs = [pkgs.rofi-wayland];
text =
# bash
''
pid_file="/tmp/my_countdown.pid"
DRY=
COUNTDOWN=
while [ $# -gt 0 ]; do
key="$1"
case $key in
-c | --countdown)
COUNTDOWN=true
shift
;;
-d | --dry)
DRY=true
shift
;;
*)
break
;;
esac
done
notify() {
notify-send -u critical -a system-notify -t 1000 -h string:x-canonical-private-synchronous:anything "$@"
}
# Used for development, instead of running command, notifies if command was successful and exits.
dry_success() {
if [ "$DRY" == "true" ]; then
TITLE="Action Successful:"
notify "$TITLE" "$1"
exit 0
fi
}
cancel() {
if [ -f "$pid_file" ]; then
# Read the process ID from the file and kill the process
kill "$(cat "$pid_file")" &>/dev/null
notify-send "Action canceled"
rm -f "$pid_file"
else
echo "No countdown to cancel."
fi
}
countdown() {
if [ "$COUNTDOWN" == "true" ]; then
msg="''${1:-doing something}"
echo $$ >"$pid_file"
for i in {5..1}; do
notify-send "$msg in $i" -h string:x-canonical-private-synchronous:anything
sleep 1
done
echo "Countdown done"
rm -f "$pid_file"
fi
}
action_logout() {
countdown "Logging out"
dry_success "Logged out"
PROCESS="Hyprland|\.Hyprland-wrapp"
if pgrep -x $PROCESS >/dev/null; then
hyprctl dispatch exit 0
sleep 2
if pgrep -x $PROCESS; then
pkill -9 $PROCESS
fi
fi
}
action_poweroff() {
countdown "Shutting down"
dry_success "Shutdown"
poweroff
}
action_lock() {
dry_success "Screen Locked"
hyprlock
}
action_reboot() {
countdown "Rebooting"
dry_success "Reboot"
reboot
}
action_suspend() {
countdown "Suspending"
dry_success "Suspend"
suspend
}
action_dmenu() {
selection=$(echo -e " Reboot\n Lock\n󰍃 Logout\n󰐥 Shutdown\n󰒲 Suspend" | rofi -dmenu -i)
case "$selection" in
"󰐥 Shutdown") action_poweroff ;;
" Reboot") action_reboot ;;
" Lock") action_lock ;;
"󰍃 Logout") action_logout ;;
"󰒲 Suspend") action_suspend ;;
*)
echo "ERROR" "Invalid option"
exit 1
;;
esac
}
# Check if the script is already running and decide to cancel or start countdown
if [ -f "$pid_file" ]; then
cancel
else
ACTION=''${1:-usage}
case "$ACTION" in
logout)
action_logout
;;
poweroff)
action_poweroff
;;
reboot)
action_reboot
;;
lock)
action_lock
;;
usage)
echo " Usage: powermenu [OPTION]... [ACTION usage|dmenu|logout|poweroff|reboot|lock]"
echo ""
echo "Options:"
echo " -c, --countdown Enable 5 seconds countdown before action is performed"
echo " -d, --dry Print instead of perform action debug/development"
echo ""
echo "Actions:"
echo " usage Print help information"
echo " dmenu Open menu with rofi for selecting action"
echo " logout Kills current active Hyprland session"
echo " poweroff Shut down current host"
echo " reboot Restart current host"
echo " lock Locks current session with hyprlock"
echo ""
;;
dmenu)
action_dmenu
;;
*)
echo "Invalid action: $ACTION (expecting: usage|logout|poweroff|reboot|lock)"
;;
esac
fi
'';
};
in {
config = mkIf rofi.enable {
home.packages = [powermenu];
ooknet.binds.powerMenu = "powermenu -c dmenu";
};
}