Ubuntu – Launch app only if not already open

launchershortcuts

I would like to mimic the use of Alfred on Mac OS X, where if you try to open an app after searching for it, it will only open a new window if the program is not already running, otherwise it will set the focus on the currently running instance of that application. Is there anyway to change the default behavior of the launcher to check for this before opening a new window?

Best Answer

Update April 7: A different version added and found Albert, see update and Bonus bellow !!!

Concerning dash functionality: You have asked " Is there anyway to change the default behavior of the launcher to check for this before opening a new window". Basic answer is, no, as a regular user you have no way of adding that behavior to dash. However, if there would be a unity scope developer who'd be willing to implement that, you might approach them or develop one yourself if you have resolve and willing to learn. My coding skills are very modest, hence I use shell scripting and the available graphical front-end for the scripts as a workaround.

Related information

Original post:

I have written a script that uses zenity dialogue and wmctrl to achieve what you asked for. Notice that this is a graphical script, meaning it will only work with windows, in GUI, and won't work if you try to launch something in tty. Besides, from what I understand Alfred does exactly the same thing. You can create a desktop shortcut to it or launcher shortcut to it, as described here and here.

The script:

#!/bin/bash
# Author: Serg Kolo
# Description: A launcher script that checks whether
#       or not a window of a particular program already exists
#       If a window of such program is open, bring it to focus
#       Otherwise - launch a new window
#       Written for https://askubuntu.com/q/440142/295286
# Date: April 6 , 2015
#


MYPROG=$( zenity --entry --title='MY LAUNCHER' --text='Type the name of application to run' )
sleep 0.5
wmctrl -lx | awk '{print $3}' | grep -i "$MYPROG"

if [ $? -eq 0 ]; then
    sleep 1         
    wmctrl -xa $MYPROG
   #as an alternative try the line bellow
   #wmctrl -a $MYPROG
    exit 1
else 
    $MYPROG &
    exit 0
fi

Side notes: in the previous version , script used echo $?, to test if previous expressions exited successfully. As per muru's suggestion ( from the edit ), I changed the code to somewhat more compact version, so i suggest you take a look at the previous version and the current.

Also , previously wmctrl -a $MYPROG didn't work with testing google-chrome or chromium-browser; for some stupid reason some programs have WM_CLASS property of the window capitalized , while the program as listed by dpkg --get-selections is lowercase (just read man wmctrl and run wmctrl -lx, you'll know). Adding that -ax should take care of this. The script brings up the already open chromium window as it should

Another thing - wmctlr is somewhat weird in that it needs a delay sometimes (had experience with it in another script), so i had to add sleep 1 line. Previously it would be kind of on and off with firefox, but now works swimmingly.

The script in action

In the animation bellow you can see that on the first run of the script, there is one instance of firefox open, and the script switches focus to that window; on the second test, I open new instance of google-chrome, which hasn't been open previously. (Side note: If you are currious about the desktop, by the way, that is openbox with cairo dock)

Per suggestion in the comments, embedded animation removed, posted link only. Report if it is broken please ! http://i.stack.imgur.com/puuPZ.gif

Update, April 7

I improved the script somewhat to make all the programs listed in zenity's drop-down entry box. Now the user doesn't have to memorize each program, but can just scroll through a list of them using arrow keys or just open the drop down menu. Also, this improved version raises windows not by name, but by window id, which gives much better performance. Note, the way i go through .desktop files is kind of redundant, using cut command twice, but since my script-fu isn't that good so far, this is all i can do. Suggestions for improvement are welcome!

#!/bin/bash
# Author: Serg Kolo
# Description: Second version of a launcher script that checks whether
#       or not a window of a particular program already exists
#       If a window of such program is open, bring it to focus
#       Otherwise - launch a new window
#       Written for https://askubuntu.com/q/440142/295286
# Date: April 7 , 2015
#

set -x

MYPROG=$(zenity --entry --text 'Select program from list' --entry-text $(ls /usr/share/applications/*.desktop | cut -d'/' -f5 | cut -d'.' -f1 | xargs echo))
sleep 0.5
# Do we have a window of such program ?
wmctrl -lx| awk '{print $3}'  | grep -i $MYPROG

if [ $? -eq 0 ]; then
    sleep 0.5 # if yes, find that window id, and raise it
    WINID=$(wmctrl -lx | grep -i $MYPROG | awk 'NR==1{print $1}')
    wmctrl -ia $WINID &
 #  exit 0  
else
    echo $MYPROG | grep -i libreoffice
    if [ $? -eq 0  ]
    then
        MYPROG=$(echo $MYPROG | sed 's/-/ --/g')
    fi
    $MYPROG &

#  exit 0 
fi

enter image description here

Bonus:

I have actually found Albert , which is Linux version of Alfred, but have not tried it myself. Worth checking out though. However, as Jacob noted already, it is still buggy.

There is an app called Gnome-Do, which graphically looks similar to Alfred, however it does not have the same functionality as this script.

enter image description here

Let me know if you like this script, if there's anything needs fixing, and don't forget to upvote the answer if you find it useful

Related Question