gh-12464: Implement a more efficient way of adding macos translucency (gh-15006)

This commit is contained in:
mr. m
2026-08-18 00:19:24 +02:00
committed by GitHub
parent 9f2771aff6
commit e2e1ab4e6d
6 changed files with 179 additions and 54 deletions

View File

@@ -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

View File

@@ -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,

View File

@@ -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<ThemeGeometry>& 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;

View File

@@ -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<ZenWindowMaterialView*>(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<nsCocoaWindow*>(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();

View File

@@ -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.

View File

@@ -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();