Tiling XFCE windows with shortcut keys

Here are some shell scripts to help arrange windows without having to drag them with the mouse.

The scripts use xdotool and wmctrl to move and resize windows, the scripts work with multiple monitors as long as they have a similar size screen.

If you want to use different size screens, you are probably has to design a function to calculate the correct x-axis offset.

I made the scripts using 1920x1080 resolution, higher or lower resolutions might need to tweak some values.

shell scripts

top_left_windows.sh
#!/bin/bash

window=$(printf '0x0%x' $(xdotool getwindowfocus))
x_pos=($(wmctrl -l -G | grep $window | awk '{print $3; }'))
y_pos=($(wmctrl -l -G | grep $window | awk '{print $4; }'))
x_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $1; }'))
y_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $2; }'))
offset=$(((x_pos / x_size) * x_size))

new_x_size=$((($x_size / 2) * 95 / 100))
new_y_size=$((($y_size / 2) * 86 / 100))
new_x_pos=$(($x_size * 2 / 100 + $offset))
new_y_pos=$(($y_size * 2 / 100))

wmctrl -i -r $window -b remove,maximized_horz,maximized_vert
wmctrl -i -r $window -e 0,$new_x_pos,$new_y_pos,$new_x_size,$new_y_size
top_right_window.sh
#!/bin/bash

window=$(printf '0x0%x' $(xdotool getwindowfocus))
x_pos=($(wmctrl -l -G | grep $window | awk '{print $3; }'))
y_pos=($(wmctrl -l -G | grep $window | awk '{print $4; }'))
x_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $1; }'))
y_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $2; }'))
offset=$(((x_pos / x_size) * x_size))

new_x_size=$((($x_size / 2) * 95 / 100))
new_y_size=$((($y_size / 2) * 86 / 100))
new_x_pos=$((($x_size / 2) + ($x_size * 1 / 100) + $offset))
new_y_pos=$(($y_size * 2 / 100))

wmctrl -i -r $window -b remove,maximized_horz,maximized_vert
wmctrl -i -r $window -e 0,$new_x_pos,$new_y_pos,$new_x_size,$new_y_size
bottom_left_window.sh
#!/bin/bash

window=$(printf '0x0%x' $(xdotool getwindowfocus))
x_pos=($(wmctrl -l -G | grep $window | awk '{print $3; }'))
y_pos=($(wmctrl -l -G | grep $window | awk '{print $4; }'))
x_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $1; }'))
y_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $2; }'))
offset=$(((x_pos / x_size) * x_size))

new_x_size=$((($x_size / 2) * 95 / 100))
new_y_size=$((($y_size / 2) * 86 / 100))
new_x_pos=$(($x_size * 2 / 100 + $offset))
new_y_pos=$((($y_size / 2) + ($y_size * 2 / 100)))

wmctrl -i -r $window -b remove,maximized_horz,maximized_vert
wmctrl -i -r $window -e 0,$new_x_pos,$new_y_pos,$new_x_size,$new_y_size
bottom_right_window.sh

#!/bin/bash

window=$(printf '0x0%x' $(xdotool getwindowfocus))
x_pos=($(wmctrl -l -G | grep $window | awk '{print $3; }'))
y_pos=($(wmctrl -l -G | grep $window | awk '{print $4; }'))
x_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $1; }'))
y_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $2; }'))
offset=$(((x_pos / x_size) * x_size))

new_x_size=$((($x_size / 2) * 95 / 100))
new_y_size=$((($y_size / 2) * 86 / 100))
new_x_pos=$((($x_size / 2) + ($x_size * 1 / 100) + $offset))
new_y_pos=$((($y_size / 2) + ($y_size * 2 / 100)))

wmctrl -i -r $window -b remove,maximized_horz,maximized_vert
wmctrl -i -r $window -e 0,$new_x_pos,$new_y_pos,$new_x_size,$new_y_size
top_windows.sh
#!/bin/bash

window=$(printf '0x0%x' $(xdotool getwindowfocus))
x_pos=($(wmctrl -l -G | grep $window | awk '{print $3; }'))
y_pos=($(wmctrl -l -G | grep $window | awk '{print $4; }'))
x_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $1; }'))
y_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $2; }'))
offset=$(((x_pos / x_size) * x_size))

