Compare commits

...

4 Commits

Author SHA1 Message Date
13ecfa92f0 fix(gtk): bundle the submenu arrow — Papirus has no pan-end-symbolic
Some checks failed
Check / eval (push) Failing after 1m33s
05bab55's menu fix pointed -gtk-icon-source at the icon theme, but
Papirus doesn't ship pan-end-symbolic and its inheritance chain
(breeze-dark → hicolor) has no provider installed, so GTK menu submenu
arrows rendered as nothing (nm-applet: no cue that 'VPN Connections'
opens a submenu). Bundle the triangle as a store-path SVG recolored
via -gtk-recolor(url(…)) — the same mechanism adw-gtk3 uses for its
own check-mark assets, immune to icon-pack coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 19:06:11 +01:00
61d591f5d2 feat(waybar): explain 'Not charging' hold state in the battery tooltip
With a charge cap, AC-plugged inside the hysteresis band (power.nix:
start = cap − 10) reports 'Not charging' — indistinguishable from a
broken charger without a hint. tooltip-format-plugged now says the cap
is holding the level and how charging resumes. No cap value baked: the
menu changes it live without a rebuild.

Whole-swap parity: the same tooltip added to all four theme
waybar.jsonc files (boreal/executive-slate/summer-day/summer-night) —
the generated config is bypassed under these themes.

Verified on hardware (TuringMachine, boreal theme, cap 80, battery 71%
in the hold band): all four jsonc validate with jq; home-manager switch
deploys the boreal config with the tooltip; battery currently in the
exact Plugged state the tooltip targets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 19:06:11 +01:00
b39808d847 fix(waybar): VPN tooltip names the active VPN(s)
The shield's tooltip said only 'VPN active' — with both NM VPNs and
Tailscale feeding the same indicator, a forgotten tailscaled read as
'the icon is stuck after disconnecting'. List the active NM
VPN/WireGuard connection names and/or 'Tailscale' in the tooltip.

Verified on hardware (TuringMachine): script exercised with Tailscale
up → tooltip 'VPN: Tailscale'; tailscale down → empty output
(self-hide). NM name path is the same awk the nomarchy-vpn picker uses.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 19:06:11 +01:00
Bernardo Magri
50a558615c feat(hyprland): SUPER+0 → workspace 10; migration doc gains autoLogin
Workspace binds were generated for 1-9 only, leaving SUPER+0 dead.
Generate 10, with the 0 key mapping to workspace 10 (and SHIFT+0 to
move); cheatsheet updated to match.

MIGRATION.md's example system.nix now includes
nomarchy.system.greeter.autoLogin — the migration path missed what
nomarchy-install sets on every LUKS machine, so migrated boxes stopped
at tuigreet asking for a password behind the LUKS prompt.

Verified: nix flake check --no-build passes; generated
homeConfigurations.nomarchy hyprland binds eval'd and contain
'$mod, 0, workspace, 10' + SHIFT variant. V3 next: rebuild on the
migrated T14s (TuringMachine) and press SUPER+0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 19:06:11 +01:00
9 changed files with 53 additions and 14 deletions

View File

@@ -169,6 +169,11 @@ ryzenadj)**, **no Secure Boot**, and the **stateVersion override**.
nomarchy.hardware.amd.enable = true; # amd-pstate + radeonsi VA-API
# nomarchy.hardware.amd.rocm.enable = true; # opt-in GPU compute (multi-GB)
# LUKS machines: the disk passphrase already gates access, so boot
# straight into the session — this is what nomarchy-install sets on
# encrypted installs. Omit it on unencrypted machines.
nomarchy.system.greeter.autoLogin = username;
# CRITICAL: keep your ORIGINAL install's value — never Nomarchy's 26.05.
system.stateVersion = "24.11";
}

View File

