20

I read through the various answers to having separate desktop folders in each Workspace using Screenlets, devilspie, or CCSM ... but that's not the answer to my question. I installed 14.04 LTS a few days ago and have had good success getting most of my apps and some new ones to run. What I would like is to have 4 separate workspaces, each with some different icons for the environments I run. For example,

  • Workspace 1 – dedicated to science and math apps
  • Workspace 2 – dedicated to music tools
  • Workspace 3 – for electronic circuits and simulations
  • Workspace 4 – for web browsing and general computing

Think of an Android tablet where each screen can contain separate icons.

It must be obvious how to do this, but I can't find an answer. I am 4 days old on Ubuntu, so please don't assume I know what I'm doing!

10
  • You mean a different set of launcher icons per workspace? Yummy I like that, but I have to run, will work on it tomorrow if that is what you mean. Please let me know. Apr 10, 2015 at 14:20
  • Yes, that's it Jacob. There are specific tools (like LTspice) for circuit simulation that have no relevance for music.
    – Dennis J
    Apr 10, 2015 at 14:28
  • Can be done without a doubt. Probably tomorrow or SUnday :). Apr 10, 2015 at 14:33
  • Thank you Jacob. Just getting started for the day, so I will give it a try. This sounds exactly like what I asked for!!! I'll get into it and report back.
    – Dennis J
    Apr 13, 2015 at 10:46
  • Jacob, I have not started this yet. Before I begin, I want to make a backup image. I'm not sure that Backups in System Settings will restore the entire partition. Have been researching Clonezilla, looks like a good tool to create/restore an image. That way if something goes wrong, I can get back to before I messed it up. There's a new 1TB drive on its way this week. I'll need to use Clonezilla to move the system to it. The scripts look like I can follow them, and I will report back as soon as I get going. Thanks for the followup, I bet others will appreciate what you've done as well.
    – Dennis J
    Apr 14, 2015 at 13:58

1 Answer 1

24
+500

Setting a different Unity Launcher per workspace:


1. enter image description here 2. enter image description here 3. enter image description here 4. enter image description here

The solution below makes it easily possible to have a different set of launcher icons per workspace, no matter how many workspaces you have.

The setup includes two parts:

  1. A (one) shortcut key combination to "remember" the set of launcher icons for the current workspace.

  2. A script to run in the background, keeping track of what is the current workspace and setting the corresponding Unity Launcher. It acts whenever the user switches workspace.

How it works

Two small scripts are involved:

The first script does one simple thing: it writes the contents of the current launcher into a (hidden) file in your home directory, named (numbered) after your current workspace.

The second script keeps an eye on what is the current workspace. If there is a workspace change, the script sees if a corresponding (launcher-) datafile exists (created by the first script). If so, it reads the file and alters the Unity Launcher, as remembered in the file.

That's it.

