Page MenuHomePhabricator

Bug 28354 - Added option "browser.tabs.allow_transparent_browser" to "about:config" to stop forcing opaque backgrounds. r=dao
ClosedPublic

Authored by kravantokh on Feb 11 2024, 8:34 PM.
Referenced Files
Unknown Object (File)
Feb 5 2026, 10:57 AM
Unknown Object (File)
Nov 13 2025, 1:26 PM
Unknown Object (File)
Nov 13 2025, 1:26 PM
Unknown Object (File)
Nov 13 2025, 1:26 PM
Unknown Object (File)
Nov 13 2025, 1:26 PM
Unknown Object (File)
Oct 26 2025, 1:28 AM
Unknown Object (File)
Sep 19 2025, 3:56 AM
Unknown Object (File)
Aug 6 2025, 1:06 AM

Details

Summary

The background behind the rendered webpage may now be made transparent with these changes by toggling the mentioned preference.
The new option defaults to false, preserving the previous behaviour as the default. For the changes to apply "browser.tabs.allow_transparent_browser" has to be explicitly set to "true" in about:config.

For transparency to actually work, though, a userChrome.css is necessary to make the tab's background transparent ( :root { --tabpanel-background-color: #00000063 !important; } ).
Pages may not be transparent by default (except for some rare cases), but extensions may be used to enforce transparent background colors on all pages.

As such this patch implements all necessary changes to allow users to make firefox transparent without having to patch and recompile it.

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
phab-bot changed the visibility from "Custom Policy" to "Public (No Login Required)".Feb 11 2024, 8:34 PM
phab-bot changed the edit policy from "Custom Policy" to "Restricted Project (Project)".
phab-bot removed a project: secure-revision.
kravantokh updated this revision to Diff 821478.
kravantokh retitled this revision from WIP: Bug 28354 - Added option "browser.display.allow_transparent_background" to "about:config" to stop forcing opaque backgrounds. to Bug 28354 - Added option "browser.display.allow_transparent_background" to "about:config" to stop forcing opaque backgrounds. r=emilio.
kravantokh edited the summary of this revision. (Show Details)
kravantokh added a reviewer: emilio.
emilio requested changes to this revision.Feb 11 2024, 9:17 PM

So... Some comments on the approach here. But I think this is not correct. We rely on this color being opaque here:

https://searchfox.org/mozilla-central/rev/1ef947827852125825dda93d8f4f83d1f55739eb/layout/base/PresShell.cpp#5497,5524

Which one of the usages of this was causing problems / couldn't be tweaked?

