7

A known feature in Chromium is the option to make it run in the background, which makes it easier to open .

Is it possible to do the same with firefox (and other applications)?

Jacob Vlijm
  • 83,767
a3k
  • 175
  • Please define "in the background". Without a window? – Jacob Vlijm Nov 26 '16 at 16:38
  • Yes without a window (Like uGet and Telegram) – a3k Nov 26 '16 at 18:45
  • I see, can be done. Will post back if no one does before I do :) – Jacob Vlijm Nov 26 '16 at 19:22
  • No one answered :( – a3k Nov 26 '16 at 21:26
  • Haha, no, but it needs some work to create the solution. I will probably post tomorrow :) – Jacob Vlijm Nov 26 '16 at 21:27
  • Ok thank you for all your effort . Just wondering if it is difficult ? – a3k Nov 26 '16 at 21:38
  • Do you want something like this add-on? https://addons.mozilla.org/en-US/firefox/addon/minimizetotray-revived/ Also see: http://askubuntu.com/questions/471782/how-to-run-thunderbird-in-the-background/472423#472423 – muru Nov 27 '16 at 11:24
  • @muru did you try? It does.. well, totally nothing but close the application. Just like the comments mention. – Jacob Vlijm Nov 27 '16 at 12:21
  • @muru It does nothing ! The only solution is provided in the answer below by Magnificent Jacob – a3k Nov 27 '16 at 12:26
  • @JacobVlijm I used to use it months ago. Haven't tried it recently. – muru Nov 27 '16 at 12:28
  • 1
    @muru Ah, thanks. Also: In case anyone tried the linked add-on, it leaves firefox with a pid, but no traceable windows. Please run killall firefox before running the answer below, else the script will assume firefox runs already. (you might want to remove the comment :) ) – Jacob Vlijm Nov 27 '16 at 12:51

2 Answers2

6

Running an application in the background

The solution below will allow you to run firefox (or any other application) in the background, meaning: without a visible window. Nor will the application show in Dash as a running application:

enter image description here

enter image description here

If you pick Toggle Firefox however, the application will pop up immediately:

enter image description here

How it works

  1. If the panel icon (indicator) starts up, it launches a new firefox window, but immediately hides it (including possible existing firefox windows) from the face of the earth, using xdotool:

    xdotool windowunmap <window_id>
    

    This will not only hide the window, but also will hide the fact that firefox is running at all, since the unity launcher acts on visibly existing windows.

  2. The indicator stores the id of all unmapped windows in ~/.config/hidden_windows, to be mapped on the next time you choose Toggle Firefox from the menu.

The script

#!/usr/bin/env python3
import subprocess
import os
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3
import time

app = "firefox"
winsdir = os.path.join(os.environ["HOME"], ".config/hidden_windows")

try:
    os.mkdir(winsdir)
except FileExistsError:
    pass

def checkruns(app):
    try:
        return subprocess.check_output(["pgrep", app]).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        for w in os.listdir(winsdir):
            if w.startswith(app):
                os.remove(os.path.join(winsdir, w))

def get_currentwins(pid):
    wins = subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8").splitlines()
    return [l.split()[0] for l in wins if pid in l]

def hide_currentwins(matches):
    # open(os.path.join(winsdir, "windowlist"), "wt").write("\n".join(matches))
    for w in matches:
        open(os.path.join(winsdir, app+"_"+w), "wt")
        subprocess.Popen(["xdotool", "windowunmap", w])

def run_app(app):
    subprocess.Popen(app)
    while True:
        time.sleep(1)
        pid = checkruns(app)
        matches = get_currentwins(pid) if pid else None
        if matches:
            hide_currentwins(matches)
            break

def restore_wins():
    for w in [w for w in os.listdir(winsdir) if w.startswith(app)]:
        wid = w.split("_")[-1]
        subprocess.Popen(["xdotool", "windowmap", wid])
        os.remove(os.path.join(winsdir, w))

