This outlines an easy method to modify the behavior of select launchers so that when clicked, they open the program if no instance of the program is already running, but restore focus to the program if an instance is already running. It also allows for the ability to hide the window from the taskbar, so that some launchers become their own icons. In other words, you can create a custom "icon box" for some programs (which double as launchers), while other programs use the task list.
Current version: 0.52
UPDATE (25 Dec 2007): Posted version 0.52, which should resolve problems with certain programs not responding correctly to arguments.
The current version, allows for minimizing windows, multiple windows, and a few other goodies. This is still somewhat beta, but should be stable. Moreover, I hope to much more tightly integrate this into the gnome interface at some point, which would make it much easier to use.
Limitations compared to full-blown dock programs:
1) You must manually apply to all launchers.
2) It does not trap instances launched via some other means (e.g., unmodified launcher, browser link in another program, etc.); however, you can still trigger them to hide by clicking on the launcher if it has the -h option (it will now hide all matching windows, not just those launched from the panel initially).
3) Minimization is dependent on a keyboard shortcut (due to a wmctrl bug), so must be set using the -k option if it is not Alt+F9 (the default for Metacity).
On the other hand, launch-restore integrates into your existing panel (of any type), so does not require a commitment to a full-blown dock.
Installation is simple: just install the attached .deb file, which just installs launch-restore into /usr/local/bin, and downloads wmctrl & xautomation if they are not on your system (needed for window handling). If you later want to remove the script, just use synpatic or apt-get to remove "launch-restore" and it will undo everything.
In the simplest case, all you need to do is modify the launcher (I only do this to the icons I put on my panel, but you could also modify the menu entries) by inserting
in front of the program name (and any parameters) already in the launcher. MATCH is a string specific to each program that wmctrl will use to determine if the program is already running. MATCH is tested against either the "name" of a window (i.e., the title you see in the title bar) or the "class" (usually something related to the name of the actual executable). By default, "class" is used, as that is more reliable, but for some programs that won't work. Note that all matching is case-sensitive.
If you wish to just match against the name, you use the "-n" option. For example, to match Firefox, your launcher should look like:
(The %u is there so you can drag & drop a file onto the Firefox icon and have it open in Firefox.)
7.04 and earlier: launch-restore -n Firefox firefox %u
7.10: launch-restore -n Firefox-bin firefox %u
To determine the class of a program, run this in a terminal with the application(s) running:
Which will produce an output something like this (from my system at the moment, running 7.04):
The first 2 columns are the window ID and desktop, and can be ignored. The 3rd column is the "class" - you can choose any fragment of it to match against (e.g., "Firefox" for firefox, "thunderbird" for Thunderbird, "OpenOffice" for OpenOffice). 4th column is computer, and can be ignored. Final column is the "name" (i.e., the title on the titlebar) for each window. The "class" will be constant for every instance of a particular program, while the "name" frequently changes for most programs, and so "class" is the easier target. Also, if you happen to be browsing a website with "Thunderbird" in the title, you may end up restoring focus to Firefox instead of Thunderbird if you match on Thunderbird by name instead of class (and for many other cases).
0x01800003 -1 panel.fbpanel desktop panel
0x00c00003 -1 gnome-panel.Gnome-panel desktop Left Expanded Edge Panel
0x00c00031 -1 gnome-panel.Gnome-panel desktop Bottom Expanded Edge Panel
0x01000021 -1 desktop_window.Nautilus desktop Desktop
0x0260007c 0 Gecko.Firefox-bin desktop Ubuntu Forums - Post New Thread - Firefox
0x02800003 0 mousepad.Mousepad desktop launch-restore
0x02a00003 1 mousepad.Mousepad desktop to do.txt
0x03000073 1 Gecko.Mozilla-thunderbird-bin desktop Inbox for firstname.lastname@example.org - Thunderbird
0x03400062 0 VCLSalFrame.DocumentWindow.OpenOffice.org 2.0 desktop file.ods - OpenOffice.org Calc
0x02c0001f 0 gnome-terminal.Gnome-terminal desktop user@desktop: ~
You can pass additional parameters to launch-restore, here are the most interesting (run it in a terminal to see all parameters):
-x : prevents passing of program arguments to program if an instance of program is already running (I use this for shortcuts to files on my panel, as otherwise the running version receive focus, but then a second copy starts anyway).
-h : hides the program from the taskbar (and alt+tab switching - at least in Gnome). Note that it may very briefly appear before vanishing.
-m: prevents minimization by clicking on the launcher again.
-a & -d: affects how the program deals with multiple windows.
-k to change the minimize key shortcut.
-f to restore focus even when passing arguments (e.g., when dropping a link onto the Firefox launcher).
Use "launch-restore --help" in a terminal for full details of all options.
1 & 2) launches Thunderbird and hides it from the taskbar.
launch-restore -h thunderbird-bin mozilla-thunderbird [in 7.04 and ealier]
launch-restore -h Thunderbird-bin thunderbird [in 7.10]
launch-restore Firefox firefox %u [in 7.04 and earlier]
launch-restore Firefox-bin firefox %u [in 7.10]
launch-restore Toplevel /usr/bin/idle
launch-restore -n -k R_Alt,F5 Audacious audacious
launch-restore --a -m -x nautilus.Nautilus /home/user/
3 & 4) launches Firefox, matching on class (although using "-n" and matching on name would also work with no further changes).
5) launches the python IDLE IDE, and is an example of a program that is difficult to match (the title contains no fixed information at all, and the class is bizarre, but at least "Toplevel" appears to be unqiue on my system).
6) launches audacious, and like Firefox works exactly the same with or without "-n". The -k option resets the "minimize" keyboard shortcut to the Right Alt + F5; this is just an example, it should match the shortcut for your window manager (Metacity's default shortcut is automatic).
7) launches/restores a Nautilus window to your home folder (only starting 1 instance), prevents it from being minimized when the launcher is clicked again, and will match all windows on the current desktop if multiple windows exist.
Additionally, you could combine this with the "easy" gnome dock approach to enhance the dock behavior for some launchers: http://www.ubuntuforums.org/showthread.php?t=333322.
Note that if used with firefox when a window list is still on your panel, you will get a "starting firefox" message in your panel each time you click the launcher; this is due to a bug ("feature") in Gnome, and I cannot make it go away. In 7.10, this bug also affects Thunderbird.
I'd hoped to integrate this into X better, including replacing the need for wmctrl and xautomation (to execute the keyboard shortcut to minimize windows), and creating a background daemon that would simplify application. However, upon examining the available tools to do this tasks, I've concluded that it would be a tremendous amount of effort (weeks of full-time effort) for very little gain, as X simply does not allow for some of what I'd like to accomplish, and I'd spend most of my effort on very low-level code to ensure things don't get too slow. While I may revisit this program over time, and will still make an effort to fix bugs that anyone finds in the current version, I don't anticipate any major updates, as I simply do not have the time required. The script is released under the GPL, so anyone who wants to spend the time is free to do so.
Please post if you encounter any problems and I will modify the script accordingly.