fune/widget/cocoa/nsLookAndFeel.mm
Emilio Cobos Álvarez 5f05578314 Bug 1036966 - Make accessibility.tabfocus default to 7 on macOS too. r=morgan,settings-reviewers,mac-reviewers,mstange
Stop supporting following the system preference, but keep macOS users
able to switch to just text controls (accessibility.tabfocus=1) in the
settings.

Change the meaning of the "Use the tab key to move focus between form
controls and links" checkbox in the Firefox settings, which was
introduced in bug 1628476 to override the system setting.

The intention, I think was that this checkbox being off resulted in
"follow the system" behavior, but that didn't quite happen due to a bug
in the preferences code (this[1] won't unset the pref, because of
this[2], which means we'll just return 0).

This patch changes it so that the checkbox instead always ignores the
system setting. There will no longer be a Firefox setting (neither in
the UI nor on about:config) that means "follow system setting".

This allows us to somewhat simplify the approach compared to the
previous patch in D196110, and keep the accessibility.tabfocus working
as the source of truth without a migration.

In the future, we can think of migrating accessibility.tabfocus to a
boolean pref, which would allow us to do the cleanups to the preferences
code that D196110 did.

[1]: https://searchfox.org/mozilla-central/rev/f1532761de0b60337e42c6c3f525288a523dabef/browser/components/preferences/main.js#2252
[2]: https://searchfox.org/mozilla-central/rev/f1532761de0b60337e42c6c3f525288a523dabef/toolkit/content/preferencesBindings.js#450,483

Differential Revision: https://phabricator.services.mozilla.com/D208602
2024-05-03 23:10:47 +00:00

679 lines
23 KiB
Text

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "mozilla/widget/ThemeChangeKind.h"
#include "nsLookAndFeel.h"
#include "nsCocoaFeatures.h"
#include "nsNativeThemeColors.h"
#include "nsStyleConsts.h"
#include "nsIContent.h"
#include "gfxFont.h"
#include "gfxFontConstants.h"
#include "gfxPlatformMac.h"
#include "nsCSSColorUtils.h"
#include "mozilla/FontPropertyTypes.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/StaticPrefs_widget.h"
#include "mozilla/Telemetry.h"
#include "mozilla/widget/WidgetMessageUtils.h"
#import <Cocoa/Cocoa.h>
#import <AppKit/NSColor.h>
// This must be included last:
#include "nsObjCExceptions.h"
using namespace mozilla;
@interface MOZLookAndFeelDynamicChangeObserver : NSObject
+ (void)startObserving;
@end
nsLookAndFeel::nsLookAndFeel() {
[MOZLookAndFeelDynamicChangeObserver startObserving];
}
nsLookAndFeel::~nsLookAndFeel() = default;
void nsLookAndFeel::EnsureInit() {
if (mInitialized) {
return;
}
NS_OBJC_BEGIN_TRY_ABORT_BLOCK
mInitialized = true;
NSWindow* window =
[[NSWindow alloc] initWithContentRect:NSZeroRect
styleMask:NSWindowStyleMaskTitled
backing:NSBackingStoreBuffered
defer:NO];
auto release = MakeScopeExit([&] { [window release]; });
mRtl = window.windowTitlebarLayoutDirection ==
NSUserInterfaceLayoutDirectionRightToLeft;
mTitlebarHeight = std::ceil(window.frame.size.height);
RecordTelemetry();
NS_OBJC_END_TRY_ABORT_BLOCK
}
void nsLookAndFeel::RefreshImpl() {
mInitialized = false;
nsXPLookAndFeel::RefreshImpl();
}
static nscolor GetColorFromNSColor(NSColor* aColor) {
NSColor* deviceColor =
[aColor colorUsingColorSpace:NSColorSpace.deviceRGBColorSpace];
return NS_RGBA((unsigned int)(deviceColor.redComponent * 255.0),
(unsigned int)(deviceColor.greenComponent * 255.0),
(unsigned int)(deviceColor.blueComponent * 255.0),
(unsigned int)(deviceColor.alphaComponent * 255.0));
}
static nscolor GetColorFromNSColorWithCustomAlpha(NSColor* aColor,
float alpha) {
NSColor* deviceColor =
[aColor colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];
return NS_RGBA((unsigned int)(deviceColor.redComponent * 255.0),
(unsigned int)(deviceColor.greenComponent * 255.0),
(unsigned int)(deviceColor.blueComponent * 255.0),
(unsigned int)(alpha * 255.0));
}
// Turns an opaque selection color into a partially transparent selection color,
// which usually leads to better contrast with the text color and which should
// look more visually appealing in most contexts.
// The idea is that the text and its regular, non-selected background are
// usually chosen in such a way that they contrast well. Making the selection
// color partially transparent causes the selection color to mix with the text's
// regular background, so the end result will often have better contrast with
// the text than an arbitrary opaque selection color.
// The motivating example for this is the light selection color on dark web
// pages: White text on a light blue selection color has very bad contrast,
// whereas white text on dark blue (which what you get if you mix
// partially-transparent light blue with the black textbox background) has much
// better contrast.
static nscolor ProcessSelectionBackground(nscolor aColor, ColorScheme aScheme) {
if (aScheme == ColorScheme::Dark) {
// When we use a dark selection color, we do not change alpha because we do
// not use dark selection in content. The dark system color is appropriate
// for Firefox UI without needing to adjust its alpha.
return aColor;
}
uint16_t hue, sat, value;
uint8_t alpha;
nscolor resultColor = aColor;
NS_RGB2HSV(resultColor, hue, sat, value, alpha);
int factor = 2;
alpha = alpha / factor;
if (sat > 0) {
// The color is not a shade of grey, restore the saturation taken away by
// the transparency.
sat = mozilla::clamped(sat * factor, 0, 255);
} else {
// The color is a shade of grey, find the value that looks equivalent
// on a white background with the given opacity.
value = mozilla::clamped(255 - (255 - value) * factor, 0, 255);
}
NS_HSV2RGB(resultColor, hue, sat, value, alpha);
return resultColor;
}
nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme,
nscolor& aColor) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK
NSAppearance.currentAppearance = NSAppearanceForColorScheme(aScheme);
nscolor color = 0;
switch (aID) {
case ColorID::Infobackground:
color = aScheme == ColorScheme::Light
? NS_RGB(0xdd, 0xdd, 0xdd)
: GetColorFromNSColor(NSColor.windowBackgroundColor);
break;
case ColorID::Highlight:
color = ProcessSelectionBackground(
GetColorFromNSColor(NSColor.selectedTextBackgroundColor), aScheme);
break;
// This is used to gray out the selection when it's not focused. Used with
// nsISelectionController::SELECTION_DISABLED.
case ColorID::TextSelectDisabledBackground:
color = ProcessSelectionBackground(
GetColorFromNSColor(NSColor.secondarySelectedControlColor), aScheme);
break;
case ColorID::MozMenuhoverdisabled:
aColor = NS_TRANSPARENT;
break;
case ColorID::Accentcolor:
color = GetColorFromNSColor(NSColor.controlAccentColor);
break;
case ColorID::MozMenuhover:
case ColorID::Selecteditem:
color = GetColorFromNSColor(NSColor.selectedContentBackgroundColor);
if (aID == ColorID::MozMenuhover &&
!LookAndFeel::GetInt(IntID::PrefersReducedTransparency)) {
// Wash the color a little bit with semi-transparent white to match a
// bit closer the native NSVisualEffectSelection on menus.
color = NS_ComposeColors(
color,
NS_RGBA(255, 255, 255, aScheme == ColorScheme::Light ? 51 : 25));
}
break;
case ColorID::Accentcolortext:
case ColorID::MozMenuhovertext:
case ColorID::Selecteditemtext:
color = GetColorFromNSColor(NSColor.selectedMenuItemTextColor);
break;
case ColorID::IMESelectedRawTextBackground:
case ColorID::IMESelectedConvertedTextBackground:
case ColorID::IMERawInputBackground:
case ColorID::IMEConvertedTextBackground:
color = NS_TRANSPARENT;
break;
case ColorID::IMESelectedRawTextForeground:
case ColorID::IMESelectedConvertedTextForeground:
case ColorID::IMERawInputForeground:
case ColorID::IMEConvertedTextForeground:
case ColorID::Highlighttext:
color = NS_SAME_AS_FOREGROUND_COLOR;
break;
case ColorID::IMERawInputUnderline:
case ColorID::IMEConvertedTextUnderline:
color = NS_40PERCENT_FOREGROUND_COLOR;
break;
case ColorID::IMESelectedRawTextUnderline:
case ColorID::IMESelectedConvertedTextUnderline:
color = NS_SAME_AS_FOREGROUND_COLOR;
break;
//
// css2 system colors http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
//
// It's really hard to effectively map these to the Appearance Manager
// properly, since they are modeled word for word after the win32 system
// colors and don't have any real counterparts in the Mac world. I'm sure
// we'll be tweaking these for years to come.
//
// Thanks to mpt26@student.canterbury.ac.nz for the hardcoded values that
// form the defaults
// if querying the Appearance Manager fails ;)
//
case ColorID::MozMacDefaultbuttontext:
color = NS_RGB(0xFF, 0xFF, 0xFF);
break;
case ColorID::MozSidebar:
color = aScheme == ColorScheme::Light ? NS_RGB(0xf6, 0xf6, 0xf6)
: NS_RGB(0x2d, 0x2d, 0x2d);
break;
case ColorID::MozSidebarborder:
// hsla(240, 5%, 5%, .1)
color = NS_RGBA(12, 12, 13, 26);
break;
case ColorID::MozButtonactivetext:
// Pre-macOS 12, pressed buttons were filled with the highlight color and
// the text was white. Starting with macOS 12, pressed (non-default)
// buttons are filled with medium gray and the text color is the same as
// in the non-pressed state.
color = nsCocoaFeatures::OnMontereyOrLater()
? GetColorFromNSColor(NSColor.controlTextColor)
: NS_RGB(0xFF, 0xFF, 0xFF);
break;
case ColorID::Windowtext:
case ColorID::MozDialogtext:
color = GetColorFromNSColor(NSColor.windowFrameTextColor);
break;
case ColorID::Appworkspace:
color = NS_RGB(0xFF, 0xFF, 0xFF);
break;
case ColorID::Background:
color = NS_RGB(0x63, 0x63, 0xCE);
break;
case ColorID::Buttonface:
case ColorID::MozButtonhoverface:
case ColorID::MozButtonactiveface:
case ColorID::MozButtondisabledface:
case ColorID::MozColheader:
case ColorID::MozColheaderhover:
case ColorID::MozColheaderactive:
color = GetColorFromNSColor(NSColor.controlColor);
if (!NS_GET_A(color)) {
color = GetColorFromNSColor(NSColor.controlBackgroundColor);
}
break;
case ColorID::Buttonhighlight:
color = GetColorFromNSColor(NSColor.selectedControlColor);
break;
case ColorID::Scrollbar:
color = GetColorFromNSColor(NSColor.scrollBarColor);
break;
case ColorID::Threedhighlight:
color = GetColorFromNSColor(NSColor.highlightColor);
break;
case ColorID::Buttonshadow:
case ColorID::Threeddarkshadow:
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID)
: NS_RGB(0xDC, 0xDC, 0xDC);
break;
case ColorID::Threedshadow:
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID)
: NS_RGB(0xE0, 0xE0, 0xE0);
break;
case ColorID::Threedface:
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID)
: NS_RGB(0xF0, 0xF0, 0xF0);
break;
case ColorID::Threedlightshadow:
case ColorID::Buttonborder:
case ColorID::MozDisabledfield:
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID)
: NS_RGB(0xDA, 0xDA, 0xDA);
break;
case ColorID::Menu:
// Hand-picked from Sonoma because there doesn't seem to be any
// appropriate menu system color.
color = aScheme == ColorScheme::Dark ? NS_RGB(0x36, 0x36, 0x39)
: NS_RGB(0xeb, 0xeb, 0xeb);
break;
case ColorID::Windowframe:
color = GetColorFromNSColor(NSColor.windowFrameColor);
break;
case ColorID::MozDialog:
case ColorID::Window:
color = GetColorFromNSColor(aScheme == ColorScheme::Light
? NSColor.windowBackgroundColor
: NSColor.underPageBackgroundColor);
break;
case ColorID::Field:
case ColorID::MozCombobox:
color = GetColorFromNSColor(NSColor.controlBackgroundColor);
break;
case ColorID::Fieldtext:
case ColorID::MozComboboxtext:
case ColorID::Buttontext:
case ColorID::MozButtonhovertext:
case ColorID::Menutext:
case ColorID::Infotext:
case ColorID::MozCellhighlighttext:
case ColorID::MozColheadertext:
case ColorID::MozColheaderhovertext:
case ColorID::MozColheaderactivetext:
case ColorID::MozSidebartext:
color = GetColorFromNSColor(NSColor.controlTextColor);
break;
case ColorID::MozMacFocusring:
color = GetColorFromNSColorWithCustomAlpha(
NSColor.keyboardFocusIndicatorColor, 0.48);
break;
case ColorID::MozMacDisabledtoolbartext:
case ColorID::Graytext:
color = GetColorFromNSColor(NSColor.disabledControlTextColor);
break;
case ColorID::MozCellhighlight:
// For inactive list selection
color = GetColorFromNSColor(NSColor.secondarySelectedControlColor);
break;
case ColorID::MozEventreerow:
// Background color of even list rows.
color =
GetColorFromNSColor(NSColor.controlAlternatingRowBackgroundColors[0]);
break;
case ColorID::MozOddtreerow:
// Background color of odd list rows.
color =
GetColorFromNSColor(NSColor.controlAlternatingRowBackgroundColors[1]);
break;
case ColorID::MozNativehyperlinktext:
color = GetColorFromNSColor(NSColor.linkColor);
break;
case ColorID::MozNativevisitedhyperlinktext:
color = GetColorFromNSColor(NSColor.systemPurpleColor);
break;
case ColorID::MozHeaderbartext:
case ColorID::MozHeaderbarinactivetext:
case ColorID::Inactivecaptiontext:
case ColorID::Captiontext:
aColor = GetColorFromNSColor(NSColor.textColor);
return NS_OK;
case ColorID::MozHeaderbar:
case ColorID::MozHeaderbarinactive:
case ColorID::Inactivecaption:
case ColorID::Activecaption:
// This has better contrast than the stand-in colors.
aColor = GetColorFromNSColor(NSColor.windowBackgroundColor);
return NS_OK;
case ColorID::Marktext:
case ColorID::Mark:
case ColorID::SpellCheckerUnderline:
case ColorID::Activeborder:
case ColorID::Inactiveborder:
case ColorID::MozAutofillBackground:
aColor = GetStandinForNativeColor(aID, aScheme);
return NS_OK;
default:
aColor = NS_RGB(0xff, 0xff, 0xff);
return NS_ERROR_FAILURE;
}
aColor = color;
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK
}
static bool SystemWantsDarkTheme() {
// This returns true if the macOS system appearance is set to dark mode,
// false otherwise.
NSAppearanceName aquaOrDarkAqua =
[NSApp.effectiveAppearance bestMatchFromAppearancesWithNames:@[
NSAppearanceNameAqua, NSAppearanceNameDarkAqua
]];
return [aquaOrDarkAqua isEqualToString:NSAppearanceNameDarkAqua];
}
nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsresult res = NS_OK;
switch (aID) {
case IntID::ScrollButtonLeftMouseButtonAction:
aResult = 0;
break;
case IntID::ScrollButtonMiddleMouseButtonAction:
case IntID::ScrollButtonRightMouseButtonAction:
aResult = 3;
break;
case IntID::CaretBlinkTime:
aResult = 567;
break;
case IntID::CaretWidth:
aResult = 1;
break;
case IntID::SelectTextfieldsOnKeyFocus:
// Select textfield content when focused by kbd
// used by EventStateManager::sTextfieldSelectModel
aResult = 1;
break;
case IntID::SubmenuDelay:
aResult = 200;
break;
case IntID::MenusCanOverlapOSBar:
// xul popups are not allowed to overlap the menubar.
aResult = 0;
break;
case IntID::SkipNavigatingDisabledMenuItem:
aResult = 1;
break;
case IntID::DragThresholdX:
case IntID::DragThresholdY:
aResult = 4;
break;
case IntID::ScrollArrowStyle:
aResult = eScrollArrow_None;
break;
case IntID::UseOverlayScrollbars:
case IntID::AllowOverlayScrollbarsOverlap:
aResult = NSScroller.preferredScrollerStyle == NSScrollerStyleOverlay;
break;
case IntID::ScrollbarDisplayOnMouseMove:
aResult = 0;
break;
case IntID::ScrollbarFadeBeginDelay:
aResult = 450;
break;
case IntID::ScrollbarFadeDuration:
aResult = 200;
break;
case IntID::TreeOpenDelay:
aResult = 1000;
break;
case IntID::TreeCloseDelay:
aResult = 1000;
break;
case IntID::TreeLazyScrollDelay:
aResult = 150;
break;
case IntID::TreeScrollDelay:
aResult = 100;
break;
case IntID::TreeScrollLinesMax:
aResult = 3;
break;
case IntID::MacBigSurTheme:
aResult = nsCocoaFeatures::OnBigSurOrLater();
break;
case IntID::MacRTL:
EnsureInit();
aResult = mRtl;
break;
case IntID::MacTitlebarHeight:
EnsureInit();
aResult = mTitlebarHeight;
break;
case IntID::AlertNotificationOrigin:
aResult = NS_ALERT_TOP;
break;
case IntID::ScrollToClick: {
aResult = [[NSUserDefaults standardUserDefaults]
boolForKey:@"AppleScrollerPagingBehavior"];
} break;
case IntID::ChosenMenuItemsShouldBlink:
aResult = 1;
break;
case IntID::IMERawInputUnderlineStyle:
case IntID::IMEConvertedTextUnderlineStyle:
case IntID::IMESelectedRawTextUnderlineStyle:
case IntID::IMESelectedConvertedTextUnderline:
aResult = static_cast<int32_t>(StyleTextDecorationStyle::Solid);
break;
case IntID::SpellCheckerUnderlineStyle:
aResult = static_cast<int32_t>(StyleTextDecorationStyle::Dotted);
break;
case IntID::ScrollbarButtonAutoRepeatBehavior:
aResult = 0;
break;
case IntID::SwipeAnimationEnabled:
aResult = NSEvent.isSwipeTrackingFromScrollEventsEnabled;
break;
case IntID::ContextMenuOffsetVertical:
aResult = -6;
break;
case IntID::ContextMenuOffsetHorizontal:
aResult = 1;
break;
case IntID::SystemUsesDarkTheme:
aResult = SystemWantsDarkTheme();
break;
case IntID::PrefersReducedMotion:
aResult =
NSWorkspace.sharedWorkspace.accessibilityDisplayShouldReduceMotion;
break;
case IntID::PrefersReducedTransparency:
aResult = NSWorkspace.sharedWorkspace
.accessibilityDisplayShouldReduceTransparency;
break;
case IntID::InvertedColors:
aResult =
NSWorkspace.sharedWorkspace.accessibilityDisplayShouldInvertColors;
break;
case IntID::UseAccessibilityTheme:
aResult = NSWorkspace.sharedWorkspace
.accessibilityDisplayShouldIncreaseContrast;
break;
case IntID::PanelAnimations:
aResult = 1;
break;
default:
aResult = 0;
res = NS_ERROR_FAILURE;
}
return res;
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
nsresult nsLookAndFeel::NativeGetFloat(FloatID aID, float& aResult) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsresult res = NS_OK;
switch (aID) {
case FloatID::IMEUnderlineRelativeSize:
aResult = 2.0f;
break;
case FloatID::SpellCheckerUnderlineRelativeSize:
aResult = 2.0f;
break;
case FloatID::CursorScale: {
id uaDefaults = [[NSUserDefaults alloc]
initWithSuiteName:@"com.apple.universalaccess"];
float f = [uaDefaults floatForKey:@"mouseDriverCursorSize"];
[uaDefaults release];
aResult = f > 0.0 ? f : 1.0; // default to 1.0 if value not available
break;
}
default:
aResult = -1.0;
res = NS_ERROR_FAILURE;
}
return res;
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
bool nsLookAndFeel::NativeGetFont(FontID aID, nsString& aFontName,
gfxFontStyle& aFontStyle) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsAutoCString name;
gfxPlatformMac::LookupSystemFont(aID, name, aFontStyle);
aFontName.Append(NS_ConvertUTF8toUTF16(name));
return true;
NS_OBJC_END_TRY_BLOCK_RETURN(false);
}
void nsLookAndFeel::RecordAccessibilityTelemetry() {
if ([[NSWorkspace sharedWorkspace]
respondsToSelector:@selector
(accessibilityDisplayShouldInvertColors)]) {
bool val =
[[NSWorkspace sharedWorkspace] accessibilityDisplayShouldInvertColors];
Telemetry::ScalarSet(Telemetry::ScalarID::A11Y_INVERT_COLORS, val);
}
}
@implementation MOZLookAndFeelDynamicChangeObserver
+ (void)startObserving {
static MOZLookAndFeelDynamicChangeObserver* gInstance = nil;
if (!gInstance) {
gInstance = [[MOZLookAndFeelDynamicChangeObserver alloc] init]; // leaked
}
}
- (instancetype)init {
self = [super init];
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(colorsChanged)
name:NSControlTintDidChangeNotification
object:nil];
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(colorsChanged)
name:NSSystemColorsDidChangeNotification
object:nil];
[NSWorkspace.sharedWorkspace.notificationCenter
addObserver:self
selector:@selector(mediaQueriesChanged)
name:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification
object:nil];
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(scrollbarsChanged)
name:NSPreferredScrollerStyleDidChangeNotification
object:nil];
[NSDistributedNotificationCenter.defaultCenter
addObserver:self
selector:@selector(scrollbarsChanged)
name:@"AppleAquaScrollBarVariantChanged"
object:nil
suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately];
[NSDistributedNotificationCenter.defaultCenter
addObserver:self
selector:@selector(cachedValuesChanged)
name:@"AppleNoRedisplayAppearancePreferenceChanged"
object:nil
suspensionBehavior:NSNotificationSuspensionBehaviorCoalesce];
[NSDistributedNotificationCenter.defaultCenter
addObserver:self
selector:@selector(cachedValuesChanged)
name:@"com.apple.KeyboardUIModeDidChange"
object:nil
suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately];
[NSApp addObserver:self
forKeyPath:@"effectiveAppearance"
options:0
context:nil];
return self;
}
- (void)observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey, id>*)change
context:(void*)context {
if ([keyPath isEqualToString:@"effectiveAppearance"]) {
[self entireThemeChanged];
} else {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
}
- (void)entireThemeChanged {
LookAndFeel::NotifyChangedAllWindows(widget::ThemeChangeKind::StyleAndLayout);
}
- (void)scrollbarsChanged {
LookAndFeel::NotifyChangedAllWindows(widget::ThemeChangeKind::StyleAndLayout);
}
- (void)mediaQueriesChanged {
// Changing`Invert Colors` sends
// AccessibilityDisplayOptionsDidChangeNotifications. We monitor that setting
// via telemetry, so call into that recording method here.
nsLookAndFeel::RecordAccessibilityTelemetry();
LookAndFeel::NotifyChangedAllWindows(
widget::ThemeChangeKind::MediaQueriesOnly);
}
- (void)colorsChanged {
LookAndFeel::NotifyChangedAllWindows(widget::ThemeChangeKind::Style);
}
- (void)cachedValuesChanged {
// We only need to re-cache (and broadcast) updated LookAndFeel values, so
// that they're up-to-date the next time they're queried. No further change
// handling is needed.
// TODO: Add a change hint for this which avoids the unnecessary media query
// invalidation.
LookAndFeel::NotifyChangedAllWindows(
widget::ThemeChangeKind::MediaQueriesOnly);
}
@end