def toggle_app(*args):
    pid = checkruns(app)
    if pid:
        matches = get_currentwins(pid)
        if matches:
            hide_currentwins(matches)
        else:
            restore_wins()
    else:
        subprocess.Popen(app)

run_app(app)

class Indicator():
    def __init__(self):
        self.app = 'toggle_app'
        self.indicator = AppIndicator3.Indicator.new(
            self.app, app,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)       
        self.indicator.set_menu(self.create_menu())

    def create_menu(self):
        self.menu = Gtk.Menu()
        item_toggle = Gtk.MenuItem('Toggle '+app)
        item_toggle.connect("activate", toggle_app)
        self.menu.append(item_toggle)
        sep1 = Gtk.SeparatorMenuItem()
        self.menu.append(sep1)
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.stop)
        self.menu.append(item_quit)
        self.menu.show_all()
        return self.menu

    def stop(self, source):
        Gtk.main_quit()

Indicator()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()

How to use

  1. The script needs both wmctrl and xdotool

    sudo apt-get install wmctrl xdotool
    
  2. Copy the script into an empty file, save it as firefox_bg.py

  3. Test_run the script by the command:

    python3 /path/to/firefox_bg.py
    
  4. If all works fine, add it to Startup Applications: Dash > Startup Applications > Add. Add the command:

    /bin/bash -c "sleep 10 && python3 /path/to/firefox_bg.py"
    

    Alternatively, copy the code below into an empty file, save it as firefox_bgrunner.desktop in ~/usr/share/applications, log out and back in.

    [Desktop Entry]
    Type=Application
    Exec=python3 /path/to/firefox_bg.py
    Name=Firefox Webbrowser Background Runner
    Icon=firefox
    StartupWMClasss=nonsense
    

    *The last line, StartupWMClasss=nonsense is to make sure Firefox windows will appear under their own icon, not the one of the indicator.

    No need to mention that you have to edit the Exec= line to reflect the real (absolute) path to where you stored firefox_bg.py

    Then you will have the panel runner available from Dash:

    enter image description here

Other applications?

I tested the same procedure with gnome-terminal andThunderbird (the latter usually not the quickest to startup), and it works perfectly:

enter image description here

To use with other applications, simply edit the line:

app = "firefox"

Note however that some applications seem to check if their attempt to create a window succeeded, and create a second one if the first one is unmapped. This happened to me with Inkscape.

The script can even then perfectly be used though, but would need a small edit. If anyone ever might need to use it with Inkscape, please leave a comment.

Jacob Vlijm
  • 83,767
0

I'd like to propose a 2019 solution to this for Ubuntu 18-19+ with GNOME that is a little bit simpler (IMO) and uses bash instead of python for simplicity. I made this so that Firefox would ask for my Master Password when I signed in, but then not ask again unless I went to view passwords. I was tired of it popping up every time I started firefox.

First install the dependencies:

sudo apt-get update && apt-get install -y wmctrl xdotool

Then put this script somewhere, say /data/system/bin/firefox-background:

firefox "about:blank" &
WAITFOR="Mozilla Firefox"

APP=$(wmctrl -lp |grep "${WAITFOR}" |awk '{print $1}')
while [ -z "${APP}" ]; do
    sleep 1
    APP=$(wmctrl -lp |grep "${WAITFOR}" |awk '{print $1}')
done
xdotool windowunmap ${APP}

And:

chmod +x /data/system/bin/firefox-background

Now you can run this script however you would like such as from a terminal window or from the GNOME startup with a file in .config/autostart/FirefoxBackground.desktop:

[Desktop Entry]
Name=Firefox Background
Exec=/data/system/bin/firefox-background
Terminal=false
Icon=firefox
Type=Application
StartupNotify=false
X-GNOME-Autostart-enabled=true
StartupWMClasss=nonsense

After that, you'll get a popup for the master password once, and never again unless you intend to access secure info.

Fmstrat
  • 111