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.
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