Files
dotfiles/dot_local/bin/executable_umbriel-smart-move
T

37 lines
1.7 KiB
Bash
Raw Normal View History

#!/bin/sh
# umbriel-smart-move left|right
# niri's consume-or-expel move, extended across outputs:
# - stacked in a column → expel to a new column on that side
# - alone, column beside it → consume into that column
# - alone, at the strip's end → move to the output on that side
# Pressing twice therefore steps a window past its neighbour: in, then out the
# far side. Dwindle and master workspaces have no columns; there the window
# moves in that direction, or onto the next output at the edge. Floating and
# scratchpad windows are left alone.
set -eu
case ${1:-} in
left | right) dir=$1 ;;
*) echo "usage: umbriel-smart-move left|right" >&2; exit 2 ;;
esac
windows=$(umbriel windows --json)
layout=$(umbriel workspaces --json | jq -r '.[] | select(.focused) | .layout')
# "<action>" for the focused window, or nothing when it should stay put.
action=$(printf '%s' "$windows" | jq -r --arg dir "$dir" --arg layout "$layout" '
(map(select(.focused)) | first) as $w
| if $w == null or $w.floating or $w.scratchpad != "" then empty
elif $layout != "scrolling" then "window-move-or-output-\($dir)"
else
[ .[] | select(.workspace == $w.workspace and (.floating | not) and .scratchpad == "") ] as $tiled
| ([ $tiled[] | select(.column == $w.column) ] | length) as $rows
| ([ $tiled[] | .column ] | if $dir == "left" then min else max end) as $edge
| if $rows > 1 or $w.column != $edge then "window-consume-or-expel-\($dir)"
else "window-move-or-output-\($dir)"
end
end')
[ -n "$action" ] || exit 0
# At the outermost output, "no output to the left/right" is the expected end.
umbriel msg "$action" >/dev/null 2>&1 || true