Switching workspace in GNOME via the command line

I use rdesktop to connect to some Windows machines, and it works beautifully. I like to allow it to grab keyboard input so I can switch and close windows on my Windows desktop without fear of accidentally doing something to the rest of my Linux desktop.

However, I have never found a way of letting some keystrokes escape – specifically Ctrl-Alt-Left, Right, Up, Down so that I can switch workspaces (virtual desktops) away from the workspace containing rdesktop.

I have finally found what I hope is a good workaround – I have installed easystroke and defined some mouse gestures I can use to switch desktop. These mouse gestures are not swallowed by rdesktop, so they still work, even when it has focus.

When I asked easystroke to send the Ctrl-Alt-Left etc. keystrokes, they got swallowed by rdesktop, so all I needed to be able to do complete the story was a command-line tool to switch workspace.

That turned out to be trickier than you might imagine, but here is my solution, using the amazing wmctrl.

This should work on GNOME with the metacity window manager, and the standard GNOME workspace switcher. It should be easy to adapt to other window managers and workspace tools.

First, install some tools. On Ubuntu you need:

sudo apt-get install bc wmctrl coreutils grep bash

Now create a file with gedit ~/bin/workspace-switcher & and edit it to look like this:

#!/bin/bash

CMD="$1"

NUM_WORKSPACES=`gconftool-2 --get /apps/metacity/general/num_workspaces`
NUM_COLS=`gconftool-2 --get /apps/panel/applets/workspace_switcher_screen0/prefs/num_rows`

NUM_ROWS=`echo "$NUM_WORKSPACES / $NUM_COLS" | bc`

CURRENT_WS=`wmctrl -d | grep \* | cut -d " " -f 1`

MOVE_LEFT="- $NUM_ROWS"
MOVE_RIGHT="+ $NUM_ROWS"
MOVE_UP="-1"
MOVE_DOWN="+1"

case $CMD in

"Left" )
	NEW_WS=`echo $CURRENT_WS "-" $NUM_ROWS | bc`
	if [[ $NEW_WS -lt 0 ]]; then NEW_WS=$CURRENT_WS; fi
	;;

"Right" )
	NEW_WS=`echo $CURRENT_WS "+" $NUM_ROWS | bc`
	if [[ $NEW_WS -ge $NUM_WORKSPACES ]]; then NEW_WS=$CURRENT_WS; fi
	;;

"Up" )
	WS_COL=`echo $CURRENT_WS "%" $NUM_ROWS | bc`
	if [[ $WS_COL -eq 0 ]]; then
	{
		NEW_WS=$CURRENT_WS
	}
	else
	{
		NEW_WS=`echo $CURRENT_WS "- 1" | bc`
	}; fi
	;;

"Down" )
	NEW_WS=`echo $CURRENT_WS "+ 1" | bc`
	NEW_WS_COL=`echo $NEW_WS "%" $NUM_ROWS | bc`
	if [[ $NEW_WS_COL -eq 0 ]]; then NEW_WS=$CURRENT_WS; fi
	;;

* )
	NEW_WS=$CMD

esac

wmctrl -s $NEW_WS

Make it executable with chmod +x ~/bin/workspace-switcher and make sure ~/bin is in your PATH.

You can run it like this:

switch-workspace Left

to move left – the other possiblities are, obviously, Right, Up and Down.

Or like this:

switch-workspace 3

to move to a workspace by number.

If you want to use it with easystroke, create an action, and for the command simply enter switch-workspace Left and similar as the command.

Easystroke can be installed on Ubuntu like this:

sudo apt-get install easystroke

15 thoughts on “Switching workspace in GNOME via the command line”

  1. When I check for existence of utilities included by default on my Ubuntu 10.04 system (e.g., “which bash”), I find that bc, grep and bash are already there. When I try to install coreutils with apt-get, it reports that the latest version is already installed. The only thing that is missing is wmctrl.

  2. Thank you, Thank you, Thank you!!
    Now I can have many more workspaces than the 12 I was limiting myself to … :) ;)
    I’m a visual person …

  3. This is awesome. I am using xmonad on Debian in VirtualBox. OSX is capturing the super key so I have to use Alt for xmonad. But this means that the default gnome switching shortcuts are not captured. But I was able to set up shortcuts to each workspace with your script. Great!

  4. I have modified it a bit but thanks a lot for the idea! No more struggle with workspace grid/matrix in gnome shell

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.