summaryrefslogtreecommitdiffstats
path: root/widget/cocoa/AppearanceOverride.mm
diff options
context:
space:
mode:
Diffstat (limited to 'widget/cocoa/AppearanceOverride.mm')
-rw-r--r--widget/cocoa/AppearanceOverride.mm100
1 files changed, 100 insertions, 0 deletions
diff --git a/widget/cocoa/AppearanceOverride.mm b/widget/cocoa/AppearanceOverride.mm
new file mode 100644
index 0000000000..3f3d5e38e9
--- /dev/null
+++ b/widget/cocoa/AppearanceOverride.mm
@@ -0,0 +1,100 @@
+/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+#import <Cocoa/Cocoa.h>
+
+#include "AppearanceOverride.h"
+
+#include "mozilla/Preferences.h"
+#include "mozilla/StaticPrefs_browser.h"
+#include "mozilla/StaticPrefs_widget.h"
+
+#include "nsXULAppAPI.h"
+#include "SDKDeclarations.h"
+
+static void ToolbarThemePrefChanged(const char* aPref, void* aUserInfo);
+
+@interface MOZGlobalAppearance ()
+@property NSInteger toolbarTheme;
+@end
+
+@implementation MOZGlobalAppearance
+
++ (MOZGlobalAppearance*)sharedInstance {
+ static MOZGlobalAppearance* sInstance = nil;
+ if (!sInstance) {
+ sInstance = [[MOZGlobalAppearance alloc] init];
+ if (XRE_IsParentProcess()) {
+ mozilla::Preferences::RegisterCallbackAndCall(
+ &ToolbarThemePrefChanged,
+ nsDependentCString(mozilla::StaticPrefs::GetPrefName_browser_theme_toolbar_theme()));
+ }
+ }
+ return sInstance;
+}
+
++ (NSSet*)keyPathsForValuesAffectingAppearance {
+ return [NSSet setWithObjects:@"toolbarTheme", nil];
+}
+
+- (NSAppearance*)appearance {
+ if (@available(macOS 10.14, *)) {
+ switch (self.toolbarTheme) { // Value for browser.theme.toolbar-theme pref
+ case 0: // Dark
+ return [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
+ case 1: // Light
+ return [NSAppearance appearanceNamed:NSAppearanceNameAqua];
+ case 2: // System
+ default:
+ break;
+ }
+ }
+ // nil means "no override".
+ return nil;
+}
+
+- (void)setAppearance:(NSAppearance*)aAppearance {
+ // ignored
+}
+
+- (NSApplication*)_app {
+ return NSApp;
+}
+
++ (NSSet*)keyPathsForValuesAffectingEffectiveAppearance {
+ if (@available(macOS 10.14, *)) {
+ // Automatically notify any key-value observers of our effectiveAppearance property whenever the
+ // pref or the NSApp's effectiveAppearance change.
+ return [NSSet setWithObjects:@"toolbarTheme", @"_app.effectiveAppearance", nil];
+ }
+ return [NSSet set];
+}
+
+- (NSAppearance*)effectiveAppearance {
+ if (@available(macOS 10.14, *)) {
+ switch (self.toolbarTheme) { // Value for browser.theme.toolbar-theme pref
+ case 0: // Dark
+ return [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
+ case 1: // Light
+ return [NSAppearance appearanceNamed:NSAppearanceNameAqua];
+ case 2: // System
+ default:
+ // Use the NSApp effectiveAppearance. This is the system appearance.
+ return NSApp.effectiveAppearance;
+ }
+ }
+ // Use aqua on pre-10.14.
+ return [NSAppearance appearanceNamed:NSAppearanceNameAqua];
+}
+
+@end
+
+static void ToolbarThemePrefChanged(const char* aPref, void* aUserInfo) {
+ MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
+ MOZ_RELEASE_ASSERT(NS_IsMainThread());
+
+ MOZGlobalAppearance.sharedInstance.toolbarTheme =
+ mozilla::StaticPrefs::browser_theme_toolbar_theme();
+}