feat(hyprland): launch-or-focus binds (item 17)
All checks were successful
Check / eval (push) Successful in 3m4s

nomarchy.launchOrFocus (opt-in, commented template example): each
entry gives a key that FOCUSES the app's existing window
(case-insensitive class match via jq + a "(?i)" focuswindow regex) or
launches it when none is open. One shared nomarchy-focus-or-launch
script; a bind whose command was removed from the suite fires a
"not installed" toast instead of failing silently. The same entries
render into the SUPER+? cheatsheet through prettyKeys — bind and
documentation stay one source. README row added.

Verified: V0; V1 — a scratch downstream with two entries renders both
binds (default command = lowercased class; custom mods/command/desc
honored), the script passes bash -n with a usage guard, and the
cheatsheet carries both rows. Focus behaviour needs a session -> V3
(HARDWARE-QUEUE).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-07-05 20:56:01 +01:00
parent 4e3acbe89c
commit 8d54eecd67
8 changed files with 116 additions and 6 deletions

View File

@@ -31,6 +31,34 @@ let
${pkgs.swayosd}/bin/swayosd-client --custom-icon "$icon" --custom-progress "$2"
'';
# Launch-or-focus (nomarchy.launchOrFocus, item 17): focus the app's
# window if one exists (case-insensitive class match), launch it
# otherwise. Self-gates: an uninstalled command notifies instead of
# failing silently, so a bind survives the app being removed from the
# suite. rofi.nix renders the same entries into the SUPER+? cheatsheet.
focusOrLaunch = pkgs.writeShellScriptBin "nomarchy-focus-or-launch" ''
class="''${1:-}"; shift || true
[ -n "$class" ] && [ $# -gt 0 ] || {
echo "usage: nomarchy-focus-or-launch <class> <command...>" >&2; exit 64
}
if hyprctl clients -j 2>/dev/null \
| ${pkgs.jq}/bin/jq -e --arg c "$class" \
'any(.[]; (.class | ascii_downcase) == ($c | ascii_downcase))' >/dev/null; then
exec hyprctl dispatch focuswindow "class:(?i)^$class\$"
fi
command -v "$1" >/dev/null 2>&1 \
|| { notify-send "Launch" "$1 is not installed."; exit 0; }
exec "$@"
'';
lofEntries = map
(e: e // {
command = if e.command == "" then lib.toLower e.class else e.command;
})
config.nomarchy.launchOrFocus;
lofBinds = map
(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.
workspaceBinds = builtins.concatLists (builtins.genList
(i:
@@ -393,7 +421,8 @@ in
bind = map mkBind (keybinds.binds
++ lib.optionals (lib.hasInfix "," config.nomarchy.keyboard.layout)
keybinds.multiLayoutBinds)
++ workspaceBinds;
++ workspaceBinds
++ lofBinds;
# Media keys via swayosd-client: it performs the action AND shows
# the on-screen display (the nomarchy.osd module). e = repeat,