Since no one seems to have a Firefox-specific answer (probably because that -class
flag, not being documented in the man page, is not properly functional), I'll just post my ugly hack as a solution. If someone could improve it substantially, I'll give them the answer credit instead.
I wrote the following script, called it firefoxApp.sh, and put it in ~/bin/. It's a terrible hack, and I'm ashamed of it. And also proud. I ditched the separate Firefox profile, and instead just used wmctrl, grep, and xprop to change the WM_CLASS
of the newly-created window, after a delay (since windows sometimes take a substantial amount of time to appear and be titled). If someone could tell me a more precise and reliable way to find the windows to reclass, that's not plagued by timing/race conditions, this script would be greatly improved. I tried and failed to do it with the PID of the launched process (presumably because the whole Firefox profile has one root PID). I won't post here the code for that attempt, since I no longer have it.
#!/bin/sh
targetclass=$1
url=$2
titlegrep=$3
if [ "$#" -ne 3 ]
then
echo "USAGE: $0 TARGETCLASS URL TITLEGREP" 1>&2
exit 1
fi
firefox -P default -new-window "$url" &
sleep 10
# Ensure only newlines split items in the upcoming for loop:
IFS='
'
for wid in `wmctrl -l -x | grep $titlegrep | awk '{ print \$1 }'`
do
xprop -id $wid -f WM_CLASS 8s -set WM_CLASS $targetclass
done
This script I call using .desktop files in ~/.local/share/applications which look like the following.
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Terminal=false
Type=Application
Name=Calendar (Firefox)
Exec=firefoxApp.sh googlecalendar calendar.google.com Calendar
Icon=calendar
StartupWMClass=googlecalendar
If I choose, I can use a more specific icon name like google-calendar-firefox-app
, and then drop a file named google-calendar-firefox-app.svg
in ~/.local/share/icons.
Update: I've new settled on using actual separate profiles for each such "app". It's a little more work to set them up, but this can be largely automated with another script which I'll just leave as a Gist here, and this works with Firefox rather than around it, eliminating the race-conditions of the window-renaming approach.
Of course, a significant downside feature of this approach is that these apps are sandboxed from the main Firefox profile, and won't share any plugins or extensions with it. So, e.g., you might need to copy passwords from LastPass manually.
As a bonus, the script also populates a userChrome.css
file to hide the window chrome in the new profile, which aids in creating the illusion of web "apps". It can be invoked with --help
to get
usage: create_firefox_app.py [-h] [--app_name APP_NAME]
[--hide_user_chrome HIDE_USER_CHROME]
[--run_after_creating RUN_AFTER_CREATING]
URL icon_name
positional arguments:
URL Homepage to be used when opening new windows in the
profile via the .desktop file.
icon_name Icon name to use in .desktop file. An explicit path
can be given, or something that resolves using the
regular icon search path (however that works; e.g.,
for ~/.local/share/icons/gmail.svg, you could enter
just gmail.svg).
optional arguments:
-h, --help show this help message and exit
--app_name APP_NAME Name for the generated "app" to use in the .desktop
file. If not given, a santized version of the URL will
be used instead. (default: None)
--hide_user_chrome HIDE_USER_CHROME
Whether to generate userChrome.css file that will hide
window chrome in all windows created in the new
profile. Useful to make web-apps seem more app-y.
(default: True)
--run_after_creating RUN_AFTER_CREATING
Whether we should start the new app after creating it.
(default: True)
If you enable the hide_user_chrome
option, and need to get it back for whatever reason, say to install an extension, just trash the generated ~/.mozilla/firefox/PROFILE/chrome/userChrome.css
file and restart the profile.
--class
to work at the command line, I wouldn't expect it to work in a .desktop file.-P