1 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/ArrayUtils.h"
10 #include "nsXPLookAndFeel.h"
11 #include "nsLookAndFeel.h"
12 #include "HeadlessLookAndFeel.h"
13 #include "RemoteLookAndFeel.h"
14 #include "nsContentUtils.h"
18 #include "nsIXULRuntime.h"
20 #include "SurfaceCacheUtils.h"
21 #include "mozilla/dom/ContentParent.h"
22 #include "mozilla/dom/ContentChild.h"
23 #include "mozilla/Preferences.h"
24 #include "mozilla/Services.h"
25 #include "mozilla/ServoStyleSet.h"
26 #include "mozilla/ServoCSSParser.h"
27 #include "mozilla/StaticPrefs_browser.h"
28 #include "mozilla/StaticPrefs_editor.h"
29 #include "mozilla/StaticPrefs_ui.h"
30 #include "mozilla/StaticPrefs_widget.h"
31 #include "mozilla/dom/Document.h"
32 #include "mozilla/PreferenceSheet.h"
33 #include "mozilla/gfx/2D.h"
34 #include "mozilla/widget/WidgetMessageUtils.h"
35 #include "mozilla/RelativeLuminanceUtils.h"
36 #include "mozilla/Telemetry.h"
37 #include "mozilla/TelemetryScalarEnums.h"
39 #include "gfxPlatform.h"
48 using namespace mozilla
;
50 using IntID
= mozilla::LookAndFeel::IntID
;
51 using FloatID
= mozilla::LookAndFeel::FloatID
;
52 using ColorID
= mozilla::LookAndFeel::ColorID
;
53 using FontID
= mozilla::LookAndFeel::FontID
;
55 template <typename Index
, typename Value
, Index kEnd
>
56 class EnumeratedCache
{
57 static constexpr uint32_t ChunkFor(Index aIndex
) {
58 return uint32_t(aIndex
) >> 5; // >> 5 is the same as / 32.
60 static constexpr uint32_t BitFor(Index aIndex
) {
61 return 1u << (uint32_t(aIndex
) & 31);
63 static constexpr uint32_t kChunks
= ChunkFor(kEnd
) + 1;
65 mozilla::EnumeratedArray
<Index
, kEnd
, Value
> mEntries
;
66 uint32_t mValidity
[kChunks
] = {0};
69 constexpr EnumeratedCache() = default;
71 bool IsValid(Index aIndex
) const {
72 return mValidity
[ChunkFor(aIndex
)] & BitFor(aIndex
);
75 const Value
* Get(Index aIndex
) const {
76 return IsValid(aIndex
) ? &mEntries
[aIndex
] : nullptr;
79 void Insert(Index aIndex
, Value aValue
) {
80 mValidity
[ChunkFor(aIndex
)] |= BitFor(aIndex
);
81 mEntries
[aIndex
] = aValue
;
84 void Remove(Index aIndex
) {
85 mValidity
[ChunkFor(aIndex
)] &= ~BitFor(aIndex
);
86 mEntries
[aIndex
] = Value();
90 for (auto& chunk
: mValidity
) {
93 for (auto& entry
: mEntries
) {
99 static EnumeratedCache
<ColorID
, Maybe
<nscolor
>, ColorID::End
> sLightColorCache
;
100 static EnumeratedCache
<ColorID
, Maybe
<nscolor
>, ColorID::End
> sDarkColorCache
;
101 static EnumeratedCache
<FloatID
, Maybe
<float>, FloatID::End
> sFloatCache
;
102 static EnumeratedCache
<IntID
, Maybe
<int32_t>, IntID::End
> sIntCache
;
103 static EnumeratedCache
<FontID
, widget::LookAndFeelFont
, FontID::End
> sFontCache
;
105 // To make one of these prefs toggleable from a reftest add a user
106 // pref in testing/profiles/reftest/user.js. For example, to make
107 // ui.useAccessibilityTheme toggleable, add:
109 // user_pref("ui.useAccessibilityTheme", 0);
111 // This needs to be of the same length and in the same order as
112 // LookAndFeel::IntID values.
113 static const char sIntPrefs
[][45] = {
115 "ui.caretBlinkCount",
117 "ui.caretVisibleWithSelection",
118 "ui.selectTextfieldsOnKeyFocus",
120 "ui.menusCanOverlapOSBar",
121 "ui.useOverlayScrollbars",
122 "ui.allowOverlayScrollbarsOverlap",
123 "ui.skipNavigatingDisabledMenuItem",
126 "ui.useAccessibilityTheme",
127 "ui.scrollArrowStyle",
128 "ui.scrollSliderStyle",
129 "ui.scrollButtonLeftMouseButtonAction",
130 "ui.scrollButtonMiddleMouseButtonAction",
131 "ui.scrollButtonRightMouseButtonAction",
134 "ui.treeLazyScrollDelay",
135 "ui.treeScrollDelay",
136 "ui.treeScrollLinesMax",
137 "accessibility.tabfocus", // Weird one...
138 "ui.chosenMenuItemsShouldBlink",
139 "ui.windowsAccentColorInTitlebar",
140 "ui.windowsDefaultTheme",
144 "ui.macGraphiteTheme",
147 "ui.alertNotificationOrigin",
149 "ui.IMERawInputUnderlineStyle",
150 "ui.IMESelectedRawTextUnderlineStyle",
151 "ui.IMEConvertedTextUnderlineStyle",
152 "ui.IMESelectedConvertedTextUnderlineStyle",
153 "ui.SpellCheckerUnderlineStyle",
155 "ui.scrollbarButtonAutoRepeatBehavior",
157 "ui.swipeAnimationEnabled",
158 "ui.scrollbarDisplayOnMouseMove",
159 "ui.scrollbarFadeBeginDelay",
160 "ui.scrollbarFadeDuration",
161 "ui.contextMenuOffsetVertical",
162 "ui.contextMenuOffsetHorizontal",
163 "ui.GtkCSDAvailable",
164 "ui.GtkCSDMinimizeButton",
165 "ui.GtkCSDMaximizeButton",
166 "ui.GtkCSDCloseButton",
167 "ui.GtkCSDMinimizeButtonPosition",
168 "ui.GtkCSDMaximizeButtonPosition",
169 "ui.GtkCSDCloseButtonPosition",
170 "ui.GtkCSDReversedPlacement",
171 "ui.systemUsesDarkTheme",
172 "ui.prefersReducedMotion",
173 "ui.primaryPointerCapabilities",
174 "ui.allPointerCapabilities",
175 "ui.systemVerticalScrollbarWidth",
176 "ui.systemHorizontalScrollbarHeight",
177 "ui.touchDeviceSupportPresent",
181 "ui.videoDynamicRange",
184 static_assert(ArrayLength(sIntPrefs
) == size_t(LookAndFeel::IntID::End
),
185 "Should have a pref for each int value");
187 // This array MUST be kept in the same order as the float id list in
190 static const char sFloatPrefs
[][37] = {
191 "ui.IMEUnderlineRelativeSize",
192 "ui.SpellCheckerUnderlineRelativeSize",
193 "ui.caretAspectRatio",
194 "ui.textScaleFactor",
199 static_assert(ArrayLength(sFloatPrefs
) == size_t(LookAndFeel::FloatID::End
),
200 "Should have a pref for each float value");
202 // This array MUST be kept in the same order as the color list in
203 // specified/color.rs
204 static const char sColorPrefs
[][41] = {
205 "ui.textSelectDisabledBackground",
206 "ui.textSelectAttentionBackground",
207 "ui.textSelectAttentionForeground",
208 "ui.textHighlightBackground",
209 "ui.textHighlightForeground",
210 "ui.IMERawInputBackground",
211 "ui.IMERawInputForeground",
212 "ui.IMERawInputUnderline",
213 "ui.IMESelectedRawTextBackground",
214 "ui.IMESelectedRawTextForeground",
215 "ui.IMESelectedRawTextUnderline",
216 "ui.IMEConvertedTextBackground",
217 "ui.IMEConvertedTextForeground",
218 "ui.IMEConvertedTextUnderline",
219 "ui.IMESelectedConvertedTextBackground",
220 "ui.IMESelectedConvertedTextForeground",
221 "ui.IMESelectedConvertedTextUnderline",
222 "ui.SpellCheckerUnderline",
223 "ui.themedScrollbar",
224 "ui.themedScrollbarInactive",
225 "ui.themedScrollbarThumb",
226 "ui.themedScrollbarThumbHover",
227 "ui.themedScrollbarThumbActive",
228 "ui.themedScrollbarThumbInactive",
234 "ui.buttonhighlight",
239 "ui.-moz-disabledfield",
245 "ui.inactivecaption",
246 "ui.inactivecaptiontext",
252 "ui.threeddarkshadow",
254 "ui.threedhighlight",
255 "ui.threedlightshadow",
260 "ui.-moz-buttondefault",
261 "ui.-moz-default-color",
262 "ui.-moz-default-background-color",
264 "ui.-moz-dialogtext",
265 "ui.-moz-dragtargetzone",
266 "ui.-moz-cellhighlight",
267 "ui.-moz_cellhighlighttext",
269 "ui.selecteditemtext",
270 "ui.-moz-buttonhoverface",
271 "ui.-moz_buttonhovertext",
273 "ui.-moz_menuhovertext",
274 "ui.-moz_menubartext",
275 "ui.-moz_menubarhovertext",
276 "ui.-moz_eventreerow",
277 "ui.-moz_oddtreerow",
278 "ui.-moz-buttonactivetext",
279 "ui.-moz-buttonactiveface",
280 "ui.-moz-buttondisabledface",
281 "ui.-moz_mac_chrome_active",
282 "ui.-moz_mac_chrome_inactive",
283 "ui.-moz-mac-defaultbuttontext",
284 "ui.-moz-mac-focusring",
285 "ui.-moz-mac-menuselect",
286 "ui.-moz-mac-menushadow",
287 "ui.-moz-mac-menutextdisable",
288 "ui.-moz-mac-menutextselect",
289 "ui.-moz_mac_disabledtoolbartext",
290 "ui.-moz-mac-secondaryhighlight",
291 "ui.-moz-mac-vibrant-titlebar-light",
292 "ui.-moz-mac-vibrant-titlebar-dark",
293 "ui.-moz-mac-menupopup",
294 "ui.-moz-mac-menuitem",
295 "ui.-moz-mac-active-menuitem",
296 "ui.-moz-mac-source-list",
297 "ui.-moz-mac-source-list-selection",
298 "ui.-moz-mac-active-source-list-selection",
299 "ui.-moz-mac-tooltip",
300 "ui.-moz-accent-color",
301 "ui.-moz-accent-color-foreground",
302 "ui.-moz-autofill-background",
303 "ui.-moz-win-mediatext",
304 "ui.-moz-win-communicationstext",
305 "ui.-moz-nativehyperlinktext",
306 "ui.-moz-nativevisitedhyperlinktext",
307 "ui.-moz-hyperlinktext",
308 "ui.-moz-activehyperlinktext",
309 "ui.-moz-visitedhyperlinktext",
310 "ui.-moz-comboboxtext",
312 "ui.-moz-colheadertext",
313 "ui.-moz-colheaderhovertext",
316 static_assert(ArrayLength(sColorPrefs
) == size_t(LookAndFeel::ColorID::End
),
317 "Should have a pref for each color value");
319 const char* nsXPLookAndFeel::GetColorPrefName(ColorID aId
) {
320 return sColorPrefs
[size_t(aId
)];
323 bool nsXPLookAndFeel::sInitialized
= false;
325 nsXPLookAndFeel
* nsXPLookAndFeel::sInstance
= nullptr;
326 bool nsXPLookAndFeel::sShutdown
= false;
329 nsXPLookAndFeel
* nsXPLookAndFeel::GetInstance() {
334 NS_ENSURE_TRUE(!sShutdown
, nullptr);
336 // If we're in a content process, then the parent process will have supplied
337 // us with an initial FullLookAndFeel object.
338 // We grab this data from the ContentChild,
339 // where it's been temporarily stashed, and initialize our new LookAndFeel
342 FullLookAndFeel
* lnf
= nullptr;
344 if (auto* cc
= mozilla::dom::ContentChild::GetSingleton()) {
345 lnf
= &cc
->BorrowLookAndFeelData();
349 sInstance
= new widget::RemoteLookAndFeel(std::move(*lnf
));
350 } else if (gfxPlatform::IsHeadless()) {
351 sInstance
= new widget::HeadlessLookAndFeel();
353 sInstance
= new nsLookAndFeel();
356 // This is only ever used once during initialization, and can be cleared now.
361 widget::Theme::Init();
366 void nsXPLookAndFeel::Shutdown() {
375 // This keeps strings alive, so need to clear to make leak checking happy.
378 widget::Theme::Shutdown();
381 static void IntPrefChanged(const nsACString
& aPref
) {
382 // Most Int prefs can't change our system colors or fonts, but
383 // ui.systemUsesDarkTheme can, since it affects the effective color-scheme
384 // (affecting system colors).
385 auto changeKind
= aPref
.EqualsLiteral("ui.systemUsesDarkTheme")
386 ? widget::ThemeChangeKind::Style
387 : widget::ThemeChangeKind::MediaQueriesOnly
;
388 LookAndFeel::NotifyChangedAllWindows(changeKind
);
391 static void FloatPrefChanged() {
392 // Float prefs can't change our system colors or fonts.
393 LookAndFeel::NotifyChangedAllWindows(
394 widget::ThemeChangeKind::MediaQueriesOnly
);
397 static void ColorPrefChanged() {
398 // Color prefs affect style, because they by definition change system colors.
399 LookAndFeel::NotifyChangedAllWindows(widget::ThemeChangeKind::Style
);
403 void nsXPLookAndFeel::OnPrefChanged(const char* aPref
, void* aClosure
) {
404 nsDependentCString
prefName(aPref
);
405 for (const char* pref
: sIntPrefs
) {
406 if (prefName
.Equals(pref
)) {
407 IntPrefChanged(prefName
);
412 for (const char* pref
: sFloatPrefs
) {
413 if (prefName
.Equals(pref
)) {
419 for (const char* pref
: sColorPrefs
) {
420 // We use StringBeginsWith to handle .dark prefs too.
421 if (StringBeginsWith(prefName
, nsDependentCString(pref
))) {
428 static constexpr struct {
429 nsLiteralCString mName
;
430 widget::ThemeChangeKind mChangeKind
=
431 widget::ThemeChangeKind::MediaQueriesOnly
;
432 } kMediaQueryPrefs
[] = {
433 {"browser.display.windows.native_menus"_ns
},
434 {"browser.proton.places-tooltip.enabled"_ns
},
436 {"layout.css.prefers-color-scheme.content-override"_ns
,
437 widget::ThemeChangeKind::Style
},
438 // Affects media queries and scrollbar sizes, so gotta relayout.
439 {"widget.gtk.overlay-scrollbars.enabled"_ns
,
440 widget::ThemeChangeKind::StyleAndLayout
},
441 // This affects not only the media query, but also the native theme, so we
442 // need to re-layout.
443 {"browser.theme.toolbar-theme"_ns
, widget::ThemeChangeKind::AllBits
},
444 {"browser.theme.content-theme"_ns
},
447 // Read values from the user's preferences.
448 // This is done once at startup, but since the user's preferences
449 // haven't actually been read yet at that time, we also have to
450 // set a callback to inform us of changes to each pref.
451 void nsXPLookAndFeel::Init() {
452 MOZ_RELEASE_ASSERT(NS_IsMainThread());
454 // Say we're already initialized, and take the chance that it might fail;
455 // protects against some other process writing to our static variables.
458 RecomputeColorSchemes();
460 // XXX If we could reorganize the pref names, we should separate the branch
461 // for each types. Then, we could reduce the unnecessary loop from
462 // nsXPLookAndFeel::OnPrefChanged().
463 Preferences::RegisterPrefixCallback(OnPrefChanged
, "ui.");
464 // We really do just want the accessibility.tabfocus pref, not other prefs
465 // that start with that string.
466 Preferences::RegisterCallback(OnPrefChanged
, "accessibility.tabfocus");
468 for (auto& pref
: kMediaQueryPrefs
) {
469 Preferences::RegisterCallback(
470 [](const char*, void* aChangeKind
) {
472 widget::ThemeChangeKind(reinterpret_cast<uintptr_t>(aChangeKind
));
473 LookAndFeel::NotifyChangedAllWindows(changeKind
);
475 pref
.mName
, reinterpret_cast<void*>(uintptr_t(pref
.mChangeKind
)));
479 nsXPLookAndFeel::~nsXPLookAndFeel() {
480 NS_ASSERTION(sInstance
== this,
481 "This destroying instance isn't the singleton instance");
485 static bool IsSpecialColor(LookAndFeel::ColorID aID
, nscolor aColor
) {
486 using ColorID
= LookAndFeel::ColorID
;
488 if (aColor
== NS_SAME_AS_FOREGROUND_COLOR
) {
493 case ColorID::IMESelectedRawTextBackground
:
494 case ColorID::IMESelectedConvertedTextBackground
:
495 case ColorID::IMERawInputBackground
:
496 case ColorID::IMEConvertedTextBackground
:
497 case ColorID::IMESelectedRawTextForeground
:
498 case ColorID::IMESelectedConvertedTextForeground
:
499 case ColorID::IMERawInputForeground
:
500 case ColorID::IMEConvertedTextForeground
:
501 case ColorID::IMERawInputUnderline
:
502 case ColorID::IMEConvertedTextUnderline
:
503 case ColorID::IMESelectedRawTextUnderline
:
504 case ColorID::IMESelectedConvertedTextUnderline
:
505 case ColorID::SpellCheckerUnderline
:
506 return NS_IS_SELECTION_SPECIAL_COLOR(aColor
);
511 * In GetColor(), every color that is not a special color is color
512 * corrected. Use false to make other colors color corrected.
517 nscolor
nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID
,
518 ColorScheme aScheme
) {
519 if (aScheme
== ColorScheme::Dark
) {
520 if (auto color
= GenericDarkColor(aID
)) {
525 // The stand-in colors are taken from what the non-native theme needs (for
526 // field/button colors), the Windows 7 Aero theme except Mac-specific colors
527 // which are taken from Mac OS 10.7.
529 #define COLOR(name_, r, g, b) \
530 case ColorID::name_: \
531 return NS_RGB(r, g, b);
533 #define COLORA(name_, r, g, b, a) \
534 case ColorID::name_: \
535 return NS_RGBA(r, g, b, a);
538 // These are here for the purposes of headless mode.
539 case ColorID::IMESelectedRawTextBackground
:
540 case ColorID::IMESelectedConvertedTextBackground
:
541 case ColorID::IMERawInputBackground
:
542 case ColorID::IMEConvertedTextBackground
:
543 return NS_TRANSPARENT
;
544 case ColorID::IMESelectedRawTextForeground
:
545 case ColorID::IMESelectedConvertedTextForeground
:
546 case ColorID::IMERawInputForeground
:
547 case ColorID::IMEConvertedTextForeground
:
548 return NS_SAME_AS_FOREGROUND_COLOR
;
549 case ColorID::IMERawInputUnderline
:
550 case ColorID::IMEConvertedTextUnderline
:
551 return NS_40PERCENT_FOREGROUND_COLOR
;
552 COLOR(MozAccentColor
, 53, 132, 228)
553 COLOR(MozAccentColorForeground
, 0xff, 0xff, 0xff)
554 COLOR(SpellCheckerUnderline
, 0xff, 0x00, 0x00)
555 COLOR(TextSelectDisabledBackground
, 0xaa, 0xaa, 0xaa)
558 COLOR(Activeborder
, 0xB4, 0xB4, 0xB4)
559 COLOR(Activecaption
, 0x99, 0xB4, 0xD1)
560 COLOR(Appworkspace
, 0xAB, 0xAB, 0xAB)
561 COLOR(Background
, 0x00, 0x00, 0x00)
562 COLOR(Buttonhighlight
, 0xFF, 0xFF, 0xFF)
563 COLOR(Buttonshadow
, 0xA0, 0xA0, 0xA0)
565 // Buttons and comboboxes should be kept in sync since they are drawn with
566 // the same colors by the non-native theme.
567 COLOR(Buttonface
, 0xe9, 0xe9, 0xed)
568 COLORA(MozButtondisabledface
, 0xe9, 0xe9, 0xed, 128)
570 COLOR(MozCombobox
, 0xe9, 0xe9, 0xed)
572 COLOR(Buttontext
, 0x00, 0x00, 0x00)
573 COLOR(MozComboboxtext
, 0x00, 0x00, 0x00)
575 COLOR(Captiontext
, 0x00, 0x00, 0x00)
576 COLOR(Graytext
, 0x6D, 0x6D, 0x6D)
577 COLOR(Highlight
, 0x33, 0x99, 0xFF)
578 COLOR(Highlighttext
, 0xFF, 0xFF, 0xFF)
579 COLOR(Inactiveborder
, 0xF4, 0xF7, 0xFC)
580 COLOR(Inactivecaption
, 0xBF, 0xCD, 0xDB)
581 COLOR(Inactivecaptiontext
, 0x43, 0x4E, 0x54)
582 COLOR(Infobackground
, 0xFF, 0xFF, 0xE1)
583 COLOR(Infotext
, 0x00, 0x00, 0x00)
584 COLOR(Menu
, 0xF0, 0xF0, 0xF0)
585 COLOR(Menutext
, 0x00, 0x00, 0x00)
586 COLOR(Scrollbar
, 0xC8, 0xC8, 0xC8)
587 COLOR(Threeddarkshadow
, 0x69, 0x69, 0x69)
588 COLOR(Threedface
, 0xF0, 0xF0, 0xF0)
589 COLOR(Threedhighlight
, 0xFF, 0xFF, 0xFF)
590 COLOR(Threedlightshadow
, 0xE3, 0xE3, 0xE3)
591 COLOR(Threedshadow
, 0xA0, 0xA0, 0xA0)
592 COLOR(Window
, 0xFF, 0xFF, 0xFF)
593 COLOR(Windowframe
, 0x64, 0x64, 0x64)
594 COLOR(Windowtext
, 0x00, 0x00, 0x00)
595 COLOR(MozButtondefault
, 0x69, 0x69, 0x69)
596 COLOR(Field
, 0xFF, 0xFF, 0xFF)
597 COLORA(MozDisabledfield
, 0xFF, 0xFF, 0xFF, 128)
598 COLOR(Fieldtext
, 0x00, 0x00, 0x00)
599 COLOR(MozDialog
, 0xF0, 0xF0, 0xF0)
600 COLOR(MozDialogtext
, 0x00, 0x00, 0x00)
601 COLOR(MozColheadertext
, 0x00, 0x00, 0x00)
602 COLOR(MozColheaderhovertext
, 0x00, 0x00, 0x00)
603 COLOR(MozDragtargetzone
, 0xFF, 0xFF, 0xFF)
604 COLOR(MozCellhighlight
, 0xF0, 0xF0, 0xF0)
605 COLOR(MozCellhighlighttext
, 0x00, 0x00, 0x00)
606 COLOR(Selecteditem
, 0x33, 0x99, 0xFF)
607 COLOR(Selecteditemtext
, 0xFF, 0xFF, 0xFF)
608 COLOR(MozButtonhoverface
, 0xd0, 0xd0, 0xd7)
609 COLOR(MozButtonhovertext
, 0x00, 0x00, 0x00)
610 COLOR(MozButtonactiveface
, 0xb1, 0xb1, 0xb9)
611 COLOR(MozButtonactivetext
, 0x00, 0x00, 0x00)
612 COLOR(MozMenuhover
, 0x33, 0x99, 0xFF)
613 COLOR(MozMenuhovertext
, 0x00, 0x00, 0x00)
614 COLOR(MozMenubartext
, 0x00, 0x00, 0x00)
615 COLOR(MozMenubarhovertext
, 0x00, 0x00, 0x00)
616 COLOR(MozEventreerow
, 0xFF, 0xFF, 0xFF)
617 COLOR(MozOddtreerow
, 0xFF, 0xFF, 0xFF)
618 COLOR(MozMacChromeActive
, 0xB2, 0xB2, 0xB2)
619 COLOR(MozMacChromeInactive
, 0xE1, 0xE1, 0xE1)
620 COLOR(MozMacFocusring
, 0x60, 0x9D, 0xD7)
621 COLOR(MozMacMenuselect
, 0x38, 0x75, 0xD7)
622 COLOR(MozMacMenushadow
, 0xA3, 0xA3, 0xA3)
623 COLOR(MozMacMenutextdisable
, 0x88, 0x88, 0x88)
624 COLOR(MozMacMenutextselect
, 0xFF, 0xFF, 0xFF)
625 COLOR(MozMacDisabledtoolbartext
, 0x3F, 0x3F, 0x3F)
626 COLOR(MozMacSecondaryhighlight
, 0xD4, 0xD4, 0xD4)
627 COLOR(MozMacVibrantTitlebarLight
, 0xf7, 0xf7, 0xf7)
628 COLOR(MozMacVibrantTitlebarDark
, 0x28, 0x28, 0x28)
629 COLOR(MozMacMenupopup
, 0xe6, 0xe6, 0xe6)
630 COLOR(MozMacMenuitem
, 0xe6, 0xe6, 0xe6)
631 COLOR(MozMacActiveMenuitem
, 0x0a, 0x64, 0xdc)
632 COLOR(MozMacSourceList
, 0xf7, 0xf7, 0xf7)
633 COLOR(MozMacSourceListSelection
, 0xc8, 0xc8, 0xc8)
634 COLOR(MozMacActiveSourceListSelection
, 0x0a, 0x64, 0xdc)
635 COLOR(MozMacTooltip
, 0xf7, 0xf7, 0xf7)
636 // Seems to be the default color (hardcoded because of bug 1065998)
637 COLOR(MozWinMediatext
, 0xFF, 0xFF, 0xFF)
638 COLOR(MozWinCommunicationstext
, 0xFF, 0xFF, 0xFF)
639 COLOR(MozNativehyperlinktext
, 0x00, 0x66, 0xCC)
640 COLOR(MozNativevisitedhyperlinktext
, 0x55, 0x1A, 0x8B)
644 return NS_RGB(0xFF, 0xFF, 0xFF);
650 // Taken from in-content/common.inc.css's dark theme.
651 Maybe
<nscolor
> nsXPLookAndFeel::GenericDarkColor(ColorID aID
) {
652 nscolor color
= NS_RGB(0, 0, 0);
653 static constexpr nscolor kWindowBackground
= NS_RGB(28, 27, 34);
654 static constexpr nscolor kWindowText
= NS_RGB(251, 251, 254);
656 case ColorID::Window
: // --in-content-page-background
657 case ColorID::Background
:
659 color
= kWindowBackground
;
661 case ColorID::MozOddtreerow
:
662 case ColorID::MozDialog
: // --in-content-box-background
663 color
= NS_RGB(35, 34, 43);
665 case ColorID::Windowtext
: // --in-content-page-color
666 case ColorID::Menutext
:
667 case ColorID::MozDialogtext
:
668 case ColorID::Fieldtext
:
669 case ColorID::Buttontext
: // --in-content-button-text-color (via
670 // --in-content-page-color)
671 case ColorID::MozComboboxtext
:
672 case ColorID::MozButtonhovertext
:
673 case ColorID::MozButtonactivetext
:
676 case ColorID::Buttonshadow
:
677 case ColorID::Threedshadow
:
678 case ColorID::Threedlightshadow
: // --in-content-box-border-color computed
679 // with kWindowText above
680 // kWindowBackground.
681 case ColorID::Graytext
: // opacity: 0.4 of kWindowText blended over the
682 // "Window" background color, which happens to be
684 color
= NS_ComposeColors(kWindowBackground
, NS_RGBA(251, 251, 254, 102));
686 case ColorID::MozCellhighlight
:
687 case ColorID::Selecteditem
: // --in-content-primary-button-background /
688 // --in-content-item-selected
689 color
= NS_RGB(0, 221, 255);
692 case ColorID::Buttonface
: // --in-content-button-background
693 case ColorID::Threedface
:
694 case ColorID::MozCombobox
:
695 case ColorID::MozCellhighlighttext
:
696 case ColorID::Selecteditemtext
: // --in-content-primary-button-text-color /
697 // --in-content-item-selected-text
698 color
= NS_RGB(43, 42, 51);
700 case ColorID::Threeddarkshadow
: // Same as Threedlightshadow but with the
702 case ColorID::MozDisabledfield
: // opacity: 0.4 of the face above blended
703 // over the "Window" background color.
704 case ColorID::MozButtondisabledface
:
705 color
= NS_ComposeColors(kWindowBackground
, NS_RGBA(43, 42, 51, 102));
707 case ColorID::MozButtonhoverface
: // --in-content-button-background-hover
708 color
= NS_RGB(82, 82, 94);
710 case ColorID::MozButtonactiveface
: // --in-content-button-background-active
711 color
= NS_RGB(91, 91, 102);
713 case ColorID::Highlight
:
714 color
= NS_RGBA(0, 221, 255, 78);
716 case ColorID::Highlighttext
:
717 color
= NS_SAME_AS_FOREGROUND_COLOR
;
719 case ColorID::MozNativehyperlinktext
:
720 // If you change this color, you probably also want to change the default
721 // value of browser.anchor_color.dark.
722 color
= NS_RGB(0x8c, 0x8c, 0xff);
724 case ColorID::MozNativevisitedhyperlinktext
:
725 // If you change this color, you probably also want to change the default
726 // value of browser.visited_color.dark.
727 color
= NS_RGB(0xff, 0xad, 0xff);
736 // Uncomment the #define below if you want to debug system color use in a skin
737 // that uses them. When set, it will make all system color pairs that are
738 // appropriate for foreground/background pairing the same. This means if the
739 // skin is using system colors correctly you will not be able to see *any* text.
741 // #define DEBUG_SYSTEM_COLOR_USE
743 #ifdef DEBUG_SYSTEM_COLOR_USE
744 static nsresult
SystemColorUseDebuggingColor(LookAndFeel::ColorID aID
,
746 using ColorID
= LookAndFeel::ColorID
;
749 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
750 case ColorID::Activecaption
:
751 // active window caption background
752 case ColorID::Captiontext
:
753 // text in active window caption
754 aResult
= NS_RGB(0xff, 0x00, 0x00);
757 case ColorID::Highlight
:
758 // background of selected item
759 case ColorID::Highlighttext
:
760 // text of selected item
761 aResult
= NS_RGB(0xff, 0xff, 0x00);
764 case ColorID::Inactivecaption
:
765 // inactive window caption
766 case ColorID::Inactivecaptiontext
:
767 // text in inactive window caption
768 aResult
= NS_RGB(0x66, 0x66, 0x00);
771 case ColorID::Infobackground
:
772 // tooltip background color
773 case ColorID::Infotext
:
774 // tooltip text color
775 aResult
= NS_RGB(0x00, 0xff, 0x00);
780 case ColorID::Menutext
:
782 aResult
= NS_RGB(0x00, 0xff, 0xff);
785 case ColorID::Threedface
:
786 case ColorID::Buttonface
:
788 case ColorID::Buttontext
:
789 // text on push buttons
790 aResult
= NS_RGB(0x00, 0x66, 0x66);
793 case ColorID::Window
:
794 case ColorID::Windowtext
:
795 aResult
= NS_RGB(0x00, 0x00, 0xff);
798 // from the CSS3 working draft (not yet finalized)
799 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
802 case ColorID::Fieldtext
:
803 aResult
= NS_RGB(0xff, 0x00, 0xff);
806 case ColorID::MozDialog
:
807 case ColorID::MozDialogtext
:
808 aResult
= NS_RGB(0x66, 0x00, 0x66);
812 return NS_ERROR_NOT_AVAILABLE
;
819 static nsresult
GetPrefColor(const char* aPref
, nscolor
& aResult
) {
820 nsAutoCString colorStr
;
821 MOZ_TRY(Preferences::GetCString(aPref
, colorStr
));
822 if (!ServoCSSParser::ComputeColor(nullptr, NS_RGB(0, 0, 0), colorStr
,
824 return NS_ERROR_FAILURE
;
829 static nsresult
GetColorFromPref(LookAndFeel::ColorID aID
, ColorScheme aScheme
,
831 const char* prefName
= sColorPrefs
[size_t(aID
)];
832 if (aScheme
== ColorScheme::Dark
) {
833 nsAutoCString
darkPrefName(prefName
);
834 darkPrefName
.Append(".dark");
835 if (NS_SUCCEEDED(GetPrefColor(darkPrefName
.get(), aResult
))) {
839 return GetPrefColor(prefName
, aResult
);
842 // All these routines will return NS_OK if they have a value,
843 // in which case the nsLookAndFeel should use that value;
844 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
845 // platform-specific nsLookAndFeel should use its own values instead.
846 nsresult
nsXPLookAndFeel::GetColorValue(ColorID aID
, ColorScheme aScheme
,
847 UseStandins aUseStandins
,
853 #ifdef DEBUG_SYSTEM_COLOR_USE
854 if (NS_SUCCEEDED(SystemColorUseDebuggingColor(aID
, aResult
))) {
859 if (aUseStandins
== UseStandins::Yes
) {
860 aResult
= GetStandinForNativeColor(aID
, aScheme
);
865 aScheme
== ColorScheme::Light
? sLightColorCache
: sDarkColorCache
;
866 if (const auto* cached
= cache
.Get(aID
)) {
867 if (cached
->isNothing()) {
868 return NS_ERROR_FAILURE
;
870 aResult
= cached
->value();
874 if (NS_SUCCEEDED(GetColorFromPref(aID
, aScheme
, aResult
))) {
875 cache
.Insert(aID
, Some(aResult
));
879 if (NS_SUCCEEDED(NativeGetColor(aID
, aScheme
, aResult
))) {
880 if (gfxPlatform::GetCMSMode() == CMSMode::All
&&
881 !IsSpecialColor(aID
, aResult
)) {
882 qcms_transform
* transform
= gfxPlatform::GetCMSInverseRGBTransform();
885 color
[0] = NS_GET_R(aResult
);
886 color
[1] = NS_GET_G(aResult
);
887 color
[2] = NS_GET_B(aResult
);
888 color
[3] = NS_GET_A(aResult
);
889 qcms_transform_data(transform
, color
, color
, 1);
890 aResult
= NS_RGBA(color
[0], color
[1], color
[2], color
[3]);
894 // NOTE: Servo holds a lock and the main thread is paused, so writing to the
895 // global cache here is fine.
896 cache
.Insert(aID
, Some(aResult
));
900 cache
.Insert(aID
, Nothing());
901 return NS_ERROR_FAILURE
;
904 nsresult
nsXPLookAndFeel::GetIntValue(IntID aID
, int32_t& aResult
) {
909 if (const auto* cached
= sIntCache
.Get(aID
)) {
910 if (cached
->isNothing()) {
911 return NS_ERROR_FAILURE
;
913 aResult
= cached
->value();
917 if (NS_SUCCEEDED(Preferences::GetInt(sIntPrefs
[size_t(aID
)], &aResult
))) {
918 sIntCache
.Insert(aID
, Some(aResult
));
922 if (NS_FAILED(NativeGetInt(aID
, aResult
))) {
923 sIntCache
.Insert(aID
, Nothing());
924 return NS_ERROR_FAILURE
;
927 sIntCache
.Insert(aID
, Some(aResult
));
931 nsresult
nsXPLookAndFeel::GetFloatValue(FloatID aID
, float& aResult
) {
936 if (const auto* cached
= sFloatCache
.Get(aID
)) {
937 if (cached
->isNothing()) {
938 return NS_ERROR_FAILURE
;
940 aResult
= cached
->value();
945 if (NS_SUCCEEDED(Preferences::GetInt(sFloatPrefs
[size_t(aID
)], &pref
))) {
946 aResult
= float(pref
) / 100.0f
;
947 sFloatCache
.Insert(aID
, Some(aResult
));
951 if (NS_FAILED(NativeGetFloat(aID
, aResult
))) {
952 sFloatCache
.Insert(aID
, Nothing());
953 return NS_ERROR_FAILURE
;
956 sFloatCache
.Insert(aID
, Some(aResult
));
960 bool nsXPLookAndFeel::LookAndFeelFontToStyle(const LookAndFeelFont
& aFont
,
962 gfxFontStyle
& aStyle
) {
963 if (!aFont
.haveFont()) {
966 aName
= aFont
.name();
967 aStyle
= gfxFontStyle();
968 aStyle
.size
= aFont
.size();
969 aStyle
.weight
= FontWeight(aFont
.weight());
971 aFont
.italic() ? FontSlantStyle::Italic() : FontSlantStyle::Normal();
972 aStyle
.systemFont
= true;
976 widget::LookAndFeelFont
nsXPLookAndFeel::StyleToLookAndFeelFont(
977 const nsAString
& aName
, const gfxFontStyle
& aStyle
) {
978 LookAndFeelFont font
;
979 font
.haveFont() = true;
981 font
.size() = aStyle
.size
;
982 font
.weight() = aStyle
.weight
.ToFloat();
983 font
.italic() = aStyle
.style
.IsItalic();
984 MOZ_ASSERT(aStyle
.style
.IsNormal() || aStyle
.style
.IsItalic(),
985 "Cannot handle oblique font style");
988 // Assert that all the remaining font style properties have their
990 gfxFontStyle candidate
= aStyle
;
991 gfxFontStyle defaults
{};
992 candidate
.size
= defaults
.size
;
993 candidate
.weight
= defaults
.weight
;
994 candidate
.style
= defaults
.style
;
995 MOZ_ASSERT(candidate
.Equals(defaults
),
996 "Some font style properties not supported");
1002 bool nsXPLookAndFeel::GetFontValue(FontID aID
, nsString
& aName
,
1003 gfxFontStyle
& aStyle
) {
1004 if (const LookAndFeelFont
* cached
= sFontCache
.Get(aID
)) {
1005 return LookAndFeelFontToStyle(*cached
, aName
, aStyle
);
1007 LookAndFeelFont font
;
1008 const bool haveFont
= NativeGetFont(aID
, aName
, aStyle
);
1009 font
.haveFont() = haveFont
;
1011 font
= StyleToLookAndFeelFont(aName
, aStyle
);
1013 sFontCache
.Insert(aID
, std::move(font
));
1017 void nsXPLookAndFeel::RefreshImpl() {
1018 // Wipe out our caches.
1019 sLightColorCache
.Clear();
1020 sDarkColorCache
.Clear();
1022 sFloatCache
.Clear();
1024 RecomputeColorSchemes();
1026 // Clear any cached FullLookAndFeel data, which is now invalid.
1027 if (XRE_IsParentProcess()) {
1028 widget::RemoteLookAndFeel::ClearCachedData();
1032 static bool sRecordedLookAndFeelTelemetry
= false;
1034 void nsXPLookAndFeel::RecordTelemetry() {
1035 if (!XRE_IsParentProcess()) {
1039 if (sRecordedLookAndFeelTelemetry
) {
1043 sRecordedLookAndFeelTelemetry
= true;
1046 Telemetry::ScalarSet(
1047 Telemetry::ScalarID::WIDGET_DARK_MODE
,
1048 NS_SUCCEEDED(GetIntValue(IntID::SystemUsesDarkTheme
, i
)) && i
!= 0);
1050 RecordLookAndFeelSpecificTelemetry();
1055 static widget::ThemeChangeKind sGlobalThemeChangeKind
{0};
1057 void LookAndFeel::NotifyChangedAllWindows(widget::ThemeChangeKind aKind
) {
1058 sGlobalThemeChanged
= true;
1059 sGlobalThemeChangeKind
|= aKind
;
1061 if (nsCOMPtr
<nsIObserverService
> obs
= services::GetObserverService()) {
1062 const char16_t kind
[] = {char16_t(aKind
), 0};
1063 obs
->NotifyObservers(nullptr, "internal-look-and-feel-changed", kind
);
1067 void LookAndFeel::DoHandleGlobalThemeChange() {
1068 MOZ_ASSERT(sGlobalThemeChanged
);
1069 sGlobalThemeChanged
= false;
1070 auto kind
= std::exchange(sGlobalThemeChangeKind
, widget::ThemeChangeKind(0));
1072 // Tell the theme that it changed, so it can flush any handles to stale theme
1075 // We can use the *DoNotUseDirectly functions directly here, because we want
1076 // to notify all possible themes in a given process (but just once).
1077 if (XRE_IsParentProcess() ||
1078 !StaticPrefs::widget_non_native_theme_enabled()) {
1079 if (nsCOMPtr
<nsITheme
> theme
= do_GetNativeThemeDoNotUseDirectly()) {
1080 theme
->ThemeChanged();
1083 if (nsCOMPtr
<nsITheme
> theme
= do_GetBasicNativeThemeDoNotUseDirectly()) {
1084 theme
->ThemeChanged();
1087 // Clear all cached LookAndFeel colors.
1088 LookAndFeel::Refresh();
1090 // Reset default background and foreground colors for the document since they
1091 // may be using system colors.
1092 PreferenceSheet::Refresh();
1094 // Vector images (SVG) may be using theme colors so we discard all cached
1095 // surfaces. (We could add a vector image only version of DiscardAll, but
1096 // in bug 940625 we decided theme changes are rare enough not to bother.)
1097 image::SurfaceCacheUtils::DiscardAll();
1099 if (XRE_IsParentProcess()) {
1100 dom::ContentParent::BroadcastThemeUpdate(kind
);
1103 nsContentUtils::AddScriptRunner(
1104 NS_NewRunnableFunction("HandleGlobalThemeChange", [] {
1105 if (nsCOMPtr
<nsIObserverService
> obs
= services::GetObserverService()) {
1106 obs
->NotifyObservers(nullptr, "look-and-feel-changed", nullptr);
1111 static bool ShouldUseStandinsForNativeColorForNonNativeTheme(
1112 const dom::Document
& aDoc
, LookAndFeel::ColorID aColor
,
1113 const PreferenceSheet::Prefs
& aPrefs
) {
1114 using ColorID
= LookAndFeel::ColorID
;
1115 if (!aDoc
.ShouldAvoidNativeTheme()) {
1119 // The native theme doesn't use native system colors backgrounds etc, except
1120 // when in high-contrast mode, so spoof some of the colors with stand-ins to
1121 // prevent lack of contrast.
1123 case ColorID::Buttonface
:
1124 case ColorID::Buttontext
:
1125 case ColorID::MozButtonhoverface
:
1126 case ColorID::MozButtonhovertext
:
1127 case ColorID::MozButtonactiveface
:
1128 case ColorID::MozButtonactivetext
:
1129 case ColorID::MozButtondisabledface
:
1131 case ColorID::Threedlightshadow
:
1132 case ColorID::Threeddarkshadow
:
1133 case ColorID::Threedface
:
1135 case ColorID::MozCombobox
:
1136 case ColorID::MozComboboxtext
:
1138 case ColorID::Field
:
1139 case ColorID::MozDisabledfield
:
1140 case ColorID::Fieldtext
:
1142 case ColorID::Graytext
:
1143 return !aPrefs
.NonNativeThemeShouldBeHighContrast();
1152 ColorScheme
LookAndFeel::sChromeColorScheme
;
1153 ColorScheme
LookAndFeel::sContentColorScheme
;
1154 bool LookAndFeel::sColorSchemeInitialized
;
1155 bool LookAndFeel::sGlobalThemeChanged
;
1157 bool LookAndFeel::IsDarkColor(nscolor aColor
) {
1158 // Given https://www.w3.org/TR/WCAG20/#contrast-ratiodef, this is the
1159 // threshold that tells us whether contrast is better against white or black.
1161 // Contrast ratio against black is: (L + 0.05) / 0.05
1162 // Contrast ratio against white is: 1.05 / (L + 0.05)
1164 // So the intersection is:
1166 // (L + 0.05) / 0.05 = 1.05 / (L + 0.05)
1168 // And the solution to that equation is:
1170 // sqrt(1.05 * 0.05) - 0.05
1172 // So we consider a color dark if the contrast is below this threshold, and
1173 // it's at least half-opaque.
1174 constexpr float kThreshold
= 0.179129;
1175 return NS_GET_A(aColor
) > 127 &&
1176 RelativeLuminanceUtils::Compute(aColor
) < kThreshold
;
1179 auto LookAndFeel::ColorSchemeSettingForChrome() -> ChromeColorSchemeSetting
{
1180 switch (StaticPrefs::browser_theme_toolbar_theme()) {
1182 return ChromeColorSchemeSetting::Dark
;
1184 return ChromeColorSchemeSetting::Light
;
1186 return ChromeColorSchemeSetting::System
;
1190 ColorScheme
LookAndFeel::ThemeDerivedColorSchemeForContent() {
1191 switch (StaticPrefs::browser_theme_content_theme()) {
1193 return ColorScheme::Dark
;
1195 return ColorScheme::Light
;
1197 return SystemColorScheme();
1201 void LookAndFeel::RecomputeColorSchemes() {
1202 sColorSchemeInitialized
= true;
1204 sChromeColorScheme
= [] {
1205 switch (ColorSchemeSettingForChrome()) {
1206 case ChromeColorSchemeSetting::Light
:
1207 return ColorScheme::Light
;
1208 case ChromeColorSchemeSetting::Dark
:
1209 return ColorScheme::Dark
;
1210 case ChromeColorSchemeSetting::System
:
1213 return SystemColorScheme();
1216 sContentColorScheme
= [] {
1217 switch (StaticPrefs::layout_css_prefers_color_scheme_content_override()) {
1219 return ColorScheme::Dark
;
1221 return ColorScheme::Light
;
1223 return SystemColorScheme();
1225 return ThemeDerivedColorSchemeForContent();
1230 ColorScheme
LookAndFeel::ColorSchemeForStyle(
1231 const dom::Document
& aDoc
, const StyleColorSchemeFlags
& aFlags
) {
1232 using Choice
= PreferenceSheet::Prefs::ColorSchemeChoice
;
1234 const auto& prefs
= PreferenceSheet::PrefsFor(aDoc
);
1235 switch (prefs
.mColorSchemeChoice
) {
1236 case Choice::Standard
:
1238 case Choice::UserPreferred
:
1239 return aDoc
.PreferredColorScheme();
1241 return ColorScheme::Light
;
1243 return ColorScheme::Dark
;
1246 StyleColorSchemeFlags
style(aFlags
);
1248 style
.bits
= aDoc
.GetColorSchemeBits();
1250 const bool supportsDark
= bool(style
& StyleColorSchemeFlags::DARK
);
1251 const bool supportsLight
= bool(style
& StyleColorSchemeFlags::LIGHT
);
1252 if (supportsLight
&& supportsDark
) {
1253 // Both color-schemes are explicitly supported, use the preferred one.
1254 return aDoc
.PreferredColorScheme();
1256 if (supportsDark
|| supportsLight
) {
1257 // One color-scheme is explicitly supported and one isn't, so use the one
1258 // the content supports.
1259 return supportsDark
? ColorScheme::Dark
: ColorScheme::Light
;
1261 // No value specified. Chrome docs always supports both, so use the preferred
1263 if (nsContentUtils::IsChromeDoc(&aDoc
)) {
1264 return aDoc
.PreferredColorScheme();
1266 // Default content to light.
1267 return ColorScheme::Light
;
1270 LookAndFeel::ColorScheme
LookAndFeel::ColorSchemeForFrame(
1271 const nsIFrame
* aFrame
) {
1272 return ColorSchemeForStyle(*aFrame
->PresContext()->Document(),
1273 aFrame
->StyleUI()->mColorScheme
.bits
);
1277 Maybe
<nscolor
> LookAndFeel::GetColor(ColorID aId
, ColorScheme aScheme
,
1278 UseStandins aUseStandins
) {
1280 nsresult rv
= nsLookAndFeel::GetInstance()->GetColorValue(
1281 aId
, aScheme
, aUseStandins
, result
);
1282 if (NS_FAILED(rv
)) {
1285 return Some(result
);
1288 // Returns whether there is a CSS color name for this color.
1289 static bool ColorIsCSSAccessible(LookAndFeel::ColorID aId
) {
1290 using ColorID
= LookAndFeel::ColorID
;
1293 case ColorID::TextSelectDisabledBackground
:
1294 case ColorID::TextSelectAttentionBackground
:
1295 case ColorID::TextSelectAttentionForeground
:
1296 case ColorID::TextHighlightBackground
:
1297 case ColorID::TextHighlightForeground
:
1298 case ColorID::ThemedScrollbar
:
1299 case ColorID::ThemedScrollbarInactive
:
1300 case ColorID::ThemedScrollbarThumb
:
1301 case ColorID::ThemedScrollbarThumbActive
:
1302 case ColorID::ThemedScrollbarThumbInactive
:
1303 case ColorID::ThemedScrollbarThumbHover
:
1304 case ColorID::IMERawInputBackground
:
1305 case ColorID::IMERawInputForeground
:
1306 case ColorID::IMERawInputUnderline
:
1307 case ColorID::IMESelectedRawTextBackground
:
1308 case ColorID::IMESelectedRawTextForeground
:
1309 case ColorID::IMESelectedRawTextUnderline
:
1310 case ColorID::IMEConvertedTextBackground
:
1311 case ColorID::IMEConvertedTextForeground
:
1312 case ColorID::IMEConvertedTextUnderline
:
1313 case ColorID::IMESelectedConvertedTextBackground
:
1314 case ColorID::IMESelectedConvertedTextForeground
:
1315 case ColorID::IMESelectedConvertedTextUnderline
:
1316 case ColorID::SpellCheckerUnderline
:
1325 LookAndFeel::UseStandins
LookAndFeel::ShouldUseStandins(
1326 const dom::Document
& aDoc
, ColorID aId
) {
1327 const auto& prefs
= PreferenceSheet::PrefsFor(aDoc
);
1328 if (ShouldUseStandinsForNativeColorForNonNativeTheme(aDoc
, aId
, prefs
)) {
1329 return UseStandins::Yes
;
1331 if (prefs
.mUseStandins
&& ColorIsCSSAccessible(aId
)) {
1332 return UseStandins::Yes
;
1334 return UseStandins::No
;
1337 Maybe
<nscolor
> LookAndFeel::GetColor(ColorID aId
, const nsIFrame
* aFrame
) {
1338 const auto* doc
= aFrame
->PresContext()->Document();
1339 return GetColor(aId
, ColorSchemeForFrame(aFrame
),
1340 ShouldUseStandins(*doc
, aId
));
1344 nsresult
LookAndFeel::GetInt(IntID aID
, int32_t* aResult
) {
1345 return nsLookAndFeel::GetInstance()->GetIntValue(aID
, *aResult
);
1349 nsresult
LookAndFeel::GetFloat(FloatID aID
, float* aResult
) {
1350 return nsLookAndFeel::GetInstance()->GetFloatValue(aID
, *aResult
);
1354 bool LookAndFeel::GetFont(FontID aID
, nsString
& aName
, gfxFontStyle
& aStyle
) {
1355 return nsLookAndFeel::GetInstance()->GetFontValue(aID
, aName
, aStyle
);
1359 char16_t
LookAndFeel::GetPasswordCharacter() {
1360 return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
1364 bool LookAndFeel::GetEchoPassword() {
1365 if (StaticPrefs::editor_password_mask_delay() >= 0) {
1366 return StaticPrefs::editor_password_mask_delay() > 0;
1368 return nsLookAndFeel::GetInstance()->GetEchoPasswordImpl();
1372 uint32_t LookAndFeel::GetPasswordMaskDelay() {
1373 int32_t delay
= StaticPrefs::editor_password_mask_delay();
1375 return nsLookAndFeel::GetInstance()->GetPasswordMaskDelayImpl();
1380 bool LookAndFeel::DrawInTitlebar() {
1381 switch (StaticPrefs::browser_tabs_inTitlebar()) {
1389 return nsLookAndFeel::GetInstance()->GetDefaultDrawInTitlebar();
1392 void LookAndFeel::GetThemeInfo(nsACString
& aOut
) {
1393 nsLookAndFeel::GetInstance()->GetThemeInfo(aOut
);
1397 void LookAndFeel::Refresh() {
1398 nsLookAndFeel::GetInstance()->RefreshImpl();
1399 widget::Theme::LookAndFeelChanged();
1403 void LookAndFeel::NativeInit() { nsLookAndFeel::GetInstance()->NativeInit(); }
1406 void LookAndFeel::SetData(widget::FullLookAndFeel
&& aTables
) {
1407 nsLookAndFeel::GetInstance()->SetDataImpl(std::move(aTables
));
1410 } // namespace mozilla