#!/bin/bash
#
# Author: Twily 2014 - 2018
# Description: Tile windows in floating mode using hotkeys
# Requires: wmctrl, xdotool, xwininfo, xprop, sed
# Usage: $ sh ./grid 2 4
# (Eg.: Bind key W-A-KP_[1-9] to "grid 1 [1-9]"
# |---|---|---| Bind key W-KP_[1-9] to "grid 2 [1-9]"
# | 7 | 8 | 9 | Bind key W-C-KP_[1-9] to "grid 3 [1-9]")
# |---|---|---|
# | 4 | 5 | 6 | (C~trl A~lt K~ey P~ad
# |---|---|---| W~in S~hift)
# | 1 | 2 | 3 |
# |---|---|---|
#
# see http://twily.info/.config/openbox/rc.xml#view for keybind examples
#
WNAME=$(xdotool getactivewindow getwindowname)
WID=$(xdotool getactivewindow)
if [ "$WNAME" == "Desktop" ]; then exit 3; fi
W=1920 # Desktop Width
H=1080 # Desktop Height
eM=0 # (Used for equal margin on all sides)
G=0 # Window Gap
L=$eM # Left Margin
T=$(( $eM + 25 )) # Top Margin (+24 for panel)
R=$eM # Right Margin
B=$eM # Bottom Margin
eval $(xwininfo -id $WID |
sed -n -e "s/^ \+Relative upper-left X: \+\([0-9]\+\).*/M=\1/p" \
-e "s/^ \+Relative upper-left Y: \+\([0-9]\+\).*/D=\1/p")
eD=$D
D=$(( $D - 1 )); # Customize to fine tune vertical alignment +/-
W=$(( $W - $L - $R ))
H=$(( $H - $T - $B ))
G=$(( $G / 2 ))
M=$(( $M * 2 ))
X=$L && Y=$T
case "$1" in # Window Left,Top,Width,Height
1) case "$2" in # (grid 1 [1-9])
7) X=$(( $L )) && Y=$(( $T )) # top left (1/6)
W=$(( $W / 3 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
8) X=$(( $W / 3 + $L + $G )) && Y=$(( $T )) # top center (1/6)
W=$(( $W / 3 - $G * 2 - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
9) X=$(( $W / 3 * 2 + $L + $G )) && Y=$(( $T )) # top right (1/6)
W=$(( $W / 3 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
4) X=$(( $L )) && Y=$(( $T )) # left (1/3)
W=$(( $W / 3 - $G - $M )) && H=$(( $H - $D - $M )) ;;
5) X=$(( $W / 3 + $L + $G )) && Y=$(( $T )) # center (1/3)
W=$(( $W / 3 - $G * 2 - $M )) && H=$(( $H - $D - $M )) ;;
6) X=$(( $W / 3 * 2 + $L + $G )) && Y=$(( $T )) # right (1/3)
W=$(( $W / 3 - $G - $M )) && H=$(( $H - $D - $M )) ;;
1) X=$(( $L )) && Y=$(( $H / 2 + $T + $G )) # bottom left (1/6)
W=$(( $W / 3 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
2) X=$(( $W / 3 + $L + $G )) && Y=$(( $H / 2 + $T + $G )) # bottom center (1/6)
W=$(( $W / 3 - $G * 2 - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
3) X=$(( $W / 3 * 2 + $L + $G )) && Y=$(( $H / 2 + $T + $G )) # bottom right (1/6)
W=$(( $W / 3 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
*) exit 2 ;;
esac
;;
2) case "$2" in # (grid 2 [1-9])
7) X=$(( $L )) && Y=$(( $T )) # top left (1/4)
W=$(( $W / 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
8) X=$(( $L )) && Y=$(( $T )) # top (1/2)
W=$(( $W - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
9) X=$(( $W / 2 + $L + $G )) && Y=$(( $T )) # top right (1/4)
W=$(( $W / 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
4) X=$(( $L )) && Y=$(( $T )) # left (1/2)
W=$(( $W / 2 - $G - $M )) && H=$(( $H - $D - $M )) ;;
5) X=$(( $L )) && Y=$(( $T )) # center (1/1)
W=$(( $W - $M )) && H=$(( $H - $D - $M )) ;;
6) X=$(( $W / 2 + $L + $G )) && Y=$(( $T )) # right (1/2)
W=$(( $W / 2 - $G - $M )) && H=$(( $H - $D - $M )) ;;
1) X=$(( $L )) && Y=$(( $H / 2 + $T + $G )) # bottom left (1/4)
W=$(( $W / 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
2) X=$(( $L )) && Y=$(( $H / 2 + $T + $G )) # bottom (1/2)
W=$(( $W - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
3) X=$(( $W / 2 + $L + $G )) && Y=$(( $H / 2 + $T + $G )) # bottom right (1/4)
W=$(( $W / 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
*) exit 2 ;;
esac
;;
3) case "$2" in # (grid 3 [1-9])
7) X=$(( $L )) && Y=$(( $T )) # top left (1/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
8) X=$(( $W / 3 / 2 + $L )) && Y=$(( $T )) # top (1/2)
W=$(( $W / 3 * 2 - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
9) X=$(( $W / 3 + $L + $G )) && Y=$(( $T )) # top right (1/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
4) X=$(( $L )) && Y=$(( $T )) # left (2/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H - $D - $M )) ;;
5) X=$(( $L + $W / 10 )) && Y=$(( $T + $H / 10 )) # center (1/1)
W=$(( $W - $W / 5 - $M )) && H=$(( $H - $H / 5 - $D - $M )) ;;
6) X=$(( $W / 3 + $L + $G )) && Y=$(( $T )) # right (2/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H - $D - $M )) ;;
1) X=$(( $L )) && Y=$(( $H / 2 + $T + $G )) # bottom left (1/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
2) X=$(( $W / 3 / 2 + $L )) && Y=$(( $H / 2 + $T + $G )) # bottom (1/2)
W=$(( $W / 3 * 2 - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
3) X=$(( $W / 3 + $L + $G )) && Y=$(( $H / 2 + $T + $G )) # bottom right (1/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
*) exit 2 ;;
esac
;;
*) exit 1 ;;
esac
CURSOR=$(xdotool getmouselocation --shell | grep X | cut -c 3-) # Multi-monitor
if [ "$CURSOR" -gt "3840" ]; then
X=$(( $X + 3841 )) # Third monitor
elif [ "$CURSOR" -gt "1920" ]; then
X=$(( $X + 1921 )) # Second monitor
fi
WMCLASS=$(xprop -id $WID | grep WM_CLASS) # Fix windows
case "$WMCLASS" in
*"spotify"* | *"libreoffice"* | *"obs"*)
Y=$(( $Y + $eD ))
;;
*) ;;
esac
wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz
wmctrl -r :ACTIVE: -e 0,$X,$Y,$W,$H
exit 0
Top