How to make equally sized windows in corners of the screen?

Solution 1:

Gnome Shell can be changed using Gnome Extensions - I think this extension will work for you:

This is done by dragging and dropping the windows into position, it will show a orange highlight (doesn't seem to match the theme :/ ). You can change the gap between windows in the settings:

enter image description here

Though currently this extension is not available for GNOME 3.18, so you will have to give this workaround a go.

Solution 2:

On the edge of posting a duplicate of this one (but the question slightly differs), the script below does what you describe, if you run it with the arguments

python3 /path/to/script.py 2 2

However, if there are more than four windows (or more than the cells of a grid, if you use other arguments than 2 2), the script places only the four oldest windows in the grid.

What it does

When four windows are opened, randomly placed on the screen:

enter image description here

running the script will arrange them in a grid:

enter image description here

The script

#!/usr/bin/env python3
import subprocess
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 = 0; 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

  1. The script needs both xdotool and wmctrl:

    sudo apt-get install xdotool wmctrl
    
  2. Copy the script into an empty file, save it as twobytwo.py

  3. Test- run it by opening four windows (at least one terminal window to run the command), the run the command:

    python3 /path/to/twobytwo.py 2 2
    

    The windows should move into a grid of 4, as in the second image

  4. If all works fine, add it to a shortcut key: choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command:

    python3 /path/to/twobytwo.py 2 2
    

Note(s)

  • in the head section, there is a section:

    left_margin = 0
    

    I set this to zero, since gnome does not have the launcher on the left. For Unity, this should be (at least) 65, depending on the set width of the launcher.

  • As mentioned, the script, as it is, grids the four oldest windows. That means if you need more windows to be placed in the same grid, the script needs an edit. Please mention if so.