How can I automatically add workspaces, only if I need them?

kernel_panic

Assume I am using 4 workspaces and I incidentally need more, is there an automated process or, if impossible, an easy way to incidentally add more workspaces (instead of installing Ubuntu tweak etc. etc.).

Jacob Vlijm

Automatically set the number of workspaces; add and remove columns and rows, depending on your needs

Below a version of a (the) backround script that will automatically add workspaces if you entered the last column or row of your workspace-matrix.

This is how it works:

  1. If you arrive at the last column or row, additional viewports are added:

    enter image description here

  2. If your workspaces are unused for 5-10 seconds and there are no windows on it, the additional workspaces will be removed again. You will however always keep one extra row below, and one extra column right of your current viewport:

    enter image description here

The script:

#!/usr/bin/env python3
import subprocess
import time
import math

# --- set default workspaces below (horizontally, vertically)
hsize = 2
vsize = 2
# --- set the maximum number of workspaces below
max_ws = 10

def set_workspaces(size, axis):
    subprocess.Popen([
        "dconf", "write", "/org/compiz/profiles/unity/plugins/core/"+axis,
                str(size)
                ])

def get_res():
    resdata = subprocess.check_output(["xrandr"]).decode("utf-8").split()
    curr = resdata.index("current")
    return (int(resdata[curr+1]), int(resdata[curr+3].replace(",", "")))

def wspace():
    try:
        sp = subprocess.check_output(["wmctrl", "-d"]).decode("utf-8").split()
        return ([int(n) for n in sp[3].split("x")],
                [int(n) for n in sp[5].split(",")])

    except subprocess.CalledProcessError:
        pass


def clean_up(curr_col, curr_row):
    try:
        w_list = [l.split() for l in subprocess.check_output(["wmctrl", "-lG"]).decode("utf-8").splitlines()]
        xpos = max([math.ceil((int(w[2])+span[1][0])/res[0]) for w in w_list])
        min_x = max(xpos, curr_col+1, hsize)
        if xpos >= hsize:
            set_workspaces(min_x, "hsize")
        else:
            set_workspaces(min_x, "hsize")
        ypos = max([math.ceil((int(w[3])+span[1][1])/res[1]) for w in w_list])
        min_y = max(ypos, curr_row+1, vsize)
        if ypos >= vsize:
            set_workspaces(min_y, "vsize")
        else:
            set_workspaces(min_y, "vsize")
    except subprocess.CalledProcessError:
        pass

res = get_res()
t = 0

while True:
    span = wspace()
    if span != None:
        cols = int(span[0][0]/res[0]); rows = int(span[0][1]/res[1])
        currcol = int((span[1][0]+res[0])/res[0])
        if all([currcol == cols, cols*rows < max_ws]):
            set_workspaces(cols+1, "hsize")
        currrow = int((span[1][1]+res[1])/res[1])
        if all([currrow == rows, cols*rows < max_ws]):
            set_workspaces(rows+1, "vsize")
        if t == 10:
            clean_up(currcol, currrow)
            t = 0
        else:
            t = t+1
        time.sleep(1)

How to use

  1. Copy the script below into an empty file, save it as add_space.py
  2. In the head section of the script, edit the lines if you like other settings (maximum number of workspaces, default matrix e.g. 2x2):

    # --- set default workspaces below (horizontally, vertically)
    hsize = 2
    vsize = 2
    # --- set the maximum number of workspaces below
    max_ws = 10
    
  3. Test- run it by the command:

    python3 /path/to/add_space.py
    
  4. If all works fine, add it to your startup applications: Dash > Startup Applications > Add the command:

    /bin/bash -c "sleep 15 &&  python3 /path/to/add_space.py`
    

Note

As always, the script is extremely "low on juice", and does not add any noticeable load to your processor.

Explanation

The story below is a bit complicated and mostly an explanation on the concept and the procedure, rather than the coding. Only read if you're interested.

How to calculate the needed workspaces (example columns)

The output of wmctrl -d looks like:

0  * DG: 3360x2100  VP: 1680,1050  WA: 65,24 1615x1026  N/A

In the output, VP: 1680,1050 gives us information on where we are on the spanning workspace (the matrix of all viewports). This information is only useful if we also have the screen's resolution, since e.g. 1680 could be the width of two (unlikely, but still) or one time the screen.
Luckily, we can parse out the screen's resolution from the command xrandr.

Then if we know the screen's x-size is 1680 and we currently are on VP: 1680,1050, we know we are on the second column in the workspace's matrix. Since we also know the size of the total matrix (DG: 3360x2100, also from the output of wmctrl -d), we know the current matrix includes two columns (3360/1680), and we are on the "last" one.

enter image description here

The script will then send an instruction to add a column to the matrix by the command:

dconf write /org/compiz/profiles/unity/plugins/core/hsize <current_viewport_column+1>

This is the principle.

How to calculate the workspaces to remove (example columns)

Once per 10 seconds, the script runs the command to list all currently opened windows, with the command:

wmctrl -lG

This gives us information on the window's position also, looking like:

