On my home workstation, I have a pretty vanilla installation of Ubuntu (10.04), with Gnome as my desktop environment, and Compiz. I use four workspaces, and usually have around 50-60 application windows open and scattered around the workspaces. With this many applications, every once in a while I faced the problem of not being able to quickly find the one particular window that I wanted, because it was lost somewhere on one of the workspaces.
I frequently had this issue with KeePassX, a neat password management application. Often, when I wanted to log in to a website/service/whatever, and needed KeePassX to get the login credentials, I had to first go through all the workspaces to find the KeePassX window and drag it to the workspace where I wanted it. This was annoying.
Annoyance is the mother of invention, so I solved this problem with a shell script that locates the application’s window and brings it to the current workspace. If the script finds that the application is not running, it starts it. It takes two arguments, the first argument is a string that is used to locate the “lost” window — the script looks for a window with a title that contains that string. The second argument is the program to run if no window is found (optionally followed by program arguments).
This is how I use it to find/run KeePassX:
summon.sh 'passwords.kdb - KeePassX' keepassx
The KeePassX window title is
"/path/to/passwords.kdb - KeePassX", and I use the
"passwords.kdb - KeePassX" part as the title string. Just
"KeePassX" might be insufficient, if, for instance, there is a web browser window open with the KeePassX homepage and also has
"KeePassX" in the title. The
"passwords.kdb - KeePassX" string is distinctive enough.
I have this set up as a launcher in my Gnome panel, so I can simply click the KeePassX icon and have the window pop up on the current workspace:
So in case you’d like to use the script for a similar purpose, here it is:
#!/bin/sh # # summon.sh - Brings application window to current workspace or starts the # application if it isn't running. Intended for use with Gnome and # Compiz. # # Usage: summon.sh <window title> <program> [arguments]... # # <window title> is the title (or a substring of it) of the window to be # found. # # <program> is the application to run if no window is found. May be # followed by arguments. # SELF=`basename $0` if [ $# -lt 2 ]; then cat <<END Usage: $SELF <window title> <program> [arguments]... Brings application window to current workspace or starts the application if it isn't running. Intended for use with Gnome and Compiz. <window title> is the title (or a substring of it) of the window to be found. <program> is the application to run if no window is found. May be followed by arguments. END exit 1 fi TITLE_SUBSTR=$1 shift # Check if the application is running WINDOW_ID=`wmctrl -l | grep "$TITLE_SUBSTR" | sed -r 's/\s.*//'` if [ -z $WINDOW_ID ]; then # Not running -- start it exec $@ else # Application is running -- its window is $WINDOW_ID # Get the dimensions of a single workspace XDPYINFO_OUT=`xdpyinfo | grep 'dimensions:'` WORKSPACE_WIDTH=`echo "$XDPYINFO_OUT" | sed -r 's/.*:\s+([0-9]+)x.*/\1/'` WORKSPACE_HEIGHT=`echo "$XDPYINFO_OUT" \ | sed -r 's/.*:\s+[0-9]+x([0-9]+).*/\1/'` # Get the X and Y offset of the current workspace XPROP_OUT=`xprop -root -notype _NET_DESKTOP_VIEWPORT` CURRENT_X=`echo "$XPROP_OUT" | sed -r 's/.*= ([0-9]+),.*/\1/'` CURRENT_Y=`echo "$XPROP_OUT" | sed -r 's/.*= [0-9]+,\s*([0-9]+).*/\1/'` # Get the coordinates of the top left corner of the window XWININFO_OUT=`xwininfo -id "$WINDOW_ID"` WINDOW_X=`echo "$XWININFO_OUT" | grep 'Absolute upper-left X' \ | sed -r 's/.*:\s+([0-9-]+).*/\1/'` WINDOW_Y=`echo "$XWININFO_OUT" | grep 'Absolute upper-left Y' \ | sed -r 's/.*:\s+([0-9-]+).*/\1/'` # Calculate the new location of the window NEW_WINDOW_X=`echo "($CURRENT_X + ($WINDOW_X)) % $WORKSPACE_WIDTH" | bc` NEW_WINDOW_Y=`echo "($CURRENT_Y + ($WINDOW_Y)) % $WORKSPACE_HEIGHT" | bc` # Move the window to the new location and raise it wmctrl -i -r "$WINDOW_ID" -e 10,"$NEW_WINDOW_X","$NEW_WINDOW_Y",-1,-1 wmctrl -i -R "$WINDOW_ID" fi
The script uses several command-line tools:
bc. I’m pretty sure they are available by default in a standard Ubuntu installation (and probably most other Linux distros, for that matter). If, however, any of them happen to be missing in your system, install the appropriate packages first.