@@ -74,15 +74,18 @@ let
(e: "${e.mods}, ${e.key}, exec, ${focusOrLaunch}/bin/nomarchy-focus-or-launch ${e.class} ${e.command}")
lofEntries;
# SUPER+1..9 / SUPER+SHIFT+1..9 workspace binds, generated.
# SUPER+1..9,0 / SUPER+SHIFT+1..9,0 workspace binds, generated
# (the 0 key is workspace 10).
workspaceBinds = builtins.concatLists (builtins.genList
(i:
let ws = toString (i + 1);
let
ws = toString (i + 1);
key = if i == 9 then "0" else ws;
in [
"$mod, ${ws}, workspace, ${ws}"
"$mod SHIFT, ${ws}, movetoworkspace, ${ws}"
"$mod, ${key}, workspace, ${ws}"
"$mod SHIFT, ${key}, movetoworkspace, ${ws}"
])
9);
10);
# The keyboard binds — single source shared with the SUPER+? cheatsheet
# (rofi.nix renders the same list). Edit them in ./keybinds.nix.

View File

@@ -87,8 +87,8 @@
];
extra = [
{ keys = "SUPER + 1-9"; desc = "Switch to workspace 1-9"; }
{ keys = "SUPER + SHIFT + 1-9"; desc = "Move window to workspace 1-9"; }
{ keys = "SUPER + 1-9, 0"; desc = "Switch to workspace 1-10 (0 = 10)"; }
{ keys = "SUPER + SHIFT + 1-9, 0"; desc = "Move window to workspace 1-10 (0 = 10)"; }
{ keys = "SUPER + drag"; desc = "Move (LMB) / resize (RMB) window"; }
{ keys = "Volume / Brightness"; desc = "Hardware keys, shown via the OSD"; }
{ keys = "Bar: 󰾪 click"; desc = "Caffeine hold the screen awake (idle inhibitor)"; }

View File

@@ -35,6 +35,19 @@ let
base0E = hex c.accentAlt;# magenta
base0F = hex c.bad; # brown/deprecated
};
# Submenu arrow, bundled: adw-gtk3 (and our earlier fix) look up
# pan-end-symbolic in the ICON theme, but Papirus doesn't ship it and
# its inheritance chain (breeze-dark → hicolor) is broken here — so
# menu arrows rendered as nothing (nm-applet: no hint that "VPN
# Connections" opens a submenu). Same trick adw-gtk3 uses for its
# check marks: a bundled asset via -gtk-recolor(url(…)), immune to
# icon-pack coverage. Shape traced from Adwaita's pan-end-symbolic.
panEndSvg = pkgs.writeText "nomarchy-pan-end-symbolic.svg" ''
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<path d="M 6 4 L 10 8 L 6 12 Z"/>
</svg>
'';
in
{
config = lib.mkIf cfg.stylix.enable {
@@ -67,14 +80,16 @@ in
menu menuitem:disabled, .menu menuitem:disabled {
color: #${base16.base03};
}
/* Submenu disclosure arrows without this they pick muted. */
/* Submenu disclosure arrows bundled asset, NOT an icon-theme
lookup: pan-end-symbolic is missing from Papirus and its
broken inheritance chain, so -gtk-icontheme() drew nothing. */
menu menuitem arrow, .menu menuitem arrow,
menu menuitem:hover arrow, menu menuitem:selected arrow {
min-width: 16px;
min-height: 16px;
margin-left: 8px;
color: inherit;
-gtk-icon-source: -gtk-icontheme("pan-end-symbolic");
-gtk-icon-source: -gtk-recolor(url("${panEndSvg}"));
}
menu menuitem:hover arrow, menu menuitem:selected arrow {
color: #${base16.base00};

View File

@@ -107,15 +107,20 @@ let
# VPN indicator — shows a shield when a NetworkManager VPN/WireGuard
# connection is active OR Tailscale is up; prints nothing otherwise so the
# module self-hides (like nightlight/updates). Click opens the VPN submenu.
# module self-hides (like nightlight/updates). The tooltip names each
# active VPN (NM connection names, "Tailscale") — without it a forgotten
# tailscaled reads as "the icon is stuck". Click opens the VPN submenu.
vpnStatus = pkgs.writeShellScriptBin "nomarchy-vpn-status" ''
active=$(nmcli -t -f TYPE connection show --active 2>/dev/null | grep -Exm1 'vpn|wireguard')
names=$(nmcli -t -f NAME,TYPE connection show --active 2>/dev/null \
| awk -F: '$2=="vpn"||$2=="wireguard"{print $1}')
ts=""
if command -v tailscale >/dev/null 2>&1; then
[ "$(tailscale status --json 2>/dev/null | jq -r '.BackendState // empty')" = Running ] && ts=1
[ "$(tailscale status --json 2>/dev/null | jq -r '.BackendState // empty')" = Running ] && ts=Tailscale
fi
[ -n "$active" ] || [ -n "$ts" ] || exit 0
printf '{"text":"󰦝","tooltip":"VPN active (click to manage)","class":"on"}\n'
[ -n "$names$ts" ] || exit 0
list=$(printf '%s\n' "$names" "$ts" | grep -v '^$' | paste -sd ', ' -)
tip=$(printf 'VPN: %s\n(click to manage)' "$list" | jq -Rs 'rtrimstr("\n")')
printf '{"text":"󰦝","tooltip":%s,"class":"on"}\n' "$tip"
'';
# Health warning — self-gates: prints nothing while nomarchy-doctor
@@ -260,6 +265,13 @@ let
format = "<span size='${toString (t.fonts.size + 2)}pt'>{icon}</span>{capacity}%";
format-charging = "<span size='${toString (t.fonts.size + 2)}pt'>󰂄 </span>{capacity}%";
format-icons = [ "󰁺 " "󰁼 " "󰁾 " "󰂀 " "󰁹 " ];
# The kernel's "Not charging" maps to waybar's Plugged state — on a
# machine with a charge cap that's the hold band doing its job
# (power.nix sets start = cap 10), which reads as "broken charger"
# without an explanation. The cap value isn't baked here: the menu
# can change it live (sysfs + state, no rebuild), so a number would
# go stale.
tooltip-format-plugged = "Plugged in, not charging held at {capacity}% by the battery charge cap\nCharging resumes ~10% below the cap · click to adjust";
# Click either the battery or the power-profile icon → the combined
# power menu (profile + charge cap). The granular System rows stay.
on-click = "nomarchy-menu powermgmt";

View File

@@ -126,6 +126,7 @@
"format": "<span size='13pt'>{icon}</span>{capacity}%",
"format-charging": "<span size='13pt'> </span>{capacity}%",
"format-plugged": "<span size='13pt'> </span>{capacity}%",
"tooltip-format-plugged": "Plugged in, not charging — held at {capacity}% by the battery charge cap\nCharging resumes ~10% below the cap · click to adjust",
"format-icons": [
" ",
" ",

View File

@@ -118,6 +118,7 @@
"format": "<span size='13pt'>{icon}</span>{capacity}%",
"format-charging": "<span size='13pt'> </span>{capacity}%",
"format-plugged": "<span size='13pt'> </span>{capacity}%",
"tooltip-format-plugged": "Plugged in, not charging — held at {capacity}% by the battery charge cap\nCharging resumes ~10% below the cap · click to adjust",
"format-icons": [
" ",
" ",

View File

@@ -82,6 +82,7 @@
"format": "<span size='13pt'>{icon}</span>{capacity}%",
"format-charging": "<span size='13pt'> </span>{capacity}%",
"format-plugged": "<span size='13pt'> </span>{capacity}%",
"tooltip-format-plugged": "Plugged in, not charging — held at {capacity}% by the battery charge cap\nCharging resumes ~10% below the cap · click to adjust",
"format-full": " 100%",
"format-icons": [
" ",

View File

@@ -82,6 +82,7 @@
"format": "<span size='13pt'>{icon}</span>{capacity}%",
"format-charging": "<span size='13pt'> </span>{capacity}%",
"format-plugged": "<span size='13pt'> </span>{capacity}%",
"tooltip-format-plugged": "Plugged in, not charging — held at {capacity}% by the battery charge cap\nCharging resumes ~10% below the cap · click to adjust",
"format-icons": [
" ",
" ",