{ lib , writeShellScriptBin , networkmanager , util-linux , bluez , coreutils , gnugrep , gawk , libnotify , procps }: # Runtime Wi-Fi + Bluetooth airplane mode (#104). Session-scoped state under XDG # $XDG_RUNTIME_DIR; Waybar status self-hides when off (signal 11). writeShellScriptBin "nomarchy-airplane" '' set -euo pipefail rt="''${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" state_file="$rt/nomarchy-airplane.state" # Prefer an existing PATH prefix (test mocks, user wrappers) then the # closed store tools so a headless check can inject fake nmcli/rfkill. PATH=$PATH:${lib.makeBinPath [ networkmanager util-linux bluez coreutils gnugrep gawk libnotify procps ]} # -x, both comm names: nixpkgs wraps the binary as `.waybar-wrapped`, # and an unanchored `waybar` also matches (and kills) the # nomarchy-waybar supervisor, whose bash dies on an unhandled RTMIN. poke_bar() { pkill -RTMIN+11 -x 'waybar|\.waybar-wrapped' 2>/dev/null || true } wifi_enabled() { [ "$(nmcli -t -f WIFI g 2>/dev/null || echo disabled)" = "enabled" ] } # Soft-blocked means "we (or something) turned it off in software". # Hard-blocked is a laptop kill-switch — we never try to fight that. bt_soft_unblocked() { rfkill list bluetooth 2>/dev/null | grep -q 'Soft blocked: no' } bt_powered() { bluetoothctl show 2>/dev/null | grep -q 'Powered: yes' } # "Bluetooth was usable" = adapter present and not soft-blocked (or # already powered). Desktops without BT leave this false. bt_was_on() { ls /sys/class/bluetooth/hci* >/dev/null 2>&1 || return 1 bt_powered || bt_soft_unblocked } engaged() { [ -f "$state_file" ]; } engage() { if engaged; then notify-send -a Nomarchy "Airplane mode" "Already on." 2>/dev/null || true exit 0 fi wifi_prior=0 bt_prior=0 wifi_enabled && wifi_prior=1 bt_was_on && bt_prior=1 # Wi-Fi via NetworkManager so nm-applet/waybar stay consistent; # fall back to rfkill if nmcli is missing (shouldn't happen on # a Nomarchy desktop). if command -v nmcli >/dev/null 2>&1; then nmcli radio wifi off 2>/dev/null || true else rfkill block wlan 2>/dev/null || true fi # Bluetooth: soft-block the radio (covers adapters that ignore # bluetoothctl) and ask the daemon to power off when present. rfkill block bluetooth 2>/dev/null || true bluetoothctl power off >/dev/null 2>&1 || true printf 'wifi_prior=%s\nbt_prior=%s\n' "$wifi_prior" "$bt_prior" > "$state_file" poke_bar notify-send -a Nomarchy "Airplane mode" "On — Wi-Fi and Bluetooth off." 2>/dev/null || true } disengage() { if ! engaged; then notify-send -a Nomarchy "Airplane mode" "Already off." 2>/dev/null || true exit 0 fi # shellcheck disable=SC1090 . "$state_file" wifi_prior=''${wifi_prior:-0} bt_prior=''${bt_prior:-0} if [ "$wifi_prior" = 1 ]; then if command -v nmcli >/dev/null 2>&1; then nmcli radio wifi on 2>/dev/null || true else rfkill unblock wlan 2>/dev/null || true fi fi if [ "$bt_prior" = 1 ]; then rfkill unblock bluetooth 2>/dev/null || true bluetoothctl power on >/dev/null 2>&1 || true fi rm -f "$state_file" poke_bar notify-send -a Nomarchy "Airplane mode" "Off — prior radio state restored." 2>/dev/null || true } case "''${1:-toggle}" in status) # Waybar: plane glyph only while engaged; empty → self-hide. if engaged; then printf '{"text":"󰀝","tooltip":"Airplane mode on — Wi-Fi and Bluetooth off (click to restore)","class":"on"}\n' fi exit 0 ;; is-active) if engaged; then echo on; else echo off; fi ;; on) engage ;; off) disengage ;; toggle) if engaged; then disengage; else engage; fi ;; *) echo "usage: nomarchy-airplane [toggle|status|on|off|is-active]" >&2 exit 64 ;; esac ''