Skip to content

Instantly share code, notes, and snippets.

@easterncoder
Last active June 11, 2021 07:52
Show Gist options
  • Save easterncoder/2af134b541b16c0a6d8d0dfb75ca9d81 to your computer and use it in GitHub Desktop.
Save easterncoder/2af134b541b16c0a6d8d0dfb75ca9d81 to your computer and use it in GitHub Desktop.
Script to resize and position an X11 window using wmctrl
#!/bin/bash
# Help
if [ "help" == "$1" ]
then
less <<EOF
Resize and position a window.
Usage:
rpw window_substring [dimension [position]]
window_substring:
A substring of the title of the window being resized
or "0" or "active" for the active window.
Default: Active window.
dimension:
Dimension to resize the window to.
Possible values are:
NxN : Width and height specified
xN : Height specified, autocompute width
Nx : Width specified, autocompute height
N : Width and height are the same
0 : Autocompute width and height
'' : Autocompute width and height
Auto-computation of width and height are based on
the desktop dimension's ratio.
If auto-computation of both width and height are
needed then the height is first processed using a
set of breakpoints and then the width is calculated
based on the desktop dimension's ratio.
Height breakpoints are:
1440, 1080, 900, 768, 720 and 576
position:
Where to position the window being resized.
Default: center
Possible position values are:
center/c/middle/m
northwest/nw/topleft/tl
northeast/ne/topright/tr
southwest/sw/bottomleft/bl
southeast/se/bottomright/br
north/n/top/t
south/s/bottom/b
east/e/right/r
west/w/left/l
EOF
exit
fi
# Default window
[[ "$1" =~ ^0*$ ]] && window="active" || window=$1
# Get dimension of current active desktop
x=`wmctrl -d | grep -oE '\* DG: [0-9]+x[0-9]+' | cut -d' ' -f3`
desktopW=`cut -d'x' -f1 <<<"$x"`
desktopH=`cut -d'x' -f2 <<<"$x"`
width=$(cut -d'x' -f1 <<<"$2")
height=$(cut -d'x' -f2 <<<"$2")
if [[ "$height" =~ ^([^0-9]|0)*$ ]]; then
if [[ "$width" =~ ^([^0-9]|0)*$ ]]; then
# Compute Default Height
defaultH=$desktopH
# Compute default height from breakpoints
for x in 576 720 768 900 1080 1440; do [[ "$desktopH" -gt "$x" ]] && defaultH="$x" || break; done
# Set height to default if 0 or not numeric
[[ "$height" =~ ^([^0-9]|0)*$ ]] && height=$defaultH
else
height=$(printf '%.0f' $(bc -l <<<"$width*($desktopH/$desktopW)"))
fi
fi
if [[ "$width" =~ ^([^0-9]|0)*$ ]]; then
# Compute width using desktop dimension's ratio
width=$(printf '%.0f' $(bc -l <<<"$height/($desktopH/$desktopW)"))
fi
# Limit height to desktop height
[[ "$height" -gt "$desktopH" ]] && height=$desktopH
# Limit width to desktop width
[[ "$width" -gt "$desktopW" ]] && width=$desktopW
# Default position
position=${3:-center}
# Compute window coordinates
north=0
south=$(($desktopH - $height))
east=$(($desktopW - $width))
west=0
midX=`bc <<<"$east / 2"`
midY=`bc <<<"$south / 2"`
case "$position" in
northwest|nw|topleft|tl)
y=$north
x=$west
;;
northeast|ne|topright|tr)
y=$north
x=$east
;;
southwest|sw|bottomleft|bl)
y=$south
x=$west
;;
southeast|se|bottomright|br)
y=$south
x=$east
;;
north|n|top|t)
y=$north
x=$midX
;;
south|s|bottom|b)
y=$south
x=$midX
;;
east|e|right|r)
y=$midY
x=$east
;;
west|w|left|l)
y=$midY
x=$west
;;
center|c|middle|m|*)
y=$midY
x=$midX
;;
esac
# target active window
if [ "active" == "$window" ]
then
window=":ACTIVE:"
fi
# Remove unmaximize and unfullscreen the window
wmctrl -r "$window" -b remove,fullscreen,maximized_vert,maximized_horz
# Move window to current desktop and raise it
wmctrl -R "$window"
# Resize and position the window
wmctrl -r "$window" -e 0,$x,$y,$width,$height
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment