201 lines
3.9 KiB
Bash
Executable File
201 lines
3.9 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
# --- CONFIG ---
|
|
TOP_BAR=36
|
|
DECOR_H=30
|
|
DECOR_W=5
|
|
|
|
MASTER_RATIO_NUM=1
|
|
MASTER_RATIO_DEN=2
|
|
|
|
OUTER_GAP=8
|
|
INNER_GAP=8
|
|
|
|
# Master selection:
|
|
# focused = currently focused window
|
|
# first = first window on desktop
|
|
# last = last window on desktop
|
|
MASTER_MODE="focused"
|
|
|
|
# ----------------
|
|
|
|
# Get current screen resolution
|
|
read SCREEN_W SCREEN_H <<< $(xrandr | awk '
|
|
/\*/ {
|
|
split($1,a,"x")
|
|
print a[1], a[2]
|
|
exit
|
|
}')
|
|
|
|
USABLE_H=$((SCREEN_H - TOP_BAR))
|
|
|
|
# Work area after outer gaps
|
|
WORK_X=$OUTER_GAP
|
|
WORK_Y=$((TOP_BAR + OUTER_GAP))
|
|
WORK_W=$((SCREEN_W - 2 * OUTER_GAP))
|
|
WORK_H=$((USABLE_H - 2 * OUTER_GAP))
|
|
|
|
# --- focused window ---
|
|
FOCUSED=$(printf "0x%08x" "$(xdotool getactivewindow)")
|
|
|
|
# --- current desktop ---
|
|
CUR_DESKTOP=$(xdotool get_desktop)
|
|
|
|
# --- collect windows on current desktop ---
|
|
ALL_WINDOWS=$(wmctrl -l -x | awk '$2!="-1" {print $1}')
|
|
|
|
WINDOWS=()
|
|
|
|
for w in $ALL_WINDOWS; do
|
|
win_desktop=$(xdotool get_desktop_for_window "$(printf "%d" "$w")" 2>/dev/null) || continue
|
|
|
|
if [ "$win_desktop" = "$CUR_DESKTOP" ]; then
|
|
WINDOWS+=("$w")
|
|
fi
|
|
done
|
|
|
|
if [ ${#WINDOWS[@]} -eq 0 ]; then
|
|
echo "No windows found on current desktop."
|
|
exit 1
|
|
fi
|
|
|
|
# ----------------------------------------------------
|
|
# Determine master window
|
|
# ----------------------------------------------------
|
|
|
|
case "$MASTER_MODE" in
|
|
focused)
|
|
MASTER="$FOCUSED"
|
|
;;
|
|
first)
|
|
MASTER="${WINDOWS[0]}"
|
|
;;
|
|
last)
|
|
MASTER="${WINDOWS[$((${#WINDOWS[@]} - 1))]}"
|
|
;;
|
|
*)
|
|
echo "Invalid MASTER_MODE: $MASTER_MODE"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# --- separate master from stack ---
|
|
STACK=()
|
|
|
|
for w in "${WINDOWS[@]}"; do
|
|
if [ "$w" != "$MASTER" ]; then
|
|
STACK+=("$w")
|
|
fi
|
|
done
|
|
|
|
place() {
|
|
local id=$1
|
|
local x=$2
|
|
local y=$3
|
|
local raw_w=$4
|
|
local raw_h=$5
|
|
local class decor_h decor_w x_offset y_offset
|
|
x_offset=0
|
|
y_offset=0
|
|
|
|
class=$(xprop -id "$id" WM_CLASS 2>/dev/null | sed -r 's/.*"(.*)"$/\1/')
|
|
case "$class" in
|
|
Alacritty)
|
|
decor_h=42
|
|
decor_w=8
|
|
;;
|
|
Chromium)
|
|
decor_h=42
|
|
decor_w=5
|
|
;;
|
|
obsidian)
|
|
decor_h=5
|
|
decor_w=0
|
|
x_offset=-0
|
|
y_offset=-0
|
|
;;
|
|
dev.zed.Zed)
|
|
decor_h=-19
|
|
decor_w=-23
|
|
x_offset=-13
|
|
y_offset=-13
|
|
;;
|
|
*)
|
|
decor_h=$DECOR_H
|
|
decor_w=$DECOR_W
|
|
;;
|
|
esac
|
|
|
|
local w=$((raw_w - decor_w))
|
|
local h=$((raw_h - decor_h))
|
|
local fx=$((x + x_offset))
|
|
local fy=$((y + y_offset))
|
|
wmctrl -i -r "$id" -b remove,maximized_vert,maximized_horz
|
|
wmctrl -i -r "$id" -e 1,"$fx","$fy","$w","$h"
|
|
}
|
|
|
|
# ----------------------------------------------------
|
|
# Single window
|
|
# ----------------------------------------------------
|
|
|
|
if [ ${#WINDOWS[@]} -eq 1 ]; then
|
|
place \
|
|
"$MASTER" \
|
|
"$WORK_X" \
|
|
"$WORK_Y" \
|
|
"$WORK_W" \
|
|
"$WORK_H"
|
|
|
|
exit 0
|
|
fi
|
|
|
|
# ----------------------------------------------------
|
|
# Master / Stack layout
|
|
# ----------------------------------------------------
|
|
|
|
MID=$((WORK_W * MASTER_RATIO_NUM / MASTER_RATIO_DEN))
|
|
|
|
MASTER_X=$WORK_X
|
|
MASTER_Y=$WORK_Y
|
|
|
|
MASTER_W=$((MID - INNER_GAP / 2))
|
|
MASTER_H=$WORK_H
|
|
|
|
STACK_X=$((WORK_X + MID + INNER_GAP / 2))
|
|
STACK_Y=$WORK_Y
|
|
|
|
STACK_W=$((WORK_W - MID - INNER_GAP / 2))
|
|
STACK_H=$WORK_H
|
|
|
|
# --- place master ---
|
|
place \
|
|
"$MASTER" \
|
|
"$MASTER_X" \
|
|
"$MASTER_Y" \
|
|
"$MASTER_W" \
|
|
"$MASTER_H"
|
|
|
|
# --- place stack ---
|
|
COUNT=${#STACK[@]}
|
|
|
|
if [ "$COUNT" -gt 0 ]; then
|
|
|
|
SLOT_H=$(((STACK_H - INNER_GAP * (COUNT - 1)) / COUNT))
|
|
|
|
i=0
|
|
|
|
for w in "${STACK[@]}"; do
|
|
|
|
SLOT_Y=$((STACK_Y + i * (SLOT_H + INNER_GAP)))
|
|
|
|
place \
|
|
"$w" \
|
|
"$STACK_X" \
|
|
"$SLOT_Y" \
|
|
"$STACK_W" \
|
|
"$SLOT_H"
|
|
|
|
i=$((i + 1))
|
|
done
|
|
fi
|