fix: migration first-boot, fingerprint PAM, menus, mic LED
Some checks failed
Check / eval (push) Failing after 9m12s
Some checks failed
Check / eval (push) Failing after 9m12s
Post-migration annoyances from TuringMachine: - Force fprintAuth from fingerprint.pam (NixOS defaults it on with fprintd) - First-boot toast waits for swaync, retries, only marks after success - Night light status/toggle handles masked units + hyprsunset/wlsunset - VPN menu: define rofi_menu in nomarchy-vpn (was a silent no-op) - Left arrow = ↩ Back in list menus; GTK menu contrast via Stylix - Mic-mute LED udev + sync after wpctl; EasyEffects starts after tray - Migration guide: HM before GUI login, fingerprint/browser/VPN notes Verified: flake check --no-build; checks.first-boot; checks.hardware-toggles (pam=false node). V3 session items pending after user rebuild.
This commit is contained in:
@@ -234,7 +234,34 @@ let
|
||||
# when config.rasi has case-sensitive: false for drun/modi — so
|
||||
# SUPER+Space (apps) matched "ste"→Steam while the main Menu filter
|
||||
# did not match "sys"→System. Always pass -i on menu pickers.
|
||||
rofi_menu() { command rofi -dmenu -i "$@"; }
|
||||
#
|
||||
# Left arrow → one level up (same as choosing "↩ Back"). rofi's
|
||||
# -kb-custom-1 returns exit 10; Esc still returns non-zero and quits
|
||||
# the whole menu. Free-text prompts should treat "$BACK" as cancel.
|
||||
# Pass --grid as the first arg to skip Left=Back (multi-column theme
|
||||
# picker needs Left for column motion).
|
||||
rofi_menu() {
|
||||
local out rc left_back=1
|
||||
if [ "''${1:-}" = --grid ]; then
|
||||
left_back=0
|
||||
shift
|
||||
fi
|
||||
if [ "$left_back" -eq 1 ]; then
|
||||
out=$(command rofi -dmenu -i -kb-custom-1 Left "$@" </dev/stdin)
|
||||
else
|
||||
out=$(command rofi -dmenu -i "$@" </dev/stdin)
|
||||
fi
|
||||
rc=$?
|
||||
if [ "$left_back" -eq 1 ] && [ "$rc" -eq 10 ]; then
|
||||
printf '%s\n' "$BACK"
|
||||
return 0
|
||||
elif [ "$rc" -eq 0 ]; then
|
||||
printf '%s\n' "$out"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
case "''${1:-}" in
|
||||
power)
|
||||
@@ -395,7 +422,7 @@ ${themeSlugMap}
|
||||
choice=$( {
|
||||
${themeRows}
|
||||
back
|
||||
} | rofi_menu -show-icons -p Theme -theme-str ${themeGridThemeStr}) || exit 0
|
||||
} | rofi_menu --grid -show-icons -p Theme -theme-str ${themeGridThemeStr}) || exit 0
|
||||
[ "$choice" = "$BACK" ] && exec "$0"
|
||||
choice="''${choice% ✓}" # drop the active marker if present
|
||||
slug="''${THEME_SLUG[$choice]:-}"
|
||||
@@ -429,7 +456,7 @@ ${themeRows}
|
||||
|
||||
web)
|
||||
q=$(rofi_menu -p search < /dev/null) || exit 0
|
||||
[ -n "$q" ] || exit 0
|
||||
{ [ -n "$q" ] && [ "$q" != "$BACK" ]; } || exit 0
|
||||
exec xdg-open "https://www.google.com/search?q=$(urlencode "$q")" ;;
|
||||
|
||||
network)
|
||||
@@ -599,7 +626,10 @@ ${themeRows}
|
||||
row "Theme${menuHint "theme"}" preferences-desktop-theme
|
||||
row "Next wallpaper${hintForAction "exec, nomarchy-theme-sync bg next"}" preferences-desktop-wallpaper
|
||||
row "Reset wallpaper (auto)" preferences-desktop-wallpaper
|
||||
if systemctl --user is-active --quiet hyprsunset.service 2>/dev/null
|
||||
# Use the toggle script (knows hyprsunset vs wlsunset); a hard-coded
|
||||
# hyprsunset-only check always showed (off) in geo mode and when
|
||||
# the unit was still the empty HM mask from a disabled package unit.
|
||||
if [ "$(nomarchy-nightlight is-active 2>/dev/null)" = on ]
|
||||
then row "Night light (on)" weather-clear-night
|
||||
else row "Night light (off)" weather-clear-night
|
||||
fi
|
||||
@@ -680,7 +710,7 @@ ${themeRows}
|
||||
# which lags behind model releases; npx caches after first run. The
|
||||
# REPL stays open for follow-ups.
|
||||
q=$(rofi_menu -p claude < /dev/null) || exit 0
|
||||
[ -n "$q" ] || exit 0
|
||||
{ [ -n "$q" ] && [ "$q" != "$BACK" ]; } || exit 0
|
||||
exec ${cfg.terminal} -e npx --yes @anthropic-ai/claude-code@latest "$q" ;;
|
||||
|
||||
dnd)
|
||||
@@ -752,9 +782,9 @@ ${themeRows}
|
||||
case "$choice" in "Sunset"*) key=sunset; label=Sunset; cur="''${sunset:-20:00}" ;; esac
|
||||
t=$(rofi_menu -p "$label HH:MM (now $cur)" < /dev/null) || exec "$0" autotheme
|
||||
case "$t" in
|
||||
""|"$BACK") : ;;
|
||||
[01][0-9]:[0-5][0-9]|2[0-3]:[0-5][0-9])
|
||||
nomarchy-theme-sync --quiet set "settings.autoTheme.$key" "$t" --no-switch ;;
|
||||
"") : ;;
|
||||
*) notify-send "Auto theme" "Ignored '$t' — use HH:MM (24-hour)." ;;
|
||||
esac
|
||||
exec "$0" autotheme ;;
|
||||
@@ -1119,7 +1149,7 @@ ${themeRows}
|
||||
*60%*) set_limit 60 "Set to 60%" ;;
|
||||
*Custom*)
|
||||
limit=$(rofi_menu -p "Charge limit % (50–100)" < /dev/null) || exit 0
|
||||
[ -n "$limit" ] || exit 0
|
||||
{ [ -n "$limit" ] && [ "$limit" != "$BACK" ]; } || exit 0
|
||||
case "$limit" in
|
||||
*[!0-9]*) notify-send "Battery limit" "Not a whole number: $limit"; exit 0 ;;
|
||||
esac
|
||||
@@ -1172,6 +1202,23 @@ ${themeRows}
|
||||
nomarchy-vpn = pkgs.writeShellScriptBin "nomarchy-vpn" ''
|
||||
set -u
|
||||
BACK="↩ Back"
|
||||
# Own helper — this is a separate package from nomarchy-menu, so the
|
||||
# menu's rofi_menu function is not in scope (was a silent no-op: every
|
||||
# VPN submenu died with "rofi_menu: command not found").
|
||||
rofi_menu() {
|
||||
local out rc
|
||||
out=$(command rofi -dmenu -i -kb-custom-1 Left "$@" </dev/stdin)
|
||||
rc=$?
|
||||
if [ "$rc" -eq 10 ]; then
|
||||
printf '%s\n' "$BACK"
|
||||
return 0
|
||||
elif [ "$rc" -eq 0 ]; then
|
||||
printf '%s\n' "$out"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
conn_rows() {
|
||||
nmcli -t -f NAME,TYPE,STATE connection show 2>/dev/null \
|
||||
@@ -1180,12 +1227,15 @@ ${themeRows}
|
||||
|
||||
toggle_conn() {
|
||||
mark=''${1%% *}; name=''${1#* }
|
||||
err=
|
||||
if [ "$mark" = "●" ]; then
|
||||
nmcli connection down "$name" >/dev/null 2>&1 \
|
||||
&& notify-send "VPN" "Disconnected $name" || notify-send "VPN" "Could not disconnect $name"
|
||||
err=$(nmcli connection down "$name" 2>&1) \
|
||||
&& notify-send "VPN" "Disconnected $name" \
|
||||
|| notify-send "VPN" "Could not disconnect $name''${err:+ — $err}"
|
||||
else
|
||||
nmcli connection up "$name" >/dev/null 2>&1 \
|
||||
&& notify-send "VPN" "Connected $name" || notify-send "VPN" "Could not connect $name (auth or bad config?)"
|
||||
err=$(nmcli connection up "$name" 2>&1) \
|
||||
&& notify-send "VPN" "Connected $name" \
|
||||
|| notify-send "VPN" "Could not connect $name''${err:+ — $err}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1196,11 +1246,9 @@ ${themeRows}
|
||||
| rofi_menu -p "Import VPN config" ) || return
|
||||
{ [ -z "$file" ] || [ "$file" = "$BACK" ]; } && return
|
||||
case "$file" in *.ovpn) type=openvpn ;; *) type=wireguard ;; esac
|
||||
if nmcli connection import type "$type" file "$HOME/$file" >/dev/null 2>&1; then
|
||||
notify-send "VPN" "Imported $type config: $(basename "$file")"
|
||||
else
|
||||
notify-send "VPN" "Import failed ($type plugin missing, or bad file?)"
|
||||
fi
|
||||
err=$(nmcli connection import type "$type" file "$HOME/$file" 2>&1) \
|
||||
&& notify-send "VPN" "Imported $type config: $(basename "$file")" \
|
||||
|| notify-send "VPN" "Import failed''${err:+ — $err}"
|
||||
}
|
||||
|
||||
ts_state() { tailscale status --json 2>/dev/null | jq -r '.BackendState // "Unknown"'; }
|
||||
@@ -1257,14 +1305,18 @@ ${themeRows}
|
||||
while :; do
|
||||
have_ts=""
|
||||
command -v tailscale >/dev/null 2>&1 && have_ts=1
|
||||
rows=$(conn_rows)
|
||||
choice=$( {
|
||||
conn_rows
|
||||
if [ -n "$rows" ]; then printf '%s\n' "$rows"
|
||||
else printf 'No VPNs yet — import a config or enable Tailscale\n'
|
||||
fi
|
||||
printf 'Import config…\n'
|
||||
[ -n "$have_ts" ] && printf 'Tailscale ›\n'
|
||||
printf '%s\n' "$BACK"
|
||||
} | rofi_menu -p VPN ) || exit 0
|
||||
case "$choice" in
|
||||
"$BACK"|"") exec nomarchy-menu system ;;
|
||||
"No VPNs yet"*) ;; # hint row — stay in menu
|
||||
"Import config…") import_config ;;
|
||||
"Tailscale ›") tailscale_menu ;;
|
||||
"● "*|"○ "*) toggle_conn "$choice" ;;
|
||||
|
||||
Reference in New Issue
Block a user