3

I am using several Chrome windows (3-5) with many open tabs on each and I am using "On startup" > "Continue where you left off" settings. The problem is, when I start the chrome, all the windows are open on current workspace (I am using 4 workspaces). What I need to do is to move each window to specific workspace. I need to select window by it's ID because title of the window might be always different (depending which tab is on focus). It is bit annoying to move the windows to right workplace manually all the time.

This is the output of my wmctrl -l command:

wmctrl -l
0x01e00002  0 posuk13-PCSPEC XdndCollectionWindowImp
0x01e00005  0 posuk13-PCSPEC unity-launcher
0x01e00008  0 posuk13-PCSPEC unity-panel
0x01e0000b  0 posuk13-PCSPEC unity-dash
0x01e0000c  0 posuk13-PCSPEC Hud
0x0300000a  0 posuk13-PCSPEC Desktop
0x04400001  0 posuk13-PCSPEC Inbox - xxxxxx@gmail.com - Gmail - Google Chrome
0x04400039  0 posuk13-PCSPEC How to move Chrome windows using wmctrl? - Ask Ubuntu - Google Chrome
0x0440003a  0 posuk13-PCSPEC YouTube - Google Chrome
0x0440003b  0 posuk13-PCSPEC Online regex tester and debugger: JavaScript, Python, PHP, and PCRE - Google Chrome

And now let's say I need to move the YouTube window to workspace #2. The following command works:

wmctrl -r YouTube -e 0,2000,0,-1,-1

and also this works:

wmctrl -r 0x0440003a -i -e 0,2000,0,-1,-1

But the problem is that the window ID is different every restart and it's title is different every time I switch tab. Is there a way to select window by part (last 3-4 digits) of it's ID (it seams that last 2-3 digits are always the same when I start the window right after reboot), or to select e.g. 7th window from the list? The reason I need this is I want to write script that will start all required applications (Chrome, Apache, SublimeText...) and move windows to specific workplaces (I have one workplace for e-mail/Facebook, one for music and one for work stuff).

PS: Please do not suggest using system hibernation - it is not an option for me because of some driver issues.

PS2: I am using Ubuntu 15.04

2 Answers2

2

How to identify specific windows of Chrome

If the windows are always created (on startup) in the same chronological order (as you mentioned in a comment), you can use a specific property of the output of the command wmctrl -l: The list always lists the windows in the order they were created.

That means that if you have (e.g.) three windows, re- created in always the same order, you can simply first filter out the windows, belonging to Chrome, then "mark" the windows by their order as their appear(ed) in the output of wmctrl.

How to filter out Chrome windows from wmctrl

To identify windows, belonging to an application, you need to use the command:

wmctrl -lp

which will also show the pid the window belongs to. Usually, this is a single pid. In the case of Chrome however, there will be several. The procedure, programmatically, is then:

  1. Find the pids of Chrome by running:

    pgrep chrome
    
  2. Run the command:

    wmctrl -lp
    
  3. parse out, per window, the pid the window belongs to and look for a match in the output (list) of pgrep chrome

    enter image description here

  4. This will produce a list of windows, belonging to Chrome. Their identification, as mentioned, then is their order in the list. All you need to do then is parse their window id (the first string in their line in the output of wmctrl -lp that you ran) and you're done.

Subsequently, use the usual command to move the windows to the desired workspace.

An example; the test

As an example script to test if this works (python, what else :))

#!/usr/bin/env python3
import subprocess

# get the list of pids of chrome
pids = [p for p in subprocess.check_output(["pgrep", "chrome"]).decode("utf-8").splitlines()]
# get the list of windows
windows = [l.split() for l in subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8").splitlines()]
# filter out the windows of chrome, parse their window-id
matches = [w[0] for w in windows if w[2] in pids]
print(matches)

# raise the window
subprocess.Popen(["wmctrl", "-ia", matches[0]])

For this example, I opened three Chrome windows, closed them as you described and opened Chrome again.

In matches[0] (last line), I made it raise the first window of the list:

['0x05600001', '0x05600039', '0x0560003a']

On the next run, the window id's changed:

['0x05800001', '0x05800039', '0x0580003a']

but their order in the list remained, since (indeed) the windows are always created in the same (chronological) order. Therefore the last line of the script:

subprocess.Popen(["wmctrl", "-ia", matches[0]])

always makes the same (first) window raise, while

subprocess.Popen(["wmctrl", "-ia", matches[1]])

will always raise the second and so on.

Replace the raise- command by the move- command and you'll have your script work.

Jacob Vlijm
  • 85,475
0

So I was able to solve the problem using Python. And please keep in mind that this is my very first Python script so it is not perfect.

#!/usr/bin/python
import subprocess

foo=subprocess.check_output(["wmctrl", "-lx"])  #list windows with WM_CLASS
def f1(foo=foo): return iter(foo.splitlines())
list=list(f1());
gloop=0  #google loop - to count google windows
sloop=0  #sublime loop - to count sublime windows (currently only one, but I might add more in future)
google = [ ["0", "0"], ["2000", "0"], ["2000", "2000"],  ["2000", "0"] ]  #google windows positioning
sublime = [ ["2000", "0"] ]  #sublime windows positioning
for s in list:
    if (s[14:20]=='Google'):
        #print "Google"
        windowid=s[0:10]
        windowpos="0,"+google[gloop][0]+","+google[gloop][1]+",-1,-1"
        subprocess.call(["wmctrl", "-r", windowid, "-i", "-e", windowpos]);
        gloop+=1
    if (s[14:20]=='sublim'):
        #print "Sublime_text"
        windowid=s[0:10]
        windowpos="0,"+sublime[sloop][0]+","+sublime[sloop][1]+",-1,-1"
        subprocess.call(["wmctrl", "-r", windowid, "-i", "-e", windowpos]);
        sloop+=1