From e2e1ab4e6df8762453cc0db1f2515a291c42b865 Mon Sep 17 00:00:00 2001 From: "mr. m" <91018726+mr-cheffy@users.noreply.github.com> Date: Tue, 18 Aug 2026 00:19:24 +0200 Subject: [PATCH] gh-12464: Implement a more efficient way of adding macos translucency (gh-15006) --- prefs/zen/macos.yaml | 8 +- src/widget/cocoa/VibrancyManager-mm.patch | 43 +------ src/widget/cocoa/nsCocoaWindow-h.patch | 23 ++++ src/widget/cocoa/nsCocoaWindow-mm.patch | 134 ++++++++++++++++++++++ src/zen/common/styles/zen-browser-ui.css | 9 -- src/zen/common/sys/ZenUIMigration.sys.mjs | 16 ++- 6 files changed, 179 insertions(+), 54 deletions(-) create mode 100644 src/widget/cocoa/nsCocoaWindow-h.patch create mode 100644 src/widget/cocoa/nsCocoaWindow-mm.patch diff --git a/prefs/zen/macos.yaml b/prefs/zen/macos.yaml index abca5c987..3f3fd2f18 100644 --- a/prefs/zen/macos.yaml +++ b/prefs/zen/macos.yaml @@ -2,10 +2,14 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -# Enable transparent background for macos -- name: widget.macos.sidebar-blend-mode.behind-window +# Give the whole window a translucent, blurred backdrop, using the material +# below. See ZenWindowMaterialView in nsCocoaWindow.mm. +- name: zen.widget.macos.window-vibrancy value: true condition: "defined(XP_MACOSX)" + cpptype: bool + mirror: always + type: static # 1. hudWindow # 2. fullScreenUI diff --git a/src/widget/cocoa/VibrancyManager-mm.patch b/src/widget/cocoa/VibrancyManager-mm.patch index 0c899dc86..52a41a5a9 100644 --- a/src/widget/cocoa/VibrancyManager-mm.patch +++ b/src/widget/cocoa/VibrancyManager-mm.patch @@ -1,5 +1,5 @@ diff --git a/widget/cocoa/VibrancyManager.mm b/widget/cocoa/VibrancyManager.mm -index bc62ff28285691c605fe0680e7a98927f11d5882..63403611b9c5c5d12fe221c2bb56f884fabe85ba 100644 +index bc62ff28285691c605fe0680e7a98927f11d5882..c209b63179df298e9b43182813ba0045f08328cc 100644 --- a/widget/cocoa/VibrancyManager.mm +++ b/widget/cocoa/VibrancyManager.mm @@ -9,6 +9,7 @@ @@ -20,44 +20,3 @@ index bc62ff28285691c605fe0680e7a98927f11d5882..63403611b9c5c5d12fe221c2bb56f884 return NSVisualEffectStateFollowsWindowActiveState; } -@@ -35,7 +39,23 @@ static NSVisualEffectMaterial VisualEffectMaterialForVibrancyType( - VibrancyType aType) { - switch (aType) { - case VibrancyType::Sidebar: -- return NSVisualEffectMaterialSidebar; -+ switch (StaticPrefs::zen_widget_macos_window_material()) { -+ case 1: -+ return NSVisualEffectMaterialHUDWindow; -+ case 2: -+ return NSVisualEffectMaterialFullScreenUI; -+ case 3: -+ return NSVisualEffectMaterialPopover; -+ case 4: -+ return NSVisualEffectMaterialMenu; -+ case 5: -+ return NSVisualEffectMaterialToolTip; -+ case 6: -+ return NSVisualEffectMaterialHeaderView; -+ case 7: -+ default: -+ return NSVisualEffectMaterialUnderWindowBackground; -+ } - case VibrancyType::Titlebar: - return NSVisualEffectMaterialTitlebar; - } -@@ -75,6 +95,7 @@ - (NSView*)hitTest:(NSPoint)aPoint { - - - (void)prefChanged { - self.blendingMode = VisualEffectBlendingModeForVibrancyType(mType); -+ self.material = VisualEffectMaterialForVibrancyType(mType); - } - @end - -@@ -85,6 +106,7 @@ static void PrefChanged(const char* aPref, void* aClosure) { - static constexpr nsLiteralCString kObservedPrefs[] = { - "widget.macos.sidebar-blend-mode.behind-window"_ns, - "widget.macos.titlebar-blend-mode.behind-window"_ns, -+ "zen.widget.macos.window-material"_ns, - }; - - VibrancyManager::VibrancyManager(const nsCocoaWindow& aCoordinateConverter, diff --git a/src/widget/cocoa/nsCocoaWindow-h.patch b/src/widget/cocoa/nsCocoaWindow-h.patch new file mode 100644 index 000000000..77f4033c0 --- /dev/null +++ b/src/widget/cocoa/nsCocoaWindow-h.patch @@ -0,0 +1,23 @@ +diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h +index 312011c1c2ac41e78affecbdef25d72766a7c882..e5865c7d6259f0a3df48edf7a26b1b75a23cdb3a 100644 +--- a/widget/cocoa/nsCocoaWindow.h ++++ b/widget/cocoa/nsCocoaWindow.h +@@ -462,6 +462,10 @@ class nsCocoaWindow final : public nsIWidget { + void SetHideTitlebarSeparator(bool) override; + bool IsMacTitlebarDirectionRTL() override; + void SetCustomTitlebar(bool) override; ++ void SetWindowClass(const nsAString& aXulWinType, ++ const nsAString& aXulWinClass, ++ const nsAString& aXulWinName) override; ++ void UpdateWindowMaterial(); + void UpdateThemeGeometries( + const nsTArray& aThemeGeometries) override; + void LockAspectRatio(bool aShouldLock) override; +@@ -672,6 +676,7 @@ class nsCocoaWindow final : public nsIWidget { + bool mAspectRatioLocked = false; + bool mIsAlert = false; // True if this is an non-native alert window. + bool mWasShown = false; ++ bool mIsBrowserWindow = false; + + int32_t mNumModalDescendants = 0; + diff --git a/src/widget/cocoa/nsCocoaWindow-mm.patch b/src/widget/cocoa/nsCocoaWindow-mm.patch new file mode 100644 index 000000000..983efe466 --- /dev/null +++ b/src/widget/cocoa/nsCocoaWindow-mm.patch @@ -0,0 +1,134 @@ +diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm +index 2efd02e4a92433fd29bbfdb707aa81cfec45031e..3b763c3927f07e529c826f8e4f62bc80a324b247 100644 +--- a/widget/cocoa/nsCocoaWindow.mm ++++ b/widget/cocoa/nsCocoaWindow.mm +@@ -86,6 +86,7 @@ + #include "mozilla/StaticPrefs_gfx.h" + #include "mozilla/StaticPrefs_ui.h" + #include "mozilla/StaticPrefs_widget.h" ++#include "mozilla/StaticPrefs_zen.h" + #include "mozilla/WritingModes.h" + #include "mozilla/dom/Document.h" + #include "mozilla/layers/CompositorBridgeChild.h" +@@ -1332,6 +1333,110 @@ - (NSRect)_opaqueRectForWindowMoveWhenInTitlebar { + } + @end + ++@interface ZenWindowMaterialView : NSVisualEffectView ++- (void)prefChanged; ++@end ++ ++static void ZenWindowMaterialPrefChanged(const char* aPref, void* aClosure) { ++ [static_cast(aClosure) prefChanged]; ++} ++ ++static constexpr nsLiteralCString kZenWindowMaterialPrefs[] = { ++ "zen.widget.macos.window-material"_ns, ++ "zen.view.grey-out-inactive-windows"_ns, ++}; ++ ++static NSVisualEffectMaterial ZenWindowMaterial() { ++ switch (StaticPrefs::zen_widget_macos_window_material()) { ++ case 1: ++ return NSVisualEffectMaterialHUDWindow; ++ case 2: ++ return NSVisualEffectMaterialFullScreenUI; ++ case 3: ++ return NSVisualEffectMaterialPopover; ++ case 4: ++ return NSVisualEffectMaterialMenu; ++ case 5: ++ return NSVisualEffectMaterialToolTip; ++ case 6: ++ return NSVisualEffectMaterialHeaderView; ++ case 7: ++ default: ++ return NSVisualEffectMaterialUnderWindowBackground; ++ } ++} ++ ++@implementation ZenWindowMaterialView ++- (instancetype)initWithFrame:(NSRect)aRect { ++ self = [super initWithFrame:aRect]; ++ self.appearance = nil; ++ self.emphasized = NO; ++ self.blendingMode = NSVisualEffectBlendingModeBehindWindow; ++ [self prefChanged]; ++ for (const auto& pref : kZenWindowMaterialPrefs) { ++ Preferences::RegisterCallback(ZenWindowMaterialPrefChanged, pref, self); ++ } ++ return self; ++} ++ ++- (void)dealloc { ++ for (const auto& pref : kZenWindowMaterialPrefs) { ++ Preferences::UnregisterCallback(ZenWindowMaterialPrefChanged, pref, self); ++ } ++ [super dealloc]; ++} ++ ++- (void)prefChanged { ++ self.state = StaticPrefs::zen_view_grey_out_inactive_windows() ++ ? NSVisualEffectStateFollowsWindowActiveState ++ : NSVisualEffectStateActive; ++ self.material = ZenWindowMaterial(); ++} ++@end ++ ++static void ZenWindowVibrancyPrefChanged(const char* aPref, void* aClosure) { ++ static_cast(aClosure)->UpdateWindowMaterial(); ++} ++ ++void nsCocoaWindow::SetWindowClass(const nsAString& aXulWinType, ++ const nsAString& aXulWinClass, ++ const nsAString& aXulWinName) { ++ if (mWindowType != WindowType::TopLevel || mIsBrowserWindow || ++ !aXulWinType.EqualsLiteral("navigator:browser")) { ++ return; ++ } ++ mIsBrowserWindow = true; ++ Preferences::RegisterCallback(ZenWindowVibrancyPrefChanged, ++ "zen.widget.macos.window-vibrancy", this); ++ UpdateWindowMaterial(); ++} ++ ++void nsCocoaWindow::UpdateWindowMaterial() { ++ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK; ++ ++ if (!mWindow) { ++ return; ++ } ++ bool wanted = StaticPrefs::zen_widget_macos_window_vibrancy(); ++ if (wanted == ++ [mWindow.contentView isKindOfClass:[ZenWindowMaterialView class]]) { ++ return; ++ } ++ ++ NSRect frame = mWindow.contentView.frame; ++ NSView* wrapper = wanted ? [[ZenWindowMaterialView alloc] initWithFrame:frame] ++ : [[NSView alloc] initWithFrame:frame]; ++ wrapper.wantsLayer = YES; ++ for (NSView* view in [mWindow contentViewContents]) { ++ [view removeFromSuperviewWithoutNeedingDisplay]; ++ [wrapper addSubview:view]; ++ } ++ mWindow.contentView = wrapper; ++ [wrapper release]; ++ ++ NS_OBJC_END_TRY_IGNORE_BLOCK; ++} ++ + void nsCocoaWindow::UpdateWindowDraggingRegion( + const LayoutDeviceIntRegion& aRegion) { + // mChildView returns YES from mouseDownCanMoveWindow, so we need to put +@@ -4919,6 +5024,10 @@ - (BOOL)wantsBestResolutionOpenGLSurface { + nsCocoaWindow::~nsCocoaWindow() { + NS_OBJC_BEGIN_TRY_IGNORE_BLOCK; + ++ if (mIsBrowserWindow) { ++ Preferences::UnregisterCallback(ZenWindowVibrancyPrefChanged, ++ "zen.widget.macos.window-vibrancy", this); ++ } + RemoveAllChildren(); + if (mWindow && mWindowMadeHere) { + CancelAllTransitions(); diff --git a/src/zen/common/styles/zen-browser-ui.css b/src/zen/common/styles/zen-browser-ui.css index 01966ce3d..7308f9e58 100644 --- a/src/zen/common/styles/zen-browser-ui.css +++ b/src/zen/common/styles/zen-browser-ui.css @@ -113,15 +113,6 @@ body, } #zen-browser-background { - /* This is conceptually a background, but putting this on a pseudo-element - * avoids it from suppressing the chrome-content separator border, etc. - * - * See bugzilla's 1949528 and bug 1476281 (which would make this unnecessary). */ - @media (-moz-platform: macos) { - -moz-default-appearance: -moz-sidebar; - appearance: auto; - } - /* * Important: We set the color to `AccentColor` so we can * Compute the stylings and get the native accent color. diff --git a/src/zen/common/sys/ZenUIMigration.sys.mjs b/src/zen/common/sys/ZenUIMigration.sys.mjs index d025d97df..fd6bbe4f0 100644 --- a/src/zen/common/sys/ZenUIMigration.sys.mjs +++ b/src/zen/common/sys/ZenUIMigration.sys.mjs @@ -12,7 +12,7 @@ ChromeUtils.defineESModuleGetters(lazy, { class nsZenUIMigration { PREF_NAME = "zen.ui.migration.version"; - MIGRATION_VERSION = 6; + MIGRATION_VERSION = 7; init(isNewProfile) { if (!isNewProfile) { @@ -150,6 +150,20 @@ class nsZenUIMigration { }, 1000); }); } + + _migrateV7() { + if ( + AppConstants.platform === "macosx" && + Services.prefs.prefHasUserValue( + "widget.macos.sidebar-blend-mode.behind-window" + ) && + !Services.prefs.getBoolPref( + "widget.macos.sidebar-blend-mode.behind-window" + ) + ) { + Services.prefs.setBoolPref("zen.widget.macos.window-vibrancy", false); + } + } } export var gZenUIMigration = new nsZenUIMigration();