new_x_size=$(($x_size * 97 / 100))
new_y_size=$((($y_size / 2) * 86 / 100))
new_x_pos=$(($x_size * 2 / 100  + $offset))
new_y_pos=$(($y_size * 2 / 100))

wmctrl -i -r $window -b remove,maximized_horz,maximized_vert
wmctrl -i -r $window -e 0,$new_x_pos,$new_y_pos,$new_x_size,$new_y_size
bottom_window.sh

#!/bin/bash

window=$(printf '0x0%x' $(xdotool getwindowfocus))
x_pos=($(wmctrl -l -G | grep $window | awk '{print $3; }'))
y_pos=($(wmctrl -l -G | grep $window | awk '{print $4; }'))
x_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $1; }'))
y_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $2; }'))
offset=$(((x_pos / x_size) * x_size))

new_x_size=$(($x_size * 97 / 100))
new_y_size=$((($y_size / 2) * 86 / 100))
new_x_pos=$(($x_size * 2 / 100 + $offset))
new_y_pos=$((($y_size / 2) + ($y_size * 2 / 100)))

wmctrl -i -r $window -b remove,maximized_horz,maximized_vert
wmctrl -i -r $window -e 0,$new_x_pos,$new_y_pos,$new_x_size,$new_y_size
left_windows.sh
#!/bin/bash

window=$(printf '0x0%x' $(xdotool getwindowfocus))
x_pos=($(wmctrl -l -G | grep $window | awk '{print $3; }'))
y_pos=($(wmctrl -l -G | grep $window | awk '{print $4; }'))
x_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $1; }'))
y_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $2; }'))
offset=$(((x_pos / x_size) * x_size))

new_x_size=$((($x_size / 2) * 95 / 100))
new_y_size=$(($y_size * 93 / 100 ))
new_x_pos=$(($x_size * 2 / 100 + $offset))
new_y_pos=$(($y_size * 2 / 100))

wmctrl -i -r $window -b remove,maximized_horz,maximized_vert
wmctrl -i -r $window -e 0,$new_x_pos,$new_y_pos,$new_x_size,$new_y_size
right_windows.sh
#!/bin/bash

window=$(printf '0x0%x' $(xdotool getwindowfocus))
x_pos=($(wmctrl -l -G | grep $window | awk '{print $3; }'))
y_pos=($(wmctrl -l -G | grep $window | awk '{print $4; }'))
x_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $1; }'))
y_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $2; }'))
offset=$(((x_pos / x_size) * x_size))

new_x_size=$((($x_size / 2) * 95 / 100))
new_y_size=$(($y_size * 93 / 100 ))
new_x_pos=$((($x_size / 2) + ($x_size * 1 / 100) + $offset))
new_y_pos=$(($y_size * 2 / 100))

wmctrl -i -r $window -b remove,maximized_horz,maximized_vert
wmctrl -i -r $window -e 0,$new_x_pos,$new_y_pos,$new_x_size,$new_y_size
center_window.sh

#!/bin/bash

window=$(printf '0x0%x' $(xdotool getwindowfocus))
x_pos=($(wmctrl -l -G | grep $window | awk '{print $3; }'))
y_pos=($(wmctrl -l -G | grep $window | awk '{print $4; }'))
x_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $1; }'))
y_size=($(xdotool getwindowfocus getdisplaygeometry | awk '{print $2; }'))
offset=$(((x_pos / x_size) * x_size))

new_x_size=$(($x_size * 90 / 100))
new_y_size=$(($y_size * 80 / 100))
new_x_pos=$(($x_size * 5 / 100 + offset))
new_y_pos=$(($y_size * 10 / 100))

wmctrl -i -r $window -b remove,maximized_horz,maximized_vert
wmctrl -i -r $window -e 0,$new_x_pos,$new_y_pos,$new_x_size,$new_y_size

Key binds
You just bind the shell scripts using the XFCE keyboard menu. You can bind the shortcuts as you like, I use the super/windows key for the shortcuts.

super+q : top-left
super+w: top
super+e: top-right
super+a: left
super+s: center
super+d: right
super+z: bottom-left
super+x: bottom
super+c: bottom-rigth

Screenshots

2 Likes

Do you need the shell scripts? afaik the xfce4 window manager already offers tiling positions. You just need to assign key presses to them from the window manager settings.

1 Like