How to set up

  1. The script needs wmctrl to be installed:

    sudo apt-get install wmctrl
    
  2. Create a directory in which both scripts will be stored. It is importants that both scripts are kept together in one directory, since they share functionality and one imports from the other. For the same reason, it is important that you name them exactly as indicated below.

  3. Copy each of the scripts below into a (different) empty file, save them into the directory (created in 2.), exactly named as:

    set_workspace.py

    #!/usr/bin/env python3
    import subprocess    
    import os
    
    workspace_data = os.environ["HOME"]+"/.launcher_data_"
    key = ["gsettings get ", "gsettings set ", "com.canonical.Unity.Launcher favorites"]
    
    def get_res():
        # get resolution
        xr = subprocess.check_output(["xrandr"]).decode("utf-8").split()
        pos = xr.index("current")
        return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
    
    def current():
        # get the current viewport
        res = get_res()
        vp_data = subprocess.check_output(["wmctrl", "-d"]).decode("utf-8").split()
        dt = [int(n) for n in vp_data[3].split("x")]
        cols = int(dt[0]/res[0])
        curr_vpdata = [int(n) for n in vp_data[5].split(",")]
        curr_col = int(curr_vpdata[0]/res[0])+1; curr_row = int(curr_vpdata[1]/res[1])
        return str(curr_col+curr_row*cols)
    
    def remember_current():  
        currlauncher = subprocess.check_output(["/bin/bash", "-c", key[0]+key[2]]).decode("utf-8").strip()
        f = workspace_data+current()
        open(f, "w").write(currlauncher)
    
    if __name__ == "__main__":
        remember_current()
    

    launcher_perworkspace.py

    #!/usr/bin/env python3
    import subprocess
    import set_workspace
    import time
    
    workspace_data = set_workspace.workspace_data
    key = set_workspace.key
    
    def check_datafile(desktop):
        f = workspace_data+str(desktop)
        try:
            new_launcher = open(f).read()
            command = key[1]+key[2]+' "'+str(new_launcher)+'"'
            subprocess.Popen(["/bin/bash", "-c", command])
        except FileNotFoundError:
            pass
    
    curr_dt1 = set_workspace.current()
    check_datafile(curr_dt1)
    
    while True:
        time.sleep(1)
        curr_dt2 = set_workspace.current()
        if curr_dt2 != curr_dt1:
            check_datafile(curr_dt2)
        curr_dt1 = curr_dt2
    
  4. Add the first script (set_workspace.py) to a shortcut key combination of your choice: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command:

    python3 /path/to/set_workspace.py
    
  5. Run the key combination and see if a file, like: .launcher_data_3 is created in your home directory. You will probably need to press Ctrl+H to make the file visible (files, starting with a . are invisible by default).

    Navigate through your workspaces and repeat the procedure: set a combination of launcher icons, and press your key combination to "remember" the set for that specific workspace.

  6. You're practically done now. Test-run the background script with the command (from a terminal window, keep it running):

    python3 /path/to/launcher_perworkspace.py
    

    If all works fine, and your launcher switches per workspace, add the following command to your Startup applications: Dash > Startup Applications > Add:

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

Notes

  1. If you want to alter the set of launcher icons for a specific workspace, simply navigate to the workspace, add/remove icons as you like and press your key combinbation (no need to restart the background script).
  2. From the comment(s) I get the feeling there is some misunderstanding on the shortcut to remember the current Launcher for the current workspace. You only need one keyboard shortcut to "save" the current launcher for the current workspace. It will work exactly the same, no matter what workspace you are on. The script itself will determine what is the current workspace.

Edit

From your comment, I understand that you are unsure to run the script(s) and you are afraid you will mess up your current launcher.

I am pretty sure that is too much (or too little :)) respect for what the script is doing. However, you can simply backup yor current Unity Launcher with the command:

printf 'gsettings set com.canonical.Unity.Launcher favorites "' > ~/launcher_output&&printf "$(gsettings get com.canonical.Unity.Launcher favorites)">>~/launcher_output&&printf '"'>>~/launcher_output

This will create a file ~/launcher_output, containing the complete command to restore your Unity Launcher to the initial situation. In case of emergency, simply copy the file's content and paste it in the terminal.

But again, it is really unlikely you will mess up your launcher, unless you change the script manually.


IMPORTANT EDIT (2)

As requested in a comment, hereby a version that runs without having to use any shortcut combination; just run the script and start setting up your launchers on the specific workspaces. The script will create (invisible) files in your home directory, to remember your set of (Unity-) launchers on the different workspaces.

I tried this in "version 1" of the script, but always "embedding" the two launcher-checks between two workspace-checks turned out to be the trick to prevent unwanted behaviour (saving incorrect data) when moving quickly through the workspaces.

How to use

  1. Like the first version, this script uses wmctrl:

    sudo apt-get install wmctrl

  2. Copy the script into an empty file, save it as launcher_toworkspace.py

  3. Run it with the command:

    python3 /path/to/launcher_toworkspace.py
    
  4. If it works as expected, add the following command to your Startup Applications:

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

