Files
Nomarchy/modules/home/keyboard-tool.nix
Bernardo Magri baf2cd2e13
All checks were successful
Check / eval (push) Successful in 4m29s
refactor(display): extract the shared display-transition + keyboard tools (#150)
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>
2026-07-20 19:17:57 +01:00

82 lines
3.6 KiB
Nix
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
''