diff options
Diffstat (limited to 'config/hypr/scripts/LayoutKeybindDispatch.sh')
| -rwxr-xr-x | config/hypr/scripts/LayoutKeybindDispatch.sh | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/config/hypr/scripts/LayoutKeybindDispatch.sh b/config/hypr/scripts/LayoutKeybindDispatch.sh new file mode 100755 index 00000000..48d3a1c5 --- /dev/null +++ b/config/hypr/scripts/LayoutKeybindDispatch.sh @@ -0,0 +1,219 @@ +#!/usr/bin/env bash +# ================================================== +# KoolDots (2026) +# Project URL: https://github.com/LinuxBeginnings +# License: GNU GPLv3 +# SPDX-License-Identifier: GPL-3.0-or-later +# ================================================== +# Dispatch layout-sensitive navigation actions per active workspace. +# This keeps SUPER+J/K and SUPER+arrow behavior aligned with workspace rules. + +set -u + +if ! command -v hyprctl >/dev/null 2>&1; then + exit 0 +fi + +LUA_CYCLE_SCRIPT="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/scripts/LuaCycleWindow.sh" + +normalize_layout() { + case "$1" in + master | dwindle | scrolling | monocle) + printf '%s\n' "$1" + ;; + *) + printf '\n' + ;; + esac +} + +get_active_layout() { + local layout + + layout="$(hyprctl -j activeworkspace 2>/dev/null | jq -r '.tiledLayout // .tiled_layout // .layout // empty' 2>/dev/null || true)" + layout="$(normalize_layout "$layout")" + + if [[ -z "$layout" ]]; then + layout="$(hyprctl -j getoption general:layout 2>/dev/null | jq -r '.str // empty' 2>/dev/null || true)" + layout="$(normalize_layout "$layout")" + fi + + if [[ -z "$layout" ]]; then + layout="dwindle" + fi + + printf '%s\n' "$layout" +} + +dispatch_quiet() { + local dispatcher="$1" + shift || true + if (($# > 0)); then + hyprctl dispatch "$dispatcher" "$@" >/dev/null 2>&1 || true + else + hyprctl dispatch "$dispatcher" >/dev/null 2>&1 || true + fi +} + +get_active_window_address() { + if ! command -v jq >/dev/null 2>&1; then + printf '\n' + return 0 + fi + hyprctl -j activewindow 2>/dev/null | jq -r '.address // empty' 2>/dev/null || true +} + +dispatch_changed_focus() { + local before after dispatcher="$1" + shift || true + before="$(get_active_window_address)" + dispatch_quiet "$dispatcher" "$@" + after="$(get_active_window_address)" + [[ -n "$before" && -n "$after" && "$before" != "$after" ]] +} + +direction_word() { + case "$1" in + l | left) printf 'left\n' ;; + r | right) printf 'right\n' ;; + u | up) printf 'up\n' ;; + d | down) printf 'down\n' ;; + *) printf 'right\n' ;; + esac +} + +dispatch_lua_focus() { + local dir_word + dir_word="$(direction_word "$1")" + hyprctl dispatch "hl.dsp.focus({ direction = \"$dir_word\" })" >/dev/null 2>&1 || true +} + +cycle_lua() { + local mode="${1:-next}" + if [[ -x "$LUA_CYCLE_SCRIPT" ]]; then + "$LUA_CYCLE_SCRIPT" "$mode" >/dev/null 2>&1 || true + return 0 + fi + case "$mode" in + previous | prev | back) dispatch_lua_focus left ;; + *) dispatch_lua_focus right ;; + esac +} + +cycle_next() { + local layout="$1" + case "$layout" in + scrolling) + if ! dispatch_changed_focus layoutmsg "focus r"; then + dispatch_lua_focus right + fi + ;; + monocle) + if ! dispatch_changed_focus layoutmsg cyclenext; then + cycle_lua next + fi + ;; + *) + if ! dispatch_changed_focus cyclenext; then + cycle_lua next + fi + ;; + esac +} + +cycle_prev() { + local layout="$1" + case "$layout" in + scrolling) + if ! dispatch_changed_focus layoutmsg "focus l"; then + dispatch_lua_focus left + fi + ;; + monocle) + if ! dispatch_changed_focus layoutmsg cycleprev; then + cycle_lua previous + fi + ;; + *) + if ! dispatch_changed_focus cyclenext prev; then + cycle_lua previous + fi + ;; + esac +} + +focus_by_layout() { + local layout="$1" + local direction="$2" + + case "$layout" in + master) + if ! dispatch_changed_focus movefocus "$direction"; then + dispatch_lua_focus "$direction" + fi + ;; + monocle) + case "$direction" in + l | u) cycle_prev "$layout" ;; + *) cycle_next "$layout" ;; + esac + ;; + dwindle | scrolling) + case "$direction" in + l | u) + if [[ "$layout" == "scrolling" ]]; then + if ! dispatch_changed_focus layoutmsg "focus $direction"; then + dispatch_lua_focus "$direction" + fi + else + cycle_prev "$layout" + fi + ;; + *) + if [[ "$layout" == "scrolling" ]]; then + if ! dispatch_changed_focus layoutmsg "focus $direction"; then + dispatch_lua_focus "$direction" + fi + else + cycle_next "$layout" + fi + ;; + esac + ;; + *) + if ! dispatch_changed_focus movefocus "$direction"; then + dispatch_lua_focus "$direction" + fi + ;; + esac +} + +layout="$(get_active_layout)" + +case "${1:-}" in +cycle-next | next) + cycle_next "$layout" + ;; +cycle-prev | prev | previous) + cycle_prev "$layout" + ;; +focus-left | left) + focus_by_layout "$layout" l + ;; +focus-right | right) + focus_by_layout "$layout" r + ;; +focus-up | up) + focus_by_layout "$layout" u + ;; +focus-down | down) + focus_by_layout "$layout" d + ;; +layout | current-layout | status) + printf '%s\n' "$layout" + ;; +*) + echo "Usage: $(basename "$0") [cycle-next|cycle-prev|focus-left|focus-right|focus-up|focus-down|layout]" >&2 + exit 1 + ;; +esac |