The script

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

datadir = os.environ["HOME"]+"/.config/lswitcher"
if not os.path.exists(datadir):
    os.makedirs(datadir)
workspace_data = datadir+"/launcher_data_"

key = [
    "gsettings get ",
    "gsettings set ",
    "com.canonical.Unity.Launcher favorites",
    ]

def get_launcher():
    return subprocess.check_output(
        ["/bin/bash", "-c", key[0]+key[2]]
        ).decode("utf-8").strip()

def get_res():
    # get resolution
    xr = subprocess.check_output(["xrandr"]).decode("utf-8").split()
    pos = xr.index("current")
    return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]

def current():
    # get the current viewport
    res = get_res()
    vp_data = subprocess.check_output(
        ["wmctrl", "-d"]
        ).decode("utf-8").split()
    dt = [int(n) for n in vp_data[3].split("x")]
    cols = int(dt[0]/res[0])
    curr_vpdata = [int(n) for n in vp_data[5].split(",")]
    curr_col = int(curr_vpdata[0]/res[0])+1
    curr_row = int(curr_vpdata[1]/res[1])
    return str(curr_col+curr_row*cols)

curr_ws1 = current()
currlauncher1 = get_launcher()

while True:
    time.sleep(1)
    currlauncher2 = get_launcher()
    curr_ws2 = current()
    datafile = workspace_data+curr_ws2
    if curr_ws2 == curr_ws1:
        if currlauncher2 != currlauncher1:
            open(datafile, "wt").write(currlauncher2)
    else:
        if not os.path.exists(datafile):
            open(datafile, "wt").write(currlauncher2)
        else:
            curr_set = open(datafile).read()
            command = key[1]+key[2]+' "'+str(curr_set)+'"'
            subprocess.Popen(["/bin/bash", "-c", command])
    curr_ws1 = curr_ws2
    currlauncher1 = get_launcher()

Note

If you set up your workspaces with the previous version of the script, they should also work for this version.

PPA

As per 2015-04-23, the nice question of Dennis J, and the encouragement of Parto, have lead to creating a ppa for the script, covered on webupd8, including a GUI to manage it.

ppa:vlijm/lswitcher

To install it, run:

sudo add-apt-repository ppa:vlijm/lswitcher
sudo apt-get update
sudo apt-get install lswitcher

enter image description here

Since now, it is packaged for Trusty & Utopic. I will add others after testing. I will also add a .deb installer, but I'd suggest using the ppa, since usually this kind of things is updated every now and then.

Since the location of the viewport data has changed from ~/ to ~/.config/lswitcher, you'll have to set up your Unity Launcher again if you used the previous script.

11
  • Is this possible without using the keyboard shortcuts? How I visualize it is as below: When in workspace one, only a set of icons are shown; when I switch to workspace two, the launcher is empty except the dash and trash icons - then I add the icons I want which are saved automatically. Repeat for the other workspaces. Maybe you can even create a GUI for it - will give you +500 if you make it work. The GUI is optional.
    – Parto
    Apr 14, 2015 at 14:53
  • 1
    @Parto WOW, you know how to get someone's attention :) That is possible for sure, but it would take multiple threads to make it work smoothly (tried it in a "mono" track script). Expect an answer in the next few days :). Apr 14, 2015 at 14:56
  • 1
    Awesome. I'll be waiting...nice question though, wonder how I didn't think of that.
    – Parto
    Apr 14, 2015 at 15:01
  • 1
    @Parto I must say I am impressed by your generosity. I am planning on working further on it and maybe create a ppa, including GUI to start/stop, preferences etc. Thanks for the push! Your desktop looks great by the way! Apr 16, 2015 at 7:12
  • 1
    Anytime. Everyone needs a push now and then. Furthermore you've helped me before too - just consider it a thank you. About this 'project', a ppa would be nice since not everyone is techy.
    – Parto
    Apr 16, 2015 at 8:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .