2

Using Ubuntu 14.04, I'm looking into getting a 40" 4k display and have found how to resize windows down to quarter sections of the screen, but I would like the ability to further resize them down if desired. For instance, I would like to keybind the default compiz to take a full screen window and put it in the top left quarter of the screen, but if pressed again, further downsize it to the top left eighth of the screen, or to put the window in the bottom right quarter of the top quarter of the screen (taking up an eighth vertically and horizontally of the screen). Is this functionality hidden within compiz or any other application that I'm not familiar with?

2

The script below can be used as an additional functionality to the "resize-to-quarter" option in 14.04. It can be run with the arguments: "left", "right", "up", "down", to further cut the quarter in eights.

What it does

If you have your window moved to the quarter of your screen:

enter image description here

the script will cut the window in half, either the left, right, top or bottom half, depending on the argument you run it with (see below).

How to use

  • The script uses wmctrl, which is not by default on your system:

    sudo apt-get install wmctrl
    
  • Copy the script below into an empty file, save it as organize_w in the directory ~/bin. Make the script executable. Probably you will still have to create the directory ~/bin. It has the advantage that you can run the script just by the script's name:

  • Add four commands to custom keyboard shortcuts. Open system settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Add four commands to key combinations.
    On my system, I found four extremely fit shortcuts still available: I would suggest adding the commands under these key combinations:

    organize_w left 
    

    Shift+Ctrl+Numpad <

    effect:

    enter image description here

    organize_w right 
    

    Shift+Ctrl+Numpad >

    effect:

    enter image description here

    organize_w up 
    

    Shift+Ctrl+Numpad ^

    effect:

    enter image description here

    organize_w down 
    

    Shift+Ctrl +Numpad v

    effect:

    enter image description here

    This way, you can arrange windows like below with a few key strokes:

  • enter image description here

The script:

#!/usr/bin/env python3
import subprocess
import sys

arg = sys.argv[1]
WA_correction = 28

def get(command):
    return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

def execute(command):
    subprocess.Popen(["/bin/bash", "-c", command])

xprop_data = get("xprop -root").split()
w_id = xprop_data[xprop_data.index("_NET_ACTIVE_WINDOW(WINDOW):")+4].replace(",", "")
frontmost = w_id[:2]+"0"+w_id[2:]
w_data = [l for l in get("wmctrl -lG").splitlines() if frontmost in l][0].split()
new_G = w_data[2:6]
new_G[1] = str(int(int(new_G[1])-WA_correction))
xy_corr = lambda x: -10 if int(x) < 100 else 0
if arg == "left":
    new_G[2] = str(int(int(new_G[2])/2 + xy_corr(new_G[0])))
    new_G[3] = str(int(int(new_G[3]) + xy_corr(new_G[1])))            
elif arg == "right":
    new_G[0] = str(int(int(new_G[0])+int(new_G[2])/2))    
    new_G[2] = str(int(int(new_G[2])/2))
    new_G[3] = str(int(int(new_G[3]) + xy_corr(new_G[1])))
elif arg == "up":
    new_G[2] = str(int(new_G[2]) + xy_corr(new_G[0]))
    new_G[3] = str(int(int(new_G[3])/2 + xy_corr(new_G[1])))
elif arg == "down":
    new_G[1] = str(int(int(new_G[1]) + int(new_G[3])/2))
    new_G[2] = str(int(new_G[2]) + xy_corr(new_G[0]))
    new_G[3] = str(int(int(new_G[3])/2))

execute("wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz")
execute("wmctrl -ir "+frontmost+" -e 0,"+(",").join(new_G))



edit:

XFCE version

With a few minor changes, the script can also be used to resize wndows into half / quarter or eight on XFCE (tested on 14.04).

Use it exactly like the version for Unity:

#!/usr/bin/env python3
import subprocess
import sys

arg = sys.argv[1]
WA_correction = 48

def get(command):
    return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

def execute(command):
    subprocess.Popen(["/bin/bash", "-c", command])

xprop_data = get("xprop -root").split()
w_id = xprop_data[xprop_data.index("_NET_ACTIVE_WINDOW(WINDOW):")+4].replace(",", "")
frontmost = w_id[:2]+"0"+w_id[2:]
w_data = [l for l in get("wmctrl -lG").splitlines() if frontmost in l][0].split()
new_G = w_data[2:6]
new_G[1] = str(int(int(new_G[1])-WA_correction))
if arg == "left":
    new_G[2] = str(int(int(new_G[2])/2))      
elif arg == "right":
    new_G[0] = str(int(int(new_G[0])+int(new_G[2])/2))    
    new_G[2] = str(int(int(new_G[2])/2))
elif arg == "up":
    new_G[3] = str(int(int(new_G[3])/2))
elif arg == "down":
    new_G[1] = str(int(int(new_G[1]) + int(new_G[3])/2))
    new_G[3] = str(int(int(new_G[3])/2))

execute("wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz")
execute("wmctrl -ir "+frontmost+" -e 0,"+(",").join(new_G))

(XFCE version also posted on gist.gisthub)

  • Nice! I'll have to play with the script to get the windows a little more exact, but this is exactly what I was looking for! – Travis Jan 23 '15 at 4:01
  • @th01 improved the geometry, should be totally consistent now. There are small differences in how different applications interprete the geometry rules however (especially in window height), but I noticed this is also seen in how Unity itself behaves in window resizing. – Jacob Vlijm Jan 23 '15 at 10:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.