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)?
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)?
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:
If you pick Toggle Firefox however, the application will pop up immediately:
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.
~/.config/hidden_windows, to be mapped on the next time you choose Toggle Firefox from the menu.#!/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()
The script needs both wmctrl and xdotool
sudo apt-get install wmctrl xdotool
Copy the script into an empty file, save it as firefox_bg.py
Test_run the script by the command:
python3 /path/to/firefox_bg.py
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:
I tested the same procedure with gnome-terminal andThunderbird (the latter usually not the quickest to startup), and it works perfectly:
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.
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.