tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit b49c6ab85ff5ec5d6fd49b8aa6c5643edec554e0
parent bb70a75a721c6e6ed662c190f7ecf408a5e418b7
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date:   Tue, 23 Dec 2025 19:08:08 +0000

Bug 2007558 - Make transparent attribute work dynamically. r=Gijs

Differential Revision: https://phabricator.services.mozilla.com/D277444

Diffstat:
Mdom/ipc/BrowserChild.cpp | 7+++++++
Mdom/ipc/BrowserChild.h | 2++
Mdom/ipc/BrowserParent.cpp | 21+++++++++++++--------
Mdom/ipc/BrowserParent.h | 4++++
Mdom/ipc/PBrowser.ipdl | 6++++++
Mdom/ipc/tests/browser.toml | 2++
Adom/ipc/tests/browser_transparent.js | 35+++++++++++++++++++++++++++++++++++
Mdom/xul/XULFrameElement.cpp | 6++++++
8 files changed, 75 insertions(+), 8 deletions(-)

diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp @@ -3653,6 +3653,13 @@ mozilla::ipc::IPCResult BrowserChild::RecvUIResolutionChanged( return IPC_OK(); } +mozilla::ipc::IPCResult BrowserChild::RecvTransparencyChanged( + const bool& aIsTransparent) { + mIsTransparent = aIsTransparent; + SchedulePaint(); + return IPC_OK(); +} + mozilla::ipc::IPCResult BrowserChild::RecvSafeAreaInsetsChanged( const mozilla::LayoutDeviceIntMargin& aSafeAreaInsets) { mPuppetWidget->UpdateSafeAreaInsets(aSafeAreaInsets); diff --git a/dom/ipc/BrowserChild.h b/dom/ipc/BrowserChild.h @@ -525,6 +525,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor, const int32_t& aRounding, const double& aScale); + mozilla::ipc::IPCResult RecvTransparencyChanged(const bool& aIsTransparent); + mozilla::ipc::IPCResult RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent, nsTArray<uint32_t>&& aCharCodes); MOZ_CAN_RUN_SCRIPT_BOUNDARY diff --git a/dom/ipc/BrowserParent.cpp b/dom/ipc/BrowserParent.cpp @@ -572,19 +572,18 @@ BrowserBridgeParent* BrowserParent::GetBrowserBridgeParent() const { BrowserHost* BrowserParent::GetBrowserHost() const { return mBrowserHost; } +bool BrowserParent::IsTransparent() const { + return mFrameElement && mFrameElement->HasAttr(nsGkAtoms::transparent) && + nsContentUtils::IsChromeDoc(mFrameElement->OwnerDoc()); +} + ParentShowInfo BrowserParent::GetShowInfo() { TryCacheDPIAndScale(); + nsAutoString name; if (mFrameElement) { - nsAutoString name; mFrameElement->GetAttr(nsGkAtoms::name, name); - bool isTransparent = - nsContentUtils::IsChromeDoc(mFrameElement->OwnerDoc()) && - mFrameElement->HasAttr(nsGkAtoms::transparent); - return ParentShowInfo(name, false, isTransparent, mDPI, mRounding, - mDefaultScale.scale); } - - return ParentShowInfo(u""_ns, false, false, mDPI, mRounding, + return ParentShowInfo(name, false, IsTransparent(), mDPI, mRounding, mDefaultScale.scale); } @@ -3717,6 +3716,12 @@ void BrowserParent::NotifyResolutionChanged() { mDPI < 0 ? -1.0 : mDefaultScale.scale); } +void BrowserParent::NotifyTransparencyChanged() { + if (!mIsDestroyed) { + (void)SendTransparencyChanged(IsTransparent()); + } +} + bool BrowserParent::CanCancelContentJS( nsIRemoteTab::NavigationType aNavigationType, int32_t aNavigationIndex, nsIURI* aNavigationURI) const { diff --git a/dom/ipc/BrowserParent.h b/dom/ipc/BrowserParent.h @@ -204,6 +204,9 @@ class BrowserParent final : public PBrowserParent, */ bool CreatingWindow() const { return mCreatingWindow; } + // Whether our embedder can render transparent. + bool IsTransparent() const; + /* * Visit each BrowserParent in the tree formed by PBrowser and * PBrowserBridge, including `this`. @@ -707,6 +710,7 @@ class BrowserParent final : public PBrowserParent, void SetPriorityHint(bool aPriorityHint); void PreserveLayers(bool aPreserveLayers); void NotifyResolutionChanged(); + void NotifyTransparencyChanged(); bool CanCancelContentJS(nsIRemoteTab::NavigationType aNavigationType, int32_t aNavigationIndex, diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl @@ -939,6 +939,12 @@ child: async UIResolutionChanged(float dpi, int32_t rounding, double scale); /** + * Tell the child that whether it's allowed to render transparent has + * changed. See also ParentShowInfo::isTransparent. + */ + async TransparencyChanged(bool transparent); + + /** * Tell the child that the safe area of widget has changed. * */ diff --git a/dom/ipc/tests/browser.toml b/dom/ipc/tests/browser.toml @@ -83,6 +83,8 @@ skip-if = [ ["browser_subframesPreferUsed.js"] +["browser_transparent.js"] + ["browser_very_fission.js"] support-files = ["file_dummy.html"] run-if = [ diff --git a/dom/ipc/tests/browser_transparent.js b/dom/ipc/tests/browser_transparent.js @@ -0,0 +1,35 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +function getContentCanvasBg(browser) { + return SpecialPowers.spawn(browser, [], () => { + return content.windowUtils.canvasBackgroundColor; + }); +} + +add_task(async function test_transparent_dynamic() { + await BrowserTestUtils.withNewTab( + `data:text/html,hello`, + async function (browser) { + is( + await getContentCanvasBg(browser), + "rgb(255, 255, 255)", + "Content bg should be white" + ); + browser.toggleAttribute("transparent", true); + is( + await getContentCanvasBg(browser), + "rgba(0, 0, 0, 0)", + "Content bg should be transparent" + ); + browser.toggleAttribute("transparent", false); + is( + await getContentCanvasBg(browser), + "rgb(255, 255, 255)", + "Content bg should be white again" + ); + } + ); +}); diff --git a/dom/xul/XULFrameElement.cpp b/dom/xul/XULFrameElement.cpp @@ -7,6 +7,7 @@ #include "mozilla/dom/XULFrameElement.h" #include "mozilla/AsyncEventDispatcher.h" +#include "mozilla/dom/BrowserParent.h" #include "mozilla/dom/HTMLIFrameElement.h" #include "mozilla/dom/WindowProxyHolder.h" #include "mozilla/dom/XULFrameElementBinding.h" @@ -191,6 +192,11 @@ void XULFrameElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName, if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) { MOZ_ALWAYS_SUCCEEDS(bc->SetFullscreenAllowedByOwner(!aValue)); } + } else if (aName == nsGkAtoms::transparent && mFrameLoader && + (!!aValue != !!aOldValue)) { + if (auto* bp = mFrameLoader->GetBrowserParent()) { + bp->NotifyTransparencyChanged(); + } } }