mirror of
https://github.com/prdlk/dotfiles.git
synced 2026-11-02 19:32:43 +00:00
127 lines
3.9 KiB
Bash
127 lines
3.9 KiB
Bash
#!/bin/bash
|
|||
|
|
|
||
|
|
# omarchy:summary=Cycle the focused window through preset sizes
|
||
|
|
# omarchy:args=[next|prev]
|
||
|
|
|
||
|
|
set -uo pipefail
|
||
|
|
|
||
|
|
DIRECTION="${1:-next}"
|
||
|
|
|
||
|
|
# Preset widths, as a fraction of the screen. Edit to taste.
|
||
|
|
# These only apply to dwindle and to floating windows. On a scrolling
|
||
|
|
# workspace the layout cycles its own list instead. Set that list with:
|
||
|
|
# hl.config({ scrolling = { explicit_column_widths = "0.333, 0.5, 0.667, 1.0" } })
|
||
|
|
FRACTIONS=(0.333 0.5 0.667)
|
||
|
|
|
||
|
|
# Height of a floating window, as a fraction of the screen.
|
||
|
|
FLOATING_HEIGHT=0.8
|
||
|
|
|
||
|
|
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/omarchy/window-sizes"
|
||
|
|
|
||
|
|
# Try the Lua dispatcher first, then fall back to the legacy name.
|
||
|
|
hypr_dispatch() {
|
||
|
|
local lua="$1"
|
||
|
|
shift
|
||
|
|
|
||
|
|
hyprctl dispatch "$lua" >/dev/null 2>&1 || hyprctl dispatch "$@" >/dev/null
|
||
|
|
}
|
||
|
|
|
||
|
|
calc() {
|
||
|
|
awk "BEGIN { printf \"%s\", $1 }"
|
||
|
|
}
|
||
|
|
|
||
|
|
ACTIVE=$(hyprctl activewindow -j 2>/dev/null)
|
||
|
|
[[ -n $ACTIVE && $ACTIVE != "{}" ]] || exit 0
|
||
|
|
|
||
|
|
ADDRESS=$(jq -r '.address // empty' <<<"$ACTIVE")
|
||
|
|
FLOATING=$(jq -r '.floating // false' <<<"$ACTIVE")
|
||
|
|
WORKSPACE=$(jq -r '.workspace.id // empty' <<<"$ACTIVE")
|
||
|
|
LAYOUT=$(hyprctl activeworkspace -j 2>/dev/null | jq -r '.tiledLayout // empty')
|
||
|
|
|
||
|
|
# --- Scrolling: the layout keeps its own preset list ------------------------
|
||
|
|
|
||
|
|
if [[ $FLOATING != "true" && $LAYOUT == "scrolling" ]]; then
|
||
|
|
if [[ $DIRECTION == "prev" ]]; then
|
||
|
|
MSG="colresize -conf"
|
||
|
|
else
|
||
|
|
MSG="colresize +conf"
|
||
|
|
fi
|
||
|
|
|
||
|
|
hypr_dispatch "hl.dsp.layout(\"$MSG\")" layoutmsg "$MSG"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# --- Step to the next preset ------------------------------------------------
|
||
|
|
|
||
|
|
# Floating windows keep an index of their own. Tiled windows share one index
|
||
|
|
# per workspace, because the split is a property of the workspace.
|
||
|
|
if [[ $FLOATING == "true" ]]; then
|
||
|
|
STATE_KEY="window-${ADDRESS}"
|
||
|
|
else
|
||
|
|
STATE_KEY="workspace-${WORKSPACE}"
|
||
|
|
fi
|
||
|
|
|
||
|
|
STATE_FILE="$STATE_DIR/${STATE_KEY}.index"
|
||
|
|
COUNT=${#FRACTIONS[@]}
|
||
|
|
|
||
|
|
INDEX=0
|
||
|
|
if [[ -f $STATE_FILE ]]; then
|
||
|
|
INDEX=$(<"$STATE_FILE")
|
||
|
|
[[ $INDEX =~ ^[0-9]+$ ]] || INDEX=0
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ $DIRECTION == "prev" ]]; then
|
||
|
|
INDEX=$(((INDEX - 1 + COUNT) % COUNT))
|
||
|
|
else
|
||
|
|
INDEX=$(((INDEX + 1) % COUNT))
|
||
|
|
fi
|
||
|
|
|
||
|
|
mkdir -p "$STATE_DIR"
|
||
|
|
printf '%s\n' "$INDEX" >"$STATE_FILE"
|
||
|
|
|
||
|
|
FRACTION=${FRACTIONS[$INDEX]}
|
||
|
|
|
||
|
|
# --- Floating: set an absolute size and center ------------------------------
|
||
|
|
|
||
|
|
if [[ $FLOATING == "true" ]]; then
|
||
|
|
read -r MON_W MON_H < <(hyprctl monitors -j |
|
||
|
|
jq -r '.[] | select(.focused) | "\(((.width / .scale) | floor)) \(((.height / .scale) | floor))"')
|
||
|
|
|
||
|
|
[[ -n ${MON_W:-} && -n ${MON_H:-} ]] || exit 1
|
||
|
|
|
||
|
|
WIDTH=$(calc "int($MON_W * $FRACTION)")
|
||
|
|
HEIGHT=$(calc "int($MON_H * $FLOATING_HEIGHT)")
|
||
|
|
|
||
|
|
hypr_dispatch "hl.dsp.window.resize({ x = $WIDTH, y = $HEIGHT })" resizeactive exact "$WIDTH" "$HEIGHT"
|
||
|
|
hypr_dispatch "hl.dsp.window.center()" centerwindow
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# --- Dwindle: set the split ratio -------------------------------------------
|
||
|
|
|
||
|
|
# splitratio 1.0 is an even split, so a fraction of 0.5 maps to 1.0.
|
||
|
|
# With the default split_bias of 0, the ratio goes to the left or top window.
|
||
|
|
# So when the focused window is the right or bottom one, the fraction is
|
||
|
|
# mirrored. Which side the window sits on is read from its position.
|
||
|
|
read -r WIN_X WIN_Y WIN_W WIN_H < <(jq -r '"\(.at[0]) \(.at[1]) \(.size[0]) \(.size[1])"' <<<"$ACTIVE")
|
||
|
|
read -r MON_X MON_Y MON_W MON_H < <(hyprctl monitors -j |
|
||
|
|
jq -r '.[] | select(.focused) | "\(.x) \(.y) \(((.width / .scale) | floor)) \(((.height / .scale) | floor))"')
|
||
|
|
|
||
|
|
MIRROR=false
|
||
|
|
if ((WIN_W * 100 > MON_W * 90)); then
|
||
|
|
# The window spans the screen, so the split is top and bottom.
|
||
|
|
((WIN_Y + WIN_H / 2 > MON_Y + MON_H / 2)) && MIRROR=true
|
||
|
|
else
|
||
|
|
((WIN_X + WIN_W / 2 > MON_X + MON_W / 2)) && MIRROR=true
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ $MIRROR == "true" ]]; then
|
||
|
|
RATIO=$(calc "2 * (1 - $FRACTION)")
|
||
|
|
else
|
||
|
|
RATIO=$(calc "2 * $FRACTION")
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Hyprland accepts 0.1 to 1.9.
|
||
|
|
RATIO=$(calc "($RATIO < 0.1 ? 0.1 : ($RATIO > 1.9 ? 1.9 : $RATIO))")
|
||
|
|
|
||
|
|
hypr_dispatch "hl.dsp.layout(\"splitratio $RATIO exact\")" layoutmsg "splitratio $RATIO exact"
|