layout/style/PreferenceSheet.cpp
25 ↗(On Diff #821478)

Then you don't need this and you can use StaticPrefs::browser_display_allow_transparent_background.

modules/libpref/init/all.js
4046 ↗(On Diff #821477)

We should make this a static pref (see StaticPrefList.yaml) instead of using Preferences::GetBool to access it.

This revision now requires changes to proceed.Feb 11 2024, 9:17 PM

Since then I have done some testing and concluded, that the fact that that patch even worked on my system was a miracle (and that my original approach is indeed completely flawed). I have tested it on several systems and it has worked only under sway on AMD/Intel GPUs. It has not worked on sway with an Nvidia GPU. This not as relevant, though, as the way in which it fails.

On some systems it is partially transparent, but then becomes black, when focused. When unfocused it becomes transparent again. This and the fact that in nsWindow::Create (link) everything is done to obtain a transparent window lead me to believe that firefox successfully manages to create a transparent window, as such it should be capable of rendering transparent content, but I have not managed to convince it to do so on any other systems (likely due to some specific quirks in sway's codebase that are not present anywhere else, but that is just speculation), not even the tab and toolbars, which work even on the current firefox release build of my distro (122.0.1) with a certain userChrome.css on sway but not on xwayland (or X) or any other wayland compositor I tried. There it usually shows a gray background.

Moreover I have edited the lines mentioned previously to return a hardcoded color to see which one is relevant and it seems that the first one enforces the opaque background (link), despite the fact that firefox should have a transparent context. That if, as far as I understand, checks exactly that and ensures that the background is opaque when the context (presentation shell?) is opaque. But the context should be transparent (because the window is) and yet it is not. As of now I am yet unsure where this disconnect happens between the main window being created as transparent and its contents detecting it as opaque.

This is what I will be looking into next, trying to find a an approach that hopefully works on all systems I can test it on.

Any suggestions where I should be looking for such things in the codebase @emilio?

kravantokh updated this revision to Diff 826889.
kravantokh edited the summary of this revision. (Show Details)

In the end it seems to work both on wayland and X, although it was a little finicky on an intel iGPU + nvidia GPU laptop. It still does not seem to work on xwayland, though.

EDIT: did some further testing and updated this comment with the new results.

Code analysis found 5 defects in diff 826889:

  • 1 defect found by clang-tidy
  • 2 defects found by clang-format
  • 2 defects found by clang-format (Mozlint)
WARNING: Found 5 defects (warning level) that can be dismissed.

You can run this analysis locally with:

  • ./mach static-analysis check --outgoing (C/C++)
  • ./mach clang-format -p dom/ipc/BrowserParent.cpp widget/gtk/nsWindow.cpp
  • ./mach lint --warnings --outgoing

For your convenience, here is a patch that fixes all the clang-format defects (use it in your repository with hg import or git apply -p0).


If you see a problem in this automated review, please report it here.

You can view these defects in the Diff Detail section of Phabricator diff 826889.

Code analysis found 1 defect in diff 826890:

  • 1 defect found by clang-tidy

1 defect unresolved and 4 defects closed compared to the previous diff 826889.

WARNING: Found 1 defect (warning level) that can be dismissed.

You can run this analysis locally with:

  • ./mach static-analysis check --outgoing (C/C++)

If you see a problem in this automated review, please report it here.

You can view these defects in the Diff Detail section of Phabricator diff 826890.

kravantokh edited the summary of this revision. (Show Details)
emilio requested changes to this revision.Apr 15 2024, 5:40 AM

Sorry, I haven't forgotten about this, I promise...

dom/ipc/BrowserParent.cpp
557 ↗(On Diff #829174)

nsGkAtoms::transparent is just a way of having an interned string in gecko. You can see usage in here for example.

Making all top level websites transparent is likely not what you want? Instead adding transparent: true around here would work better?

widget/gtk/nsWindow.cpp
7074 ↗(On Diff #829174)

Instead of this, bug 1891414 is a better approach which should make this change completely unnecessary.

This revision now requires changes to proceed.Apr 15 2024, 5:40 AM
kravantokh updated this revision to Diff 854991.
kravantokh edited the summary of this revision. (Show Details)

Unfortunately this seems to work only on sway. On Weston and Hyprland, for example, it is bugged. On Hyprland if I move a window over it it just gets imprinted on the firefox window multiple times and the partially transparent background accumulates into full black. On weston all transparent parts simply become black. What I'm suspecting is happening is that the compositor treats the window as if it were opaque and as such it overdraws it instead of redrawing. Perhaps the parts of the codebase that request the window explicitly make it opaque and then this patch makes it transparent anyway and that confuses the compositor? Should I open a new separate issue or should this be solved here as well?

This same problem was happening before, when I did not remove the opaque regions. On sway it worked even then and it works now because it seems not to care about the wl_surface_set_opaque_region hint and fully ignores it and apparently just redraws everything instead of overdrawing on opaque windows. Weston and Hyprland, however, seem to be using the hint to optimize drawing, hence this problem, probably. This is my speculation.

Unfortunately this seems to work only on sway. On Weston and Hyprland, for example, it is bugged. On Hyprland if I move a window over it it just gets imprinted on the firefox window multiple times and the partially transparent background accumulates into full black. On weston all transparent parts simply become black. What I'm suspecting is happening is that the compositor treats the window as if it were opaque and as such it overdraws it instead of redrawing. Perhaps the parts of the codebase that request the window explicitly make it opaque and then this patch makes it transparent anyway and that confuses the compositor? Should I open a new separate issue or should this be solved here as well?

Is the opaque region wrong? After bug 1891414 we should set it correctly... It'd be good to see why that would not be working.

browser/base/content/tabbrowser.js
2179

This would be more consistent as an if below:

if (Services.prefs...()) {
  b.setAttribute("transparent", "true");
}

Much like the others?

I am terribly sorry. It was yet another rookie mistake on my part. I played around some more with the source code and then did a hard reset and pull to sync it up with the remote and then ran moz-phab patch, thinking that it would apply it against the latest changes only to realize now that it put me on a different branch and reverted to the previous version of the code, where this was not yet repaired.

Anyway, now I managed to rebase the commit against the latest ones, that include bug 1891414 and now it works perfectly under both weston and Hyprland.

Thank you a lot for your help, patience and tolerance while guiding me through writing this patch correctly.

kravantokh edited the summary of this revision. (Show Details)
emilio requested changes to this revision.May 1 2024, 12:16 AM
emilio removed a reviewer: emilio.

Thanks, I'm glad that worked properly!

Now that you're only touching the front-end, folks in tabbrowser-reviewers should review this. I dropped a few suggestions but they have the last word on this code :)

browser/base/content/tabbrowser.js
2239

Probably worth a , false and maybe even a lazy pref getter (see this in this same file for an example).

modules/libpref/init/StaticPrefList.yaml
1257 ↗(On Diff #855068)

Now that this is purely a front-end feature, probably worth moving to firefox.js and calling it something like browser.tabs.allow_transparent around here for example?

1262 ↗(On Diff #855068)

If you keep it as a static pref, remove this extra newline.

As such this patch implements all necessary changes to allow users to make firefox transparent

Could you please elaborate on what use case this serves? What kind of users would we expect to touch this pref, to what end?

The main use case for this change is simply aesthetics. A considerable number of users (from what I have seen) like having a transparent terminal and I have met the idea of having the browser be able to do the same in several places. This is mainly about choice: allowing users to opt for this transparent look, should they so desire. In a context where transparent terminals are used having a transparent browser would just make perfect sense, aesthetically speaking.

Along the years there has been at least one attempt to achieve this with a bug in firefox's gif renderer (that has since been fixed). Links: actual config and discussions about it.
Here are some relevant posts I have found: archlinux forums, r/FirefoxCSS, r/firefox.

Looking at these I considered them to be enough reason to implement this change besides the original feature request having been open for over 24 years.

As for the audience, I would expect mostly power users to reach for this option: people who are likely to be using a userChrome.css file anyway. An example of such a set of people would be the r/FirefoxCSS community or part of this other subreddit about good-looking linux configurations (transparent aesthetics are quite frequent over there).
These people would likely have no difficulty in potentially configuring an already existing page recoloring extension such as Dark Reader or this other one or even just straight up writing a custom one to automatically recolor all pages to transparent.

dao requested changes to this revision.May 3 2024, 6:04 PM

Okay, sounds good, I think we can take this. Would you mind addressing Emilio's latest comments?

modules/libpref/init/StaticPrefList.yaml
1257 ↗(On Diff #855068)

I'd prefer browser.tabs.allow_transparent_browser for clarity.

This revision now requires changes to proceed.May 3 2024, 6:04 PM
kravantokh updated this revision to Diff 857921.
kravantokh retitled this revision from Bug 28354 - Added option "browser.display.allow_transparent_background" to "about:config" to stop forcing opaque backgrounds. r=emilio to Bug 28354 - Added option "browser.tabs.allow_transparent_browser" to "about:config" to stop forcing opaque backgrounds. r=dao.
kravantokh edited the summary of this revision. (Show Details)
dao requested changes to this revision.May 7 2024, 4:40 PM
dao added inline comments.
browser/base/content/tabbrowser.js
115

Let's rename this to _allowTransparentBrowser

2237

This should check this._allowTransparentBrowser instead.

This revision now requires changes to proceed.May 7 2024, 4:40 PM
kravantokh updated this revision to Diff 860553.

testing-expection-other: this only adds an about:config pref that we won't officially support

This revision is now accepted and ready to land.May 13 2024, 5:07 PM
emilio added a subscriber: emilio.

rebase on behalf of the author