scripts/win 2.5 K raw
1
#!/bin/sh
2
# Requires: xdotool, xprop (xorg-xprop)
3
# Size and place the focused window as a percentage of the usable screen.
4
# xfwm4's own tile_* keys already cover halves and quarters (Shift+Super+h/l);
5
# this is for the geometries it has no name for -- a centered 60% window, a
6
# narrow reading column. The argument is WxH, optionally +X+Y, all in percent
7
# of the work area, with no offset meaning centered:
8
#   win 60x70       60% wide, 70% tall, centered
9
#   win 100x40+0+0  full width, top 40%
10
# The win-* symlinks beside it are presets, so a keybind is a bare path with
11
# no arguments -- the same trick vol-up/vol-down use.
12
set -u
13
14
win=$(xdotool getactivewindow 2>/dev/null) || exit 0
15
16
# The name it was called by (win-center -> center), or the first argument.
17
geom=${1:-$(printf '%s' "${0##*/}" | sed 's/^win-*//')}
18
19
case "$geom" in
20
    center) geom=40x60     ;;
21
    big)    geom=90x90     ;;
22
    small)  geom=40x50     ;;
23
    read)   geom=45x90     ;;
24
    full)   geom=100x100   ;;
25
esac
26
27
# Split WxH[+X+Y]. A missing offset stays empty and is read as "centre me".
28
pw=${geom%%x*}
29
rest=${geom#*x}
30
case "$rest" in
31
    *+*+*) ph=${rest%%+*}; off=${rest#*+}; px=${off%%+*}; py=${off#*+} ;;
32
    *)     ph=$rest;       px=;            py= ;;
33
esac
34
35
case "$pw$ph$px$py" in
36
    *[!0-9]*|'') echo "usage: ${0##*/} WxH[+X+Y] | center|big|small|read|full" >&2; exit 2 ;;
37
esac
38
39
# xfwm4 refuses to resize a maximized window, so drop those states first;
40
# without this the first press after a maximize silently does nothing.
41
xdotool windowstate --remove MAXIMIZED_VERT --remove MAXIMIZED_HORZ "$win" 2>/dev/null
42
43
# The first desktop's work area: the screen minus polybar's reserved strip, so
44
# a 100%-tall window stops at the bar instead of sliding under it.
45
set -- $(xprop -root _NET_WORKAREA | sed 's/.*= //; s/,//g')
46
ax=$1 ay=$2 aw=$3 ah=$4
47
48
# windowmove places the frame, but windowsize sets the *client* area, so the
49
# decorations have to come off the requested size or every window lands one
50
# title bar too tall.
51
set -- $(xprop -id "$win" _NET_FRAME_EXTENTS 2>/dev/null | sed 's/.*= //; s/,//g')
52
fl=${1:-0} fr=${2:-0} ft=${3:-0} fb=${4:-0}
53
54
w=$((aw * pw / 100))
55
h=$((ah * ph / 100))
56
# An omitted offset centres on that axis, which is what most of the presets
57
# want; a given one is a percentage from the work area's top-left corner.
58
if [ -n "$px" ]; then x=$((ax + aw * px / 100)); else x=$((ax + (aw - w) / 2)); fi
59
if [ -n "$py" ]; then y=$((ay + ah * py / 100)); else y=$((ay + (ah - h) / 2)); fi
60
61
xdotool windowmove "$win" "$x" "$y" \
62
        windowsize "$win" $((w - fl - fr)) $((h - ft - fb))