While in this answer, the question was on how to (re-) arrange application specific windows into a grid, the edited version below rearranges all "normal" windows into a grid:
#!/usr/bin/env python3
import subprocess
import getpass
import sys
#--- set your preferences below: padding between windows, margin(s)
cols = int(sys.argv[1]); rows = int(sys.argv[2]); padding = 10; left_margin = 70; top_margin = 30
#---
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
def get_res():
xr = get("xrandr").split(); pos = xr.index("current")
return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
def check_window(w_id):
w_type = get("xprop -id "+w_id)
if " _NET_WM_WINDOW_TYPE_NORMAL" in w_type:
return True
else:
return False
# get resolution
res = get_res()
# define (calculate) the area to divide
area_h = res[0] - left_margin; area_v = res[1] - top_margin
# create a list of calculated coordinates
x_coords = [int(left_margin+area_h/cols*n) for n in range(cols)]
y_coords = [int(top_margin+area_v/rows*n) for n in range(rows)]
coords = sum([[(cx, cy) for cx in x_coords] for cy in y_coords], [])
# calculate the corresponding window size, given the padding, margins, columns and rows
w_size = [str(int(area_h/cols - padding)), str(int(area_v/rows - padding))]
# find windows of the application, identified by their pid
wlist = [w.split()[0] for w in get("wmctrl -lp").splitlines()]
w_list = [w for w in wlist if check_window(w) == True][:cols*rows]
print(w_list)
# remove possibly maximization, move the windows
for n, w in enumerate(w_list):
data = (",").join([str(item) for item in coords[n]])+","+(",").join(w_size)
cmd1 = "wmctrl -ir "+w+" -b remove,maximized_horz"
cmd2 = "wmctrl -ir "+w+" -b remove,maximized_vert"
cmd3 = "wmctrl -ir "+w+" -e 0,"+data
for cmd in [cmd1, cmd2, cmd3]:
subprocess.Popen(["/bin/bash", "-c", cmd])
How to use
Make sure wmctrl is installed:
sudo apt-get install wmctrl
Copy the script into an empty file, save it as rearrange_windows.py
In the head section of the script, set your prefered padding if you like:
#--- set your preferences below: padding between windows, margin(s)
cols = 3; rows = 2; padding = 10; left_margin = 70; top_margin = 30
#---
Due to some bugs in the use of (the combination of) Unity / wmctrl
, I would leave left_margin = 70; top_margin = 30
as it is.
Run it by the command:
python3 /path/to/rearrange_windows.py <cols> <rows>
e.g. :
python3 /path/to/rearrange_windows.py 3 2
to set a grid of 3 collums / 2 rows of windows.
If all works as expected, add it to a shortcut key: Choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command:
python3 /path/to/rearrange_windows.py <cols> <rows>
If you'd like to use different grids (cols/rows), just create several shortcuts with different grids.
Note
If the number of windows exceeds the number of (possible) windows in the grid, the script grids the four "oldest" windows.
Examples
python3 /path/to/rearrange_windows.py 3 2

python3 /path/to/rearrange_windows.py 2 3
