|
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)) |