0x04604837  0 3425 24   1615 1026 jacob-System-Product-Name Niet-opgeslagen document 2 - gedit

In the output, 3425 is the x-position of the window. This figure is however relative to the current workspace (left side). To know the absolute position of the window (x-wise) in the workspace-matrix, we have to add the first number of the current viewport information (e.g. VP: 1680,1050, from the output of wmctrl -d).
Let's however, for simplicity reasons, assume we are on viewport 1,1 (topleft viewport), so the window's relative position equals its absolute position.

Since the screen's resolution is 1680, we know the window is on column 3425/1680, rounded up, since everything between 3360 and 5040 is on the same column in the matrix (between 3 and 4 times the resolution). For proper calculation we use math.ceil() (python)

Since the script also practices the rule to always have an extra workspace on the right/below, we need to set the number of columns to the highest value of:

  • the current workspace column + 1
  • the last column with a window on it
  • the default number of columns, as set in the head of the script

And so the script does :)

The rows are managed in exactly the same procedure.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How can I have more than 9 workspaces in xmonad?

From Dev

How can I replace generators if I need only one result?

From Dev

How can I run containers detached and have them automatically removed when they exit?

From Dev

How can i only show the header on some pages and not all of them

From Dev

How can I add the compilation date to java project automatically

From Dev

How can I automatically add a class to a link based on active anchor?

From Dev

How can I sort multiple mysql foreach arrays and need them in consistent in php?

From Dev

How can I add strings and print them?

From Dev

I Need to add items to array, not replace them

From Dev

How can I add workspaces (tabs groups) to PhpStorm?

From Dev

How can I find rows that have only 2 _ in them with Postgres?

From Dev

How can I rotate the elements and only show 4 of them?

From Dev

How can I automatically add the blogpost author into the member list?

From Dev

How can I test for plugins and only include them if they exist in .vimrc?

From Dev

How can I create a shortcut to cycle through workspaces in GNOME 3?

From Dev

How can I assign redundant shortcuts for switching workspaces in GNOME 3?

From Dev

How can I bind a key to cycle between workspaces?

From Dev

Do I need fragments and how to access them?

From Dev

How can I get only the specific H3 I am hovering over to show and not all of them?

From Dev

I have a txt file of only file locations and I need to find the size of each file then add them up using powershell

From Dev

How can I prevent Google Hangouts from opening on all workspaces?

From Dev

How can I find only the catalogs and sort them by size

From Dev

How can I get data from XML [2 identical children and I want only 1 of them]?

From Dev

How can I disable workspaces for external monitor?

From Dev

How can I reduce or increase the number of workspaces in Unity?

From Dev

How do I convert an MKV file to MP4 that has two audio streams and I only need one of them with ffmpeg?

From Dev

How can I stop workspaces from switching automatically to other workspaces when selecting different applications?

From Dev

Android how can I get coordinates and add it to link automatically

From Dev

Workspace Grid extension : how can I rename or remove the workspaces names?

Related Related

  1. 1

    How can I have more than 9 workspaces in xmonad?

  2. 2

    How can I replace generators if I need only one result?

  3. 3

    How can I run containers detached and have them automatically removed when they exit?

  4. 4

    How can i only show the header on some pages and not all of them

  5. 5

    How can I add the compilation date to java project automatically

  6. 6

    How can I automatically add a class to a link based on active anchor?

  7. 7

    How can I sort multiple mysql foreach arrays and need them in consistent in php?

  8. 8

    How can I add strings and print them?

  9. 9

    I Need to add items to array, not replace them

  10. 10

    How can I add workspaces (tabs groups) to PhpStorm?

  11. 11

    How can I find rows that have only 2 _ in them with Postgres?

  12. 12

    How can I rotate the elements and only show 4 of them?

  13. 13

    How can I automatically add the blogpost author into the member list?

  14. 14

    How can I test for plugins and only include them if they exist in .vimrc?

  15. 15

    How can I create a shortcut to cycle through workspaces in GNOME 3?

  16. 16

    How can I assign redundant shortcuts for switching workspaces in GNOME 3?

  17. 17

    How can I bind a key to cycle between workspaces?

  18. 18

    Do I need fragments and how to access them?

  19. 19

    How can I get only the specific H3 I am hovering over to show and not all of them?

  20. 20

    I have a txt file of only file locations and I need to find the size of each file then add them up using powershell

  21. 21

    How can I prevent Google Hangouts from opening on all workspaces?

  22. 22

    How can I find only the catalogs and sort them by size

  23. 23

    How can I get data from XML [2 identical children and I want only 1 of them]?

  24. 24

    How can I disable workspaces for external monitor?

  25. 25

    How can I reduce or increase the number of workspaces in Unity?

  26. 26

    How do I convert an MKV file to MP4 that has two audio streams and I only need one of them with ffmpeg?

  27. 27

    How can I stop workspaces from switching automatically to other workspaces when selecting different applications?

  28. 28

    Android how can I get coordinates and add it to link automatically

  29. 29

    Workspace Grid extension : how can I rename or remove the workspaces names?

HotTag

Archive