You can use wmctrl.
Basics commands:
wmctrl -d
to show all of your workspaces.
wmctrl -s <workspace_name>
to change to a specific workspace.
If you are using Compiz, you will have to do a trick because Compiz "workspaces" are actually Viewports of a single Workspace.
Trick Instructions
Check the output of wmctrl -d
For example, mine is:
0 * DG: 4098x2304 VP: 1366,0 WA: 0,23 1366x745 N/A
This means that actually I have one Workspace of 4098 x 2304 instead of what I "think" I have (nine "workspaces", 3 x 3).
I was at what was supposed to be "workspace" 2, but actually I was at viewport (VP) 1366,0 (4098 / 3 = 1366) as showed by the output above.
So this is how it works: we take the whole Workspace and divide for the numbers of "workspaces" we "think" we have. In my case: 4098 / 3 = 1366 and 2304 / 3 = 768.
If I want to go to my "workspace" 1, the command is:
wmctrl -o 0,0
Then, if I want to go to my "workspace" 4, the command is:
wmctrl -o 0,768
If I want to go to my "workspace" 8, the command is:
wmctrl -o 1366,1536
If I want to go to my "workspace" 9, the command is:
wmctrl -o 2732,1536
Got it? ;-)
The -o
flag "truncates" their values.
In other words it changes the "workspace" where the actual pixel is belonging to.
The following are equivalent:
wmctrl -o 0,0
wmctrl -o 1365,767
Just as another option, using another method to indicate the current viewport. I used a similar fuctionality in a number of scripts, a.o. here.
import subprocess
import os
import time
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 get_dt():
# get the current viewport
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 curr_col+curr_row*cols
res = get_res()
curr_dt1 = None
while True:
time.sleep(0.5)
curr_dt2 = get_dt()
# if we change viewport, do something:
if curr_dt2 != curr_dt1:
print(curr_dt2)
# if we enter viewport3, do something
if curr_dt2 == 3:
subprocess.Popen(["gedit"])
curr_dt1 = curr_dt2
The script detects both change in viewport as well as entering a specific viewport.
If an action should be done on change in viewports, replace the print command in:
if curr_dt2 != curr_dt1:
print(curr_dt2)
...by another command (subprocess.popen()
)
If an action should place on enterin g a specific viewport, replace the command in:
if curr_dt2 == 3:
subprocess.Popen(["gedit"])
...by another one. If The process should be killed when leaving the workspace, add a section:
if all([curr_dt1 == 3 curr_dt2 != 3]):
subprocess.Popen(["<killcommand>"])
Best Answer
If you are using a compliant window manager like Metacity (Unity 2-d) you can use wmctrl to switch a window to another desktop. The syntax is
wmctrl -r :ACTIVE: -t <DESKTOP>
. You can also change your current desktop usingwmctrl -s <DESKTOP>
. Desktop numbers start at 0. On one line, this would be:If you want to switch a window other than the active one to another desktop, use text from the title as the argument to -r. For example:
Alternatively you can use
wmctrl -l
to list the available windows and pass the id number to -r instead of the special string:ACTIVE:
. When passing an id, you also need to add -i. For example:(wmctrl can be installed on Ubuntu with
sudo apt-get install wmctrl
.) At present, this doesn't seem to work with standard Unity, unfortunately.