1

This answer does not answer my question:.

I want to resize two or more windows automatically, so that they occupy the a share of the whole screen, side by side. That is, 2 windows that occupy 1/2, 3 that occupy 1/3 each and so on.

I can do it manually right now, but just resizing windows with the keyboard individually is time consuming. For example, ctrl + Super + arrow and left/right/up/ down for each window. However, that would force me to go window by window resizing them.

1 Answers1

1

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 

enter image description here

python3 /path/to/rearrange_windows.py 2 3

enter image description here

Jacob Vlijm
  • 85,475