Single Instance and Keyboard Shortcuts in Ubuntu/Linux Mint


Linux Mint 18 Nemo Update below…


Anyone who knows me well enough to know that I love my keyboard shortcuts indeed knows me well.

Quickly moving between GUI apps makes development so much quicker and more efficient. Or at least it seems so.

Using keyboard shortcuts to move between single instances of applications is just an extension of that. Ubuntu/Mint (Gnome, that is) has some nice support for global keyboard shortcuts. But using those shortcuts doesn’t help much if you’ve already got a window open. Using the shortcut for Firefox, for example, would open another window.

For me and my web development, single instance shortcuts means super-quick moving between apps. Switching between Firefox, Chrome and Geany, my text editor of choice, using the shortcuts CTRL-ALT-f, CTRL-ALT-c, and CTRL-ALT-e is much quicker than ALT-turtling around.

Many apps include a ‘Use only a single instance’ option, but for those that don’t, a little script to the rescue.

First you’ll need to grab wmctrl.

sudo apt-get install wmctrl

Then edit a file called one-instance somewhere in the path.

#!/bin/sh
TITLE=$1
PROGNAME=$2
if [ -z "$2" ]; then
PROGNAME=$1
fi
if [ -z `wmctrl -l | grep -i "$TITLE"` ] ; then
$PROGNAME
else
wmctrl -a "$TITLE"
fi

Make the file executable

chmod 755 one-instance

The script is simple.  It tries to match something in a program’s title bar.  If it finds it, then it switches to it.  If it doesn’t find it, then it opens a new instance of it.

So, in the simplest case, if the name of the executable is the name we’re looking for in the title bar (as is the case with firefox), then you can call it like this:

one-instance firefox

If what we’re trying to match in the title bar is different from the executable name, then we specify it like this:

one-instance MATCHTITLE EXECUTE_IF_TITLE_NOT_FOUND

So, for Chrome we can use:

one-instance chromium chromium-browser

NAUTILUS BONUS:

Nautilus doesn’t work so well using this technique, so another little script had to be employed.  Called this one one-nautilus:

#!/bin/sh
CLASSNAME=nautilus.Naultius
if [ -z `wmctrl -xl | grep -i $CLASSNAME` ] ; then
nautilus ~
else
wmctrl -xa $CLASSNAME
fi

You can use this technique for programs which don’t have something constant (like Firefox) in their title bar.  You can find out a program’s class name by using this command:

wmctrl -xl

By the way, Linux Mint 14 uses the class name caja.Caja for it’s version of nautlius. 

UPDATE: Newer Mint Versions Use Nemo

Newer Mint versions, like Linux Mint 17, updated the classname to Nemo.

So we can use a new script called one-classname-instance. And we call it like this: one-classname-instance nemo.Nemo "nemo ~". Here’s the script:

#!/bin/sh
CLASSNAME=$1
PROGNAME=$2
if [ -z "$CLASSNAME" ]; then
	echo Your options...
	wmctrl -xl
	exit 1
fi
if [ -z "`wmctrl -xl | grep -i \"$CLASSNAME\"`" ]; then
	$2 &
else
	wmctrl -xa $CLASSNAME
fi

Linux Mint 18 Update
The Nemo classname is now used by the desktop and any open windows, so we need to add a bit more complexity to find the right (i.e. second) window.
Thanks to Ben in the comments for the starting off the following code.

#!/bin/sh
CLASSNAME=nemo.Nemo
# if there's only one matching classname, then start new window
if [ "`wmctrl -lx | grep \"$CLASSNAME\" | wc -l`" -eq 1 ]; then
	nemo ~
# otherwise, grab the second listing of the CLASSNAME
else
	WM_CLASS="`wmctrl -xl | grep \"$CLASSNAME\" | sed -n 2p | cut -d \" \" -f1`"
	wmctrl -ia $WM_CLASS
fi