#!/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 C-S-A to "gridmacro 1"
# |---|---|---| Bind key C-S-Z to "gridmacro 2"
# | 1 | 2 | 3 | Bind key C-S-X to "gridmacro 3")
# |---|---|---|
# | 7 | 8 | 9 | (C~trl A~lt K~ey P~ad
# |---|---|---| W~in S~hift)
# | 4 | 5 | 6 |
# |---|---|---|
#
# Note: This is an experimental alternative version of the original
# grid window tile script with hotkeys, this however only
# takes 3 keys in, cycle through the 9 window placements
# on each section by saving position to a temporary file.
# Eg. Press once for pos1, twice for pos2 and so on.
# Ideally used with macro keys. ((Note still experimental)).
#
WNAME=$(xdotool getactivewindow getwindowname)
WID=$(xdotool getactivewindow)
if [ "$WNAME" == "Desktop" ]; then exit 3; fi
W=1920 # Desktop Width
H=1080 # Desktop Height
eM=24 # (Used for equal margin on all sides)
G=24 # Window Gap
L=$eM # Left Margin
T=$(( $eM + 31 )) # 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
DFILE="/tmp/gridmacro.tmp"
MACRO=$1
SELECT=0
DATA=`cat $DFILE`
if [[ -z "$DATA" ]]; then echo "1|1|1" > "$DFILE" && DATA="1|1|1"; fi
D1=`echo $DATA|cut -d'|' -f1`
D2=`echo $DATA|cut -d'|' -f2`
D3=`echo $DATA|cut -d'|' -f3`
case "$MACRO" in # Window Left,Top,Width,Height
1) SELECT="$D1"
case "$SELECT" in # (gridmacro 1)
1) X=$(( $L )) && Y=$(( $T )) # top left (1/6)
W=$(( $W / 3 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
2) X=$(( $W / 3 + $L + $G )) && Y=$(( $T )) # top center (1/6)
W=$(( $W / 3 - $G * 2 - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
3) X=$(( $W / 3 * 2 + $L + $G )) && Y=$(( $T )) # top right (1/6)
W=$(( $W / 3 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
7) X=$(( $L )) && Y=$(( $T )) # left (1/3)
W=$(( $W / 3 - $G - $M )) && H=$(( $H - $D - $M )) ;;
8) X=$(( $W / 3 + $L + $G )) && Y=$(( $T )) # center (1/3)
W=$(( $W / 3 - $G * 2 - $M )) && H=$(( $H - $D - $M )) ;;
9) X=$(( $W / 3 * 2 + $L + $G )) && Y=$(( $T )) # right (1/3)
W=$(( $W / 3 - $G - $M )) && H=$(( $H - $D - $M )) ;;
4) X=$(( $L )) && Y=$(( $H / 2 + $T + $G )) # bottom left (1/6)
W=$(( $W / 3 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
5) 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 )) ;;
6) 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
D1=$(( $D1 + 1 )); if [ $D1 -gt 9 ]; then D1=1; fi
D2=1 && D3=1
;;
2) SELECT="$D2"
case "$SELECT" in # (gridmacro 2)
1) X=$(( $L )) && Y=$(( $T )) # top left (1/4)
W=$(( $W / 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
2) X=$(( $L )) && Y=$(( $T )) # top (1/2)
W=$(( $W - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
3) X=$(( $W / 2 + $L + $G )) && Y=$(( $T )) # top right (1/4)
W=$(( $W / 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
7) X=$(( $L )) && Y=$(( $T )) # left (1/2)
W=$(( $W / 2 - $G - $M )) && H=$(( $H - $D - $M )) ;;
8) X=$(( $L )) && Y=$(( $T )) # center (1/1)
W=$(( $W - $M )) && H=$(( $H - $D - $M )) ;;
9) X=$(( $W / 2 + $L + $G )) && Y=$(( $T )) # right (1/2)
W=$(( $W / 2 - $G - $M )) && H=$(( $H - $D - $M )) ;;
4) X=$(( $L )) && Y=$(( $H / 2 + $T + $G )) # bottom left (1/4)
W=$(( $W / 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
5) X=$(( $L )) && Y=$(( $H / 2 + $T + $G )) # bottom (1/2)
W=$(( $W - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
6) 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
D2=$(( $D2 + 1 )); if [ $D2 -gt 9 ]; then D2=1; fi
D1=1 && D3=1
;;
3) SELECT="$D3"
case "$SELECT" in # (gridmacro 3)
1) X=$(( $L )) && Y=$(( $T )) # top left (1/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
2) X=$(( $W / 3 / 2 + $L )) && Y=$(( $T )) # top (1/2)
W=$(( $W / 3 * 2 - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
3) X=$(( $W / 3 + $L + $G )) && Y=$(( $T )) # top right (1/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
7) X=$(( $L )) && Y=$(( $T )) # left (2/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H - $D - $M )) ;;
8) X=$(( $L + $W / 10 )) && Y=$(( $T + $H / 10 )) # center (1/1)
W=$(( $W - $W / 5 - $M )) && H=$(( $H - $H / 5 - $D - $M )) ;;
9) X=$(( $W / 3 + $L + $G )) && Y=$(( $T )) # right (2/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H - $D - $M )) ;;
4) X=$(( $L )) && Y=$(( $H / 2 + $T + $G )) # bottom left (1/3)
W=$(( $W / 3 * 2 - $G - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
5) X=$(( $W / 3 / 2 + $L )) && Y=$(( $H / 2 + $T + $G )) # bottom (1/2)
W=$(( $W / 3 * 2 - $M )) && H=$(( $H / 2 - $G - $D - $M )) ;;
6) 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
D3=$(( $D3 + 1 )); if [ $D3 -gt 9 ]; then D3=1; fi
D1=1 && D2=1
;;
*) exit 1 ;;
esac
echo "$D1|$D2|$D3" > "$DFILE"
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