All checks were successful
Check / eval (push) Successful in 4m29s
The full nomarchy-display-transition (dock/undock/enable — logging, the lid-inhibitor gate, restore_keyboards, the failure dump) and the nomarchy-keyboard-layout helper it calls move out of hyprland.nix into leaf files (modules/home/display-transition.nix, keyboard-tool.nix), imported by both hyprland.nix and idle.nix. This kills the lossy ~22-line mini idle.nix carried under the same binary name to dodge a circular import. The hypridle wake path (after_sleep / DPMS on-resume) now runs the real undock — restore_keyboards after a reload and the evidence dump on enable-failure — instead of a bare keyword+reload, and the two copies can no longer drift. Behaviour on the hyprland side is unchanged: the built nomarchy-display-transition and nomarchy-keyboard-layout have byte-identical store paths on HEAD vs this change (verbatim extraction). Verify: all four files parse; home activationPackage + system toplevel build; checks.docking-ux green (bash -n + safety-feature greps on the extracted scripts). The tools/monitor-fallback.nix dock harness is red on main already (the #148 reload-mid-dock assertion — identical failure on clean HEAD; filed BACKLOG #154), so it could not gate this. The idle wake-path behaviour change (full undock, incl. dock-intent clearing) is V3 pending: on-hardware suspend/resume + zero-output rescue queued in HARDWARE-QUEUE. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
82 lines
3.6 KiB
Nix
82 lines
3.6 KiB
Nix
# The per-device keyboard-layout helper (nomarchy-keyboard-layout).
|
||
# Extracted from hyprland.nix (#150) so it is built ONCE and shared: the
|
||
# Hyprland module puts it on PATH and drives it from the hotplug watcher,
|
||
# while the display-transition tool calls it (restore_keyboards) after a
|
||
# config reload. Pass the module's { pkgs, lib, config }.
|
||
{ pkgs, lib, config }:
|
||
let
|
||
sync = lib.getExe config.nomarchy.package;
|
||
|
||
# Candidate layouts offered by the new-keyboard picker: the session
|
||
# layout(s) (nomarchy.keyboard.layout, comma-split for a multi-layout
|
||
# session) plus the extra nomarchy.keyboard.layouts pool. The pool is
|
||
# deliberately NOT merged into input.kb_layout — those candidates are for
|
||
# *external* keyboards and get applied per-device by the watcher's apply().
|
||
# Loading them onto the session keyboard is what let a global switch flip
|
||
# the built-in board to the wrong layout.
|
||
pickerLayouts = lib.unique (
|
||
(lib.splitString "," config.nomarchy.keyboard.layout)
|
||
++ config.nomarchy.keyboard.layouts
|
||
);
|
||
in
|
||
# Per-device keyboard helper shared by the hotplug watcher and the manual
|
||
# System › Keyboard menu. The configured candidates are listed first, then
|
||
# every XKB layout known to the system, so the feature works on a default
|
||
# install instead of silently disappearing until home.nix is edited.
|
||
pkgs.writeShellScriptBin "nomarchy-keyboard-layout" ''
|
||
set -u
|
||
sync=${sync}
|
||
|
||
layouts() {
|
||
printf '%s\n' ${lib.concatMapStringsSep " " lib.escapeShellArg pickerLayouts}
|
||
${pkgs.gawk}/bin/awk '
|
||
/^! layout/ { in_layouts=1; next }
|
||
/^!/ && in_layouts { exit }
|
||
in_layouts && NF { print $1 }
|
||
' ${pkgs.xkeyboard_config}/share/X11/xkb/rules/base.lst
|
||
}
|
||
saved_map() { "$sync" get settings.keyboard.devices 2>/dev/null || echo '{}'; }
|
||
saved_for() { saved_map | jq -r --arg k "$1" '.[$k] // empty'; }
|
||
apply_runtime() { hyprctl keyword "device[$1]:kb_layout" "$2" >/dev/null 2>&1; }
|
||
|
||
case "''${1:-}" in
|
||
layouts)
|
||
layouts | ${pkgs.gawk}/bin/awk 'NF && !seen[$0]++' ;;
|
||
devices)
|
||
hyprctl devices -j 2>/dev/null \
|
||
| jq -r '.keyboards[] | "\(.name)\t\(.active_keymap // \"unknown\")"' ;;
|
||
saved)
|
||
[ -n "''${2:-}" ] || exit 64
|
||
saved_for "$2" ;;
|
||
restore)
|
||
[ -n "''${2:-}" ] || exit 64
|
||
layout=$(saved_for "$2")
|
||
[ -n "$layout" ] && apply_runtime "$2" "$layout" ;;
|
||
apply)
|
||
[ -n "''${2:-}" ] && [ -n "''${3:-}" ] || exit 64
|
||
layouts | ${pkgs.gnugrep}/bin/grep -Fxq "$3" \
|
||
|| { notify-send "Keyboard" "Unknown XKB layout: $3"; exit 64; }
|
||
if apply_runtime "$2" "$3"; then
|
||
map=$(saved_map | jq -c --arg k "$2" --arg v "$3" '. + {($k): $v}') || exit 1
|
||
if "$sync" --quiet set settings.keyboard.devices "$map" --no-switch; then
|
||
notify-send "Keyboard" "$2 → $3"
|
||
else
|
||
notify-send "Keyboard" "$2 → $3 for this session, but the choice could not be saved."
|
||
exit 1
|
||
fi
|
||
else
|
||
notify-send "Keyboard" "Could not apply $3 to $2."
|
||
exit 1
|
||
fi ;;
|
||
forget)
|
||
[ -n "''${2:-}" ] || exit 64
|
||
map=$(saved_map | jq -c --arg k "$2" 'del(.[$k])') || exit 1
|
||
"$sync" --quiet set settings.keyboard.devices "$map" --no-switch || exit 1
|
||
apply_runtime "$2" ${lib.escapeShellArg config.nomarchy.keyboard.layout} || true
|
||
notify-send "Keyboard" "$2 now follows the session layout." ;;
|
||
*)
|
||
echo "usage: nomarchy-keyboard-layout [layouts|devices|saved <device>|restore <device>|apply <device> <layout>|forget <device>]" >&2
|
||
exit 64 ;;
|
||
esac
|
||
''
|