Ubuntu – How to avoid opening a second instance

firefoxlircscripts

I set up lirc to control my PC with a remote. To switch between different modes I edited .lircrc as follows:

begin vlc
    include ~/.lirc/vlc
end vlc
begin gnome
    include ~/.lirc/gnome
end gnome
begin firefox
    include ~/.lirc/firefox
end firefox
begin me-tv
    include ~/.lirc/me-tv
end me-tv

begin
    prog = irexec
    button = KEY_YELLOW
    config = if [ -n $(pgrep -f vlc) ]; then (vlc &); fi
    mode = vlc
end
begin
    prog = irexec
    button = KEY_GREEN
    mode = gnome
end
begin
    prog = irexec
    button = KEY_RED
    config = if [ -n $(pgrep -x firefox) ]; then (firefox &); fi
    mode = firefox
end
begin
    prog = irexec
    button = KEY_BLUE
    config = if [ -n $(pgrep -x me-tv) ]; then (me-tv &); fi
    mode = me-tv
end

Everything works fine with it – except switching to Firefox: When Firefox is running and I press the red button it switches the mode (as it should) and opens a second window/instance of Firefox (as it should not).

The problem appears only with Firefox.

EditPreferencesTabsOpen new windows in a new tab instead is already enabled:

tabs preferences

What happens when Firefox is running and I start firefox in a terminal?

  • firefox – a second window opens
  • firefox about:startpage – a new tab in Firefox opens with the preconfigured startpage
  • (!) firefox about:blank – a new tab in Firefox opens with my personal startpage (Speeddial)
  • firefox chrome://speeddial/content/speeddial.xul (which is the adress of the Speeddial startpage) – nothing happens

What happens when Firefox is not running and I start firefox in a terminal?

  • firefox – Firefox opens as configured in Preferences (Show my windows and tabs from last time)
  • firefox about:startpage – Firefox opens with an additional new tab with the preconfigured startpage
  • (!) firefox about:blank – Firefox opens with an additional new, blank tab
  • firefox chrome://speeddial/content/speeddial.xul – Firefox doesn't open:
    *** Preventing external load of chrome: URI into browser window.
    Use -chrome <uri> instead

So, when I modify the command in the script (config = ...) and add an adress like about:blank it solves the problem partly. As problem remains that it doesn't put Firefox in the foreground when it is already running. This only happens sometimes.

Could anyone help me to edit this script to fix this misbehaviour? (Source of the script which I modified.)

Best Answer

Some of the shell code from that source doesn't do what it claims to do; mainly the type that goes:

if [ -n $(pgrep -f vlc) ]; then (vlc &); fi

This runs vlc & in two cases. If there are no processes matching "vlc", and if there are exactly one process matching "vlc". If there are more than one process matching "vlc", vlc & will not be run. So these if blocks are rather useless. Just running vlc & instead will likely be more correct.

Bad shell advice is unfortunately commonplace on the internet.

From your problem description, what you want the result to be is that the program is run if it isn't already running, and if it is running, bring that window to the front, and give it focus. To do this, wmctrl could be used.

wmctrl -a 'Mozilla Firefox' will find a window containing "Mozilla Firefox" in its title, and "activate" it. That is, move to the workspace it's in, bring it to the front and give it focus. Secondly, if no windows match, wmctrl will do nothing and exit with a non-zero (false) exit status, in which case we can assume the program is not running, and start it instead.

wmctrl -a 'Mozilla Firefox' || firefox &

It's still not perfect though. Other windows than firefox windows could potentially contain that string in their title, so we should find a more reliable way of identifying the right window in this case.

With -x, wmctrl will operate on the VM_CLASS of a window, which will typically have a unique value per program. All firefox windows will have VM_CLASS "Navigator.Firefox" as can be seen by running wmctrl -lx while firefox is running

$ wmctrl -lx
...
0x03ba3d43  3 gnome-terminal.Gnome-terminal  pilot Terminal
0x04c000bc  0 Navigator.Firefox     pilot Group #1 - Speed Dial - Mozilla Firefox

With this we can select the window that has exactly "Navigator.Firefox" as VM_CLASS

wmctrl -Fxa Navigator.Firefox || firefox &

The same should hopefully be applicable for the other programs.

Related Question