Introduction & the pain¶
I am a big fan of both KDE and Mozilla software – while no software is perfect, of course, these two I like and trust the most when it comes to my desktop and web browsing respectively. To illustrate, I have been using KDE when it was still called the K(ool) Desktop Environment 1.x, and Mozilla since its Netscape and Phoenix days.
But as both KDE’s Plasma desktop and Mozilla’s Firefox browser each became more and more powerful, making use of their individual strengths started to produce some clashes.
One of the most powerful features of Plasma – and one that I make extensive use of – are its Activities1. I use them to keep different tasks in different environments and as such remove needless distractions.
For example, to list just a few, I have a “Communication” Activity where I keep all communication channels and generic web pages and try to spend as little time there as possible; an “Organise yourself”; a “Blogging” Actvity; and several ephemeral ones for each project I need concentrating on – two recent examples were “Presentation for FRI“ where I did research, wrote and presented from; and “Activity-aware Firefox” where I was coding and testing the script I am blogging about today.
And a feature that makes Activities immensely powerful is that you can stop/suspend the ones that you do not need active right now and it stops all that is happening in it. With this you can save a lot of processor and memory resources. Then later when you start the Activity again, it shows up in the same state it was stopped. Super practical!
At the time of this writing, I have 3 active Activities and 10 suspended/stopped ones.
Now, as you can imagine, often in these Activities, you want to have some web tabs open. And here is where things start to sour. More often than I would like things like these happen:
- a link opened in one Activity could open in a Firefox window in a different Activity (sometimes even starting that extra Activity, if it was stopped)
- when resuming a stopped Activity with Firefox in it, it would sometimes spawn other Firefox windows that are not related to that Activity
- in general Firefox windows tend to move around Activities where you do not expect them to be
At some stage this became a huge pain, especially as every time Firefox started, I would never know what popped up in which Activity and would then spend way too long to move every browser window in its appropriate Activity and suspend Activities that I did want to be started. This was so bad, that I actually rued every time I needed to close Firefox or log out of Plasma, knowing what awaits when Firefox starts again.
But enough about whining, we should move towards fixing!
Solution: “Activity-aware Firefox”¶
… so, why not make Firefox aware of Activities?
As with most problems, this itch was felt by others before me. I will list the ones that I found and took inspiration from:
- Yuen Hoe “Jason Moofang” wrote a C++ wrapper for Firefox that I for some reason could not get running on my laptop – but apparently it still works, and is probably more powerful than my small script (but C++ is way outside my comfort zone)
- Ivan Čukić blogged about his soluton, but I could not find the code
- then I found this thread on Arch forums, which I kind of understood, so I based my solution on top of that; specifically the improved version by “adrian15”
Now, Firefox has continued to be developed since the above mentioned posts were written, so I could further simplify some things in the script. At this point I have to thank to Mozilla’s wonderful community on their official
#general:mozilla.org Matrix channel.
Which is how I came to this:
#!/bin/bash # # Compatability for Firefox and KDE Plasma Activities # # SPDX-License-Identifier: CC0-1.0 # SPDX-FileCopyrightText: © 2021 Matija Šuklje <firstname.lastname@example.org> ACTIVITY=$(qdbus org.kde.ActivityManager /ActivityManager/Activities CurrentActivity) FF_FOLDER=$"$HOME/.mozilla/firefox" DEF_PROF=$"$FF_FOLDER/????????.default-release" NEW_PROF=$"$FF_FOLDER/????????.$ACTIVITY" if [ -d $FF_FOLDER/????????.$ACTIVITY ]; then exec /usr/lib/firefox/firefox -P $ACTIVITY "$@" & echo ">>> started an existing profile: $ACTIVITY" else /usr/lib/firefox/firefox --createprofile $ACTIVITY echo ">>> created a new profile: $ACTIVITY" cp -a $DEF_PROF/chrome $NEW_PROF/ # copy any custom user chrome, e.g. needed to hide the top tab-bar echo ">>> copied user chrome from default profile" exec /usr/lib/firefox/firefox -P $ACTIVITY "$@" & echo ">>> started the new profile: $ACTIVITY" fi exit
Basically, what the script does is that it creates a new Firefox Profile for each Plasma Activity it was started in (it matches its ID), and then always starts that Profile in that Activity.
The script, some additional files (such as its
.desktop), along with instructions and interactions with specific add-ons etc., is available on GitLab as “Activity-aware Firefox”.
What works and what not¶
“Activity-aware Firefox” if you set it up as instructed in the
README file, works for me great. But there are some kinks still.
Basically all of the above-mentioned pain-points are gone. And that is the most important to me.
Now I can start “Activity-aware Firefox” in any Plasma Activity and know exactly what I will get. And that is a huge win!
An unexpected downside though is that for some reason Firefox kills itself if it has been sleeping for a certain period of time after receiving e.g.
SIGSTOP, if you resume a stopped Activity, Firefox will start with the default profile. If that happens, I need to close that window and simply start “Activity-aware Firefox” and it will come back as expected. Annoying, sure, but since my default profile is now without any tabs, it does not take a lot of time. Would love to hear it if someone has a good solution for this, though!
Something that was a conscious choice when writing the script was that it does not copy the default profile into the new Activity-aware one. This means when it first starts, it starts with a blank Profile. To sync add-ons, settings, bookmarks, etc. I rely on Firefox Sync, which of course takes some time to finish. But in relation on how much time it saves me on a regular basis on not messing around with misplaced windows, it is well worth it.
The reason why that was a conscious decision is that not everything in
~/.mozilla/firefox/ can be simply moved between Profiles without breaking things. So instead of trial-and-error, I decided to err on the side of cautious.
Instead of moving tabs between windows, you now have to move them between “devices”/Profiles with Firefox Sync, as every Firefox Profile is treated separately from another.
The positive side of this separation though is that if you suspend or kill “Activity-aware Firefox” in one Plasma Activity, it will not any others
Next steps – help welome¶
There are a few steps one must take to set up “Activity-aware Firefox” as I did, so I suspect it is not something I would expect more careful newcomers to replicate. Ideally this is how Firefox and Plasma would work out-of-the-box (and without the kinks!) But I am toying with the idea whether it would be beneficial to at least wrap the script and
.desktop file into an installable package.
I also did not implement any way to clean up Firefox Profiles that are not used anymore, but a good starting point is adrian15’s blog post. The reason being that I do not understand that enough (yet) and fear I would delete too much.
Another obvious next step would be to figure out how to make sure that when an Activity is started again, the Firefox it automatically starts uses the correct Profile.
Any and all help most welcome!
Just drop me a mail or open an issue/merge request.
Plasma Activities and Firefox are just too good to not work well together
hook out → well, now I need to migrate my work laptop to Activity-aware Firefox as well …
If you do not know what Activities are in Plasma or how to use them, Niccolo Vé does a good job explaining that in his video. ↩