From 45c5280b296a6647420cda794f7606c53b6566cd Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 25 Aug 2026 09:00:27 -0400 Subject: [PATCH] mise ~/.config/mise/config.toml tools: crush@0.91.0 feat(cli): add window size cycling script --- .../bin/executable_omarchy-cycle-window-size | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100755 dot_local/bin/executable_omarchy-cycle-window-size diff --git a/dot_local/bin/executable_omarchy-cycle-window-size b/dot_local/bin/executable_omarchy-cycle-window-size new file mode 100755 index 0000000..19caccc --- /dev/null +++ b/dot_local/bin/executable_omarchy-cycle-window-size @@ -0,0 +1,127 @@ +#!/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"