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
},
435 {"layout.css.prefers-color-scheme.content-override"_ns
,
436 widget::ThemeChangeKind::Style
},
437 // Affects media queries and scrollbar sizes, so gotta relayout.
438 {"widget.gtk.overlay-scrollbars.enabled"_ns
,
439 widget::ThemeChangeKind::StyleAndLayout
},
440 // This affects not only the media query, but also the native theme, so we
441 // need to re-layout.
442 {"browser.theme.toolbar-theme"_ns
, widget::ThemeChangeKind::AllBits
},
443 {"browser.theme.content-theme"_ns
},
446 // Read values from the user's preferences.
447 // This is done once at startup, but since the user's preferences
448 // haven't actually been read yet at that time, we also have to
449 // set a callback to inform us of changes to each pref.
450 void nsXPLookAndFeel::Init() {
451 MOZ_RELEASE_ASSERT(NS_IsMainThread());
453 // Say we're already initialized, and take the chance that it might fail;
454 // protects against some other process writing to our static variables.
457 RecomputeColorSchemes();
459 // XXX If we could reorganize the pref names, we should separate the branch
460 // for each types. Then, we could reduce the unnecessary loop from
461 // nsXPLookAndFeel::OnPrefChanged().
462 Preferences::RegisterPrefixCallback(OnPrefChanged
, "ui.");
463 // We really do just want the accessibility.tabfocus pref, not other prefs
464 // that start with that string.
465 Preferences::RegisterCallback(OnPrefChanged
, "accessibility.tabfocus");
467 for (auto& pref
: kMediaQueryPrefs
) {
468 Preferences::RegisterCallback(
469 [](const char*, void* aChangeKind
) {
471 widget::ThemeChangeKind(reinterpret_cast<uintptr_t>(aChangeKind
));
472 LookAndFeel::NotifyChangedAllWindows(changeKind
);
474 pref
.mName
, reinterpret_cast<void*>(uintptr_t(pref
.mChangeKind
)));
478 nsXPLookAndFeel::~nsXPLookAndFeel() {
479 NS_ASSERTION(sInstance
== this,
480 "This destroying instance isn't the singleton instance");
484 static bool IsSpecialColor(LookAndFeel::ColorID aID
, nscolor aColor
) {
485 using ColorID
= LookAndFeel::ColorID
;
487 if (aColor
== NS_SAME_AS_FOREGROUND_COLOR
) {
492 case ColorID::IMESelectedRawTextBackground
:
493 case ColorID::IMESelectedConvertedTextBackground
:
494 case ColorID::IMERawInputBackground
:
495 case ColorID::IMEConvertedTextBackground
:
496 case ColorID::IMESelectedRawTextForeground
:
497 case ColorID::IMESelectedConvertedTextForeground
:
498 case ColorID::IMERawInputForeground
:
499 case ColorID::IMEConvertedTextForeground
:
500 case ColorID::IMERawInputUnderline
:
501 case ColorID::IMEConvertedTextUnderline
:
502 case ColorID::IMESelectedRawTextUnderline
:
503 case ColorID::IMESelectedConvertedTextUnderline
:
504 case ColorID::SpellCheckerUnderline
:
505 return NS_IS_SELECTION_SPECIAL_COLOR(aColor
);
510 * In GetColor(), every color that is not a special color is color
511 * corrected. Use false to make other colors color corrected.
516 nscolor
nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID
,
517 ColorScheme aScheme
) {
518 if (aScheme
== ColorScheme::Dark
) {
519 if (auto color
= GenericDarkColor(aID
)) {
524 // The stand-in colors are taken from what the non-native theme needs (for
525 // field/button colors), the Windows 7 Aero theme except Mac-specific colors
526 // which are taken from Mac OS 10.7.
528 #define COLOR(name_, r, g, b) \
529 case ColorID::name_: \
530 return NS_RGB(r, g, b);
532 #define COLORA(name_, r, g, b, a) \
533 case ColorID::name_: \
534 return NS_RGBA(r, g, b, a);
537 // These are here for the purposes of headless mode.
538 case ColorID::IMESelectedRawTextBackground
:
539 case ColorID::IMESelectedConvertedTextBackground
:
540 case ColorID::IMERawInputBackground
:
541 case ColorID::IMEConvertedTextBackground
:
542 return NS_TRANSPARENT
;
543 case ColorID::IMESelectedRawTextForeground
:
544 case ColorID::IMESelectedConvertedTextForeground
:
545 case ColorID::IMERawInputForeground
:
546 case ColorID::IMEConvertedTextForeground
:
547 return NS_SAME_AS_FOREGROUND_COLOR
;
548 case ColorID::IMERawInputUnderline
:
549 case ColorID::IMEConvertedTextUnderline
:
550 return NS_40PERCENT_FOREGROUND_COLOR
;
551 COLOR(MozAccentColor
, 53, 132, 228)
552 COLOR(MozAccentColorForeground
, 0xff, 0xff, 0xff)
553 COLOR(SpellCheckerUnderline
, 0xff, 0x00, 0x00)
554 COLOR(TextSelectDisabledBackground
, 0xaa, 0xaa, 0xaa)
557 COLOR(Activeborder
, 0xB4, 0xB4, 0xB4)
558 COLOR(Activecaption
, 0x99, 0xB4, 0xD1)
559 COLOR(Appworkspace
, 0xAB, 0xAB, 0xAB)
560 COLOR(Background
, 0x00, 0x00, 0x00)
561 COLOR(Buttonhighlight
, 0xFF, 0xFF, 0xFF)
562 COLOR(Buttonshadow
, 0xA0, 0xA0, 0xA0)
564 // Buttons and comboboxes should be kept in sync since they are drawn with
565 // the same colors by the non-native theme.
566 COLOR(Buttonface
, 0xe9, 0xe9, 0xed)
567 COLORA(MozButtondisabledface
, 0xe9, 0xe9, 0xed, 128)
569 COLOR(MozCombobox
, 0xe9, 0xe9, 0xed)
571 COLOR(Buttontext
, 0x00, 0x00, 0x00)
572 COLOR(MozComboboxtext
, 0x00, 0x00, 0x00)
574 COLOR(Captiontext
, 0x00, 0x00, 0x00)
575 COLOR(Graytext
, 0x6D, 0x6D, 0x6D)
576 COLOR(Highlight
, 0x33, 0x99, 0xFF)
577 COLOR(Highlighttext
, 0xFF, 0xFF, 0xFF)
578 COLOR(Inactiveborder
, 0xF4, 0xF7, 0xFC)
579 COLOR(Inactivecaption
, 0xBF, 0xCD, 0xDB)
580 COLOR(Inactivecaptiontext
, 0x43, 0x4E, 0x54)
581 COLOR(Infobackground
, 0xFF, 0xFF, 0xE1)
582 COLOR(Infotext
, 0x00, 0x00, 0x00)
583 COLOR(Menu
, 0xF0, 0xF0, 0xF0)
584 COLOR(Menutext
, 0x00, 0x00, 0x00)
585 COLOR(Scrollbar
, 0xC8, 0xC8, 0xC8)
586 COLOR(Threeddarkshadow
, 0x69, 0x69, 0x69)
587 COLOR(Threedface
, 0xF0, 0xF0, 0xF0)
588 COLOR(Threedhighlight
, 0xFF, 0xFF, 0xFF)
589 COLOR(Threedlightshadow
, 0xE3, 0xE3, 0xE3)
590 COLOR(Threedshadow
, 0xA0, 0xA0, 0xA0)
591 COLOR(Window
, 0xFF, 0xFF, 0xFF)
592 COLOR(Windowframe
, 0x64, 0x64, 0x64)
593 COLOR(Windowtext
, 0x00, 0x00, 0x00)
594 COLOR(MozButtondefault
, 0x69, 0x69, 0x69)
595 COLOR(Field
, 0xFF, 0xFF, 0xFF)
596 COLORA(MozDisabledfield
, 0xFF, 0xFF, 0xFF, 128)
597 COLOR(Fieldtext
, 0x00, 0x00, 0x00)
598 COLOR(MozDialog
, 0xF0, 0xF0, 0xF0)
599 COLOR(MozDialogtext
, 0x00, 0x00, 0x00)
600 COLOR(MozColheadertext
, 0x00, 0x00, 0x00)
601 COLOR(MozColheaderhovertext
, 0x00, 0x00, 0x00)
602 COLOR(MozDragtargetzone
, 0xFF, 0xFF, 0xFF)
603 COLOR(MozCellhighlight
, 0xF0, 0xF0, 0xF0)
604 COLOR(MozCellhighlighttext
, 0x00, 0x00, 0x00)
605 COLOR(Selecteditem
, 0x33, 0x99, 0xFF)
606 COLOR(Selecteditemtext
, 0xFF, 0xFF, 0xFF)
607 COLOR(MozButtonhoverface
, 0xd0, 0xd0, 0xd7)
608 COLOR(MozButtonhovertext
, 0x00, 0x00, 0x00)
609 COLOR(MozButtonactiveface
, 0xb1, 0xb1, 0xb9)
610 COLOR(MozButtonactivetext
, 0x00, 0x00, 0x00)
611 COLOR(MozMenuhover
, 0x33, 0x99, 0xFF)
612 COLOR(MozMenuhovertext
, 0x00, 0x00, 0x00)
613 COLOR(MozMenubartext
, 0x00, 0x00, 0x00)
614 COLOR(MozMenubarhovertext
, 0x00, 0x00, 0x00)
615 COLOR(MozEventreerow
, 0xFF, 0xFF, 0xFF)
616 COLOR(MozOddtreerow
, 0xFF, 0xFF, 0xFF)
617 COLOR(MozMacChromeActive
, 0xB2, 0xB2, 0xB2)
618 COLOR(MozMacChromeInactive
, 0xE1, 0xE1, 0xE1)
619 COLOR(MozMacFocusring
, 0x60, 0x9D, 0xD7)
620 COLOR(MozMacMenuselect
, 0x38, 0x75, 0xD7)
621 COLOR(MozMacMenushadow
, 0xA3, 0xA3, 0xA3)
622 COLOR(MozMacMenutextdisable
, 0x88, 0x88, 0x88)
623 COLOR(MozMacMenutextselect
, 0xFF, 0xFF, 0xFF)
624 COLOR(MozMacDisabledtoolbartext
, 0x3F, 0x3F, 0x3F)
625 COLOR(MozMacSecondaryhighlight
, 0xD4, 0xD4, 0xD4)
626 COLOR(MozMacVibrantTitlebarLight
, 0xf7, 0xf7, 0xf7)
627 COLOR(MozMacVibrantTitlebarDark
, 0x28, 0x28, 0x28)
628 COLOR(MozMacMenupopup
, 0xe6, 0xe6, 0xe6)
629 COLOR(MozMacMenuitem
, 0xe6, 0xe6, 0xe6)
630 COLOR(MozMacActiveMenuitem
, 0x0a, 0x64, 0xdc)
631 COLOR(MozMacSourceList
, 0xf7, 0xf7, 0xf7)
632 COLOR(MozMacSourceListSelection
, 0xc8, 0xc8, 0xc8)
633 COLOR(MozMacActiveSourceListSelection
, 0x0a, 0x64, 0xdc)
634 COLOR(MozMacTooltip
, 0xf7, 0xf7, 0xf7)
635 // Seems to be the default color (hardcoded because of bug 1065998)
636 COLOR(MozWinMediatext
, 0xFF, 0xFF, 0xFF)
637 COLOR(MozWinCommunicationstext
, 0xFF, 0xFF, 0xFF)
638 COLOR(MozNativehyperlinktext
, 0x00, 0x66, 0xCC)
639 COLOR(MozNativevisitedhyperlinktext
, 0x55, 0x1A, 0x8B)
643 return NS_RGB(0xFF, 0xFF, 0xFF);
649 // Taken from in-content/common.inc.css's dark theme.
650 Maybe
<nscolor
> nsXPLookAndFeel::GenericDarkColor(ColorID aID
) {
651 nscolor color
= NS_RGB(0, 0, 0);
652 static constexpr nscolor kWindowBackground
= NS_RGB(28, 27, 34);
653 static constexpr nscolor kWindowText
= NS_RGB(251, 251, 254);
655 case ColorID::Window
: // --in-content-page-background
656 case ColorID::Background
:
658 color
= kWindowBackground
;
660 case ColorID::MozOddtreerow
:
661 case ColorID::MozDialog
: // --in-content-box-background
662 color
= NS_RGB(35, 34, 43);
664 case ColorID::Windowtext
: // --in-content-page-color
665 case ColorID::Menutext
:
666 case ColorID::MozDialogtext
:
667 case ColorID::Fieldtext
:
668 case ColorID::Buttontext
: // --in-content-button-text-color (via
669 // --in-content-page-color)
670 case ColorID::MozComboboxtext
:
671 case ColorID::MozButtonhovertext
:
672 case ColorID::MozButtonactivetext
:
675 case ColorID::Buttonshadow
:
676 case ColorID::Threedshadow
:
677 case ColorID::Threedlightshadow
: // --in-content-box-border-color computed
678 // with kWindowText above
679 // kWindowBackground.
680 case ColorID::Graytext
: // opacity: 0.4 of kWindowText blended over the
681 // "Window" background color, which happens to be
683 color
= NS_ComposeColors(kWindowBackground
, NS_RGBA(251, 251, 254, 102));
685 case ColorID::MozCellhighlight
:
686 case ColorID::Selecteditem
: // --in-content-primary-button-background /
687 // --in-content-item-selected
688 color
= NS_RGB(0, 221, 255);
691 case ColorID::Buttonface
: // --in-content-button-background
692 case ColorID::Threedface
:
693 case ColorID::MozCombobox
:
694 case ColorID::MozCellhighlighttext
:
695 case ColorID::Selecteditemtext
: // --in-content-primary-button-text-color /
696 // --in-content-item-selected-text
697 color
= NS_RGB(43, 42, 51);
699 case ColorID::Threeddarkshadow
: // Same as Threedlightshadow but with the
701 case ColorID::MozDisabledfield
: // opacity: 0.4 of the face above blended
702 // over the "Window" background color.
703 case ColorID::MozButtondisabledface
:
704 color
= NS_ComposeColors(kWindowBackground
, NS_RGBA(43, 42, 51, 102));
706 case ColorID::MozButtonhoverface
: // --in-content-button-background-hover
707 color
= NS_RGB(82, 82, 94);
709 case ColorID::MozButtonactiveface
: // --in-content-button-background-active
710 color
= NS_RGB(91, 91, 102);
712 case ColorID::Highlight
:
713 color
= NS_RGBA(0, 221, 255, 78);
715 case ColorID::Highlighttext
:
716 color
= NS_SAME_AS_FOREGROUND_COLOR
;
718 case ColorID::MozNativehyperlinktext
:
719 // If you change this color, you probably also want to change the default
720 // value of browser.anchor_color.dark.
721 color
= NS_RGB(0x8c, 0x8c, 0xff);
723 case ColorID::MozNativevisitedhyperlinktext
:
724 // If you change this color, you probably also want to change the default
725 // value of browser.visited_color.dark.
726 color
= NS_RGB(0xff, 0xad, 0xff);
735 // Uncomment the #define below if you want to debug system color use in a skin
736 // that uses them. When set, it will make all system color pairs that are
737 // appropriate for foreground/background pairing the same. This means if the
738 // skin is using system colors correctly you will not be able to see *any* text.
740 // #define DEBUG_SYSTEM_COLOR_USE
742 #ifdef DEBUG_SYSTEM_COLOR_USE
743 static nsresult
SystemColorUseDebuggingColor(LookAndFeel::ColorID aID
,
745 using ColorID
= LookAndFeel::ColorID
;
748 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
749 case ColorID::Activecaption
:
750 // active window caption background
751 case ColorID::Captiontext
:
752 // text in active window caption
753 aResult
= NS_RGB(0xff, 0x00, 0x00);
756 case ColorID::Highlight
:
757 // background of selected item
758 case ColorID::Highlighttext
:
759 // text of selected item
760 aResult
= NS_RGB(0xff, 0xff, 0x00);
763 case ColorID::Inactivecaption
:
764 // inactive window caption
765 case ColorID::Inactivecaptiontext
:
766 // text in inactive window caption
767 aResult
= NS_RGB(0x66, 0x66, 0x00);
770 case ColorID::Infobackground
:
771 // tooltip background color
772 case ColorID::Infotext
:
773 // tooltip text color
774 aResult
= NS_RGB(0x00, 0xff, 0x00);
779 case ColorID::Menutext
:
781 aResult
= NS_RGB(0x00, 0xff, 0xff);
784 case ColorID::Threedface
:
785 case ColorID::Buttonface
:
787 case ColorID::Buttontext
:
788 // text on push buttons
789 aResult
= NS_RGB(0x00, 0x66, 0x66);
792 case ColorID::Window
:
793 case ColorID::Windowtext
:
794 aResult
= NS_RGB(0x00, 0x00, 0xff);
797 // from the CSS3 working draft (not yet finalized)
798 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
801 case ColorID::Fieldtext
:
802 aResult
= NS_RGB(0xff, 0x00, 0xff);
805 case ColorID::MozDialog
:
806 case ColorID::MozDialogtext
:
807 aResult
= NS_RGB(0x66, 0x00, 0x66);
811 return NS_ERROR_NOT_AVAILABLE
;
818 static nsresult
GetPrefColor(const char* aPref
, nscolor
& aResult
) {
819 nsAutoCString colorStr
;
820 MOZ_TRY(Preferences::GetCString(aPref
, colorStr
));
821 if (!ServoCSSParser::ComputeColor(nullptr, NS_RGB(0, 0, 0), colorStr
,
823 return NS_ERROR_FAILURE
;
828 static nsresult
GetColorFromPref(LookAndFeel::ColorID aID
, ColorScheme aScheme
,
830 const char* prefName
= sColorPrefs
[size_t(aID
)];
831 if (aScheme
== ColorScheme::Dark
) {
832 nsAutoCString
darkPrefName(prefName
);
833 darkPrefName
.Append(".dark");
834 if (NS_SUCCEEDED(GetPrefColor(darkPrefName
.get(), aResult
))) {
838 return GetPrefColor(prefName
, aResult
);
841 // All these routines will return NS_OK if they have a value,
842 // in which case the nsLookAndFeel should use that value;
843 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
844 // platform-specific nsLookAndFeel should use its own values instead.
845 nsresult
nsXPLookAndFeel::GetColorValue(ColorID aID
, ColorScheme aScheme
,
846 UseStandins aUseStandins
,
852 #ifdef DEBUG_SYSTEM_COLOR_USE
853 if (NS_SUCCEEDED(SystemColorUseDebuggingColor(aID
, aResult
))) {
858 if (aUseStandins
== UseStandins::Yes
) {
859 aResult
= GetStandinForNativeColor(aID
, aScheme
);
864 aScheme
== ColorScheme::Light
? sLightColorCache
: sDarkColorCache
;
865 if (const auto* cached
= cache
.Get(aID
)) {
866 if (cached
->isNothing()) {
867 return NS_ERROR_FAILURE
;
869 aResult
= cached
->value();
873 if (NS_SUCCEEDED(GetColorFromPref(aID
, aScheme
, aResult
))) {
874 cache
.Insert(aID
, Some(aResult
));
878 if (NS_SUCCEEDED(NativeGetColor(aID
, aScheme
, aResult
))) {
879 if (gfxPlatform::GetCMSMode() == CMSMode::All
&&
880 !IsSpecialColor(aID
, aResult
)) {
881 qcms_transform
* transform
= gfxPlatform::GetCMSInverseRGBTransform();
884 color
[0] = NS_GET_R(aResult
);
885 color
[1] = NS_GET_G(aResult
);
886 color
[2] = NS_GET_B(aResult
);
887 color
[3] = NS_GET_A(aResult
);
888 qcms_transform_data(transform
, color
, color
, 1);
889 aResult
= NS_RGBA(color
[0], color
[1], color
[2], color
[3]);
893 // NOTE: Servo holds a lock and the main thread is paused, so writing to the
894 // global cache here is fine.
895 cache
.Insert(aID
, Some(aResult
));
899 cache
.Insert(aID
, Nothing());
900 return NS_ERROR_FAILURE
;
903 nsresult
nsXPLookAndFeel::GetIntValue(IntID aID
, int32_t& aResult
) {
908 if (const auto* cached
= sIntCache
.Get(aID
)) {
909 if (cached
->isNothing()) {
910 return NS_ERROR_FAILURE
;
912 aResult
= cached
->value();
916 if (NS_SUCCEEDED(Preferences::GetInt(sIntPrefs
[size_t(aID
)], &aResult
))) {
917 sIntCache
.Insert(aID
, Some(aResult
));
921 if (NS_FAILED(NativeGetInt(aID
, aResult
))) {
922 sIntCache
.Insert(aID
, Nothing());
923 return NS_ERROR_FAILURE
;
926 sIntCache
.Insert(aID
, Some(aResult
));
930 nsresult
nsXPLookAndFeel::GetFloatValue(FloatID aID
, float& aResult
) {
935 if (const auto* cached
= sFloatCache
.Get(aID
)) {
936 if (cached
->isNothing()) {
937 return NS_ERROR_FAILURE
;
939 aResult
= cached
->value();
944 if (NS_SUCCEEDED(Preferences::GetInt(sFloatPrefs
[size_t(aID
)], &pref
))) {
945 aResult
= float(pref
) / 100.0f
;
946 sFloatCache
.Insert(aID
, Some(aResult
));
950 if (NS_FAILED(NativeGetFloat(aID
, aResult
))) {
951 sFloatCache
.Insert(aID
, Nothing());
952 return NS_ERROR_FAILURE
;
955 sFloatCache
.Insert(aID
, Some(aResult
));
959 bool nsXPLookAndFeel::LookAndFeelFontToStyle(const LookAndFeelFont
& aFont
,
961 gfxFontStyle
& aStyle
) {
962 if (!aFont
.haveFont()) {
965 aName
= aFont
.name();
966 aStyle
= gfxFontStyle();
967 aStyle
.size
= aFont
.size();
968 aStyle
.weight
= FontWeight(aFont
.weight());
970 aFont
.italic() ? FontSlantStyle::Italic() : FontSlantStyle::Normal();
971 aStyle
.systemFont
= true;
975 widget::LookAndFeelFont
nsXPLookAndFeel::StyleToLookAndFeelFont(
976 const nsAString
& aName
, const gfxFontStyle
& aStyle
) {
977 LookAndFeelFont font
;
978 font
.haveFont() = true;
980 font
.size() = aStyle
.size
;
981 font
.weight() = aStyle
.weight
.ToFloat();
982 font
.italic() = aStyle
.style
.IsItalic();
983 MOZ_ASSERT(aStyle
.style
.IsNormal() || aStyle
.style
.IsItalic(),
984 "Cannot handle oblique font style");
987 // Assert that all the remaining font style properties have their
989 gfxFontStyle candidate
= aStyle
;
990 gfxFontStyle defaults
{};
991 candidate
.size
= defaults
.size
;
992 candidate
.weight
= defaults
.weight
;
993 candidate
.style
= defaults
.style
;
994 MOZ_ASSERT(candidate
.Equals(defaults
),
995 "Some font style properties not supported");
1001 bool nsXPLookAndFeel::GetFontValue(FontID aID
, nsString
& aName
,
1002 gfxFontStyle
& aStyle
) {
1003 if (const LookAndFeelFont
* cached
= sFontCache
.Get(aID
)) {
1004 return LookAndFeelFontToStyle(*cached
, aName
, aStyle
);
1006 LookAndFeelFont font
;
1007 const bool haveFont
= NativeGetFont(aID
, aName
, aStyle
);
1008 font
.haveFont() = haveFont
;
1010 font
= StyleToLookAndFeelFont(aName
, aStyle
);
1012 sFontCache
.Insert(aID
, std::move(font
));
1016 void nsXPLookAndFeel::RefreshImpl() {
1017 // Wipe out our caches.
1018 sLightColorCache
.Clear();
1019 sDarkColorCache
.Clear();
1021 sFloatCache
.Clear();
1023 RecomputeColorSchemes();
1025 // Clear any cached FullLookAndFeel data, which is now invalid.
1026 if (XRE_IsParentProcess()) {
1027 widget::RemoteLookAndFeel::ClearCachedData();
1031 static bool sRecordedLookAndFeelTelemetry
= false;
1033 void nsXPLookAndFeel::RecordTelemetry() {
1034 if (!XRE_IsParentProcess()) {
1038 if (sRecordedLookAndFeelTelemetry
) {
1042 sRecordedLookAndFeelTelemetry
= true;
1045 Telemetry::ScalarSet(
1046 Telemetry::ScalarID::WIDGET_DARK_MODE
,
1047 NS_SUCCEEDED(GetIntValue(IntID::SystemUsesDarkTheme
, i
)) && i
!= 0);
1049 RecordLookAndFeelSpecificTelemetry();
1054 static widget::ThemeChangeKind sGlobalThemeChangeKind
{0};
1056 void LookAndFeel::NotifyChangedAllWindows(widget::ThemeChangeKind aKind
) {
1057 sGlobalThemeChanged
= true;
1058 sGlobalThemeChangeKind
|= aKind
;
1060 if (nsCOMPtr
<nsIObserverService
> obs
= services::GetObserverService()) {
1061 const char16_t kind
[] = {char16_t(aKind
), 0};
1062 obs
->NotifyObservers(nullptr, "internal-look-and-feel-changed", kind
);
1066 void LookAndFeel::DoHandleGlobalThemeChange() {
1067 MOZ_ASSERT(sGlobalThemeChanged
);
1068 sGlobalThemeChanged
= false;
1069 auto kind
= std::exchange(sGlobalThemeChangeKind
, widget::ThemeChangeKind(0));
1071 // Tell the theme that it changed, so it can flush any handles to stale theme
1074 // We can use the *DoNotUseDirectly functions directly here, because we want
1075 // to notify all possible themes in a given process (but just once).
1076 if (XRE_IsParentProcess() ||
1077 !StaticPrefs::widget_non_native_theme_enabled()) {
1078 if (nsCOMPtr
<nsITheme
> theme
= do_GetNativeThemeDoNotUseDirectly()) {
1079 theme
->ThemeChanged();
1082 if (nsCOMPtr
<nsITheme
> theme
= do_GetBasicNativeThemeDoNotUseDirectly()) {
1083 theme
->ThemeChanged();
1086 // Clear all cached LookAndFeel colors.
1087 LookAndFeel::Refresh();
1089 // Reset default background and foreground colors for the document since they
1090 // may be using system colors.
1091 PreferenceSheet::Refresh();
1093 // Vector images (SVG) may be using theme colors so we discard all cached
1094 // surfaces. (We could add a vector image only version of DiscardAll, but
1095 // in bug 940625 we decided theme changes are rare enough not to bother.)
1096 image::SurfaceCacheUtils::DiscardAll();
1098 if (XRE_IsParentProcess()) {
1099 dom::ContentParent::BroadcastThemeUpdate(kind
);
1102 nsContentUtils::AddScriptRunner(
1103 NS_NewRunnableFunction("HandleGlobalThemeChange", [] {
1104 if (nsCOMPtr
<nsIObserverService
> obs
= services::GetObserverService()) {
1105 obs
->NotifyObservers(nullptr, "look-and-feel-changed", nullptr);
1110 static bool ShouldUseStandinsForNativeColorForNonNativeTheme(
1111 const dom::Document
& aDoc
, LookAndFeel::ColorID aColor
,
1112 const PreferenceSheet::Prefs
& aPrefs
) {
1113 using ColorID
= LookAndFeel::ColorID
;
1114 if (!aDoc
.ShouldAvoidNativeTheme()) {
1118 // The native theme doesn't use native system colors backgrounds etc, except
1119 // when in high-contrast mode, so spoof some of the colors with stand-ins to
1120 // prevent lack of contrast.
1122 case ColorID::Buttonface
:
1123 case ColorID::Buttontext
:
1124 case ColorID::MozButtonhoverface
:
1125 case ColorID::MozButtonhovertext
:
1126 case ColorID::MozButtonactiveface
:
1127 case ColorID::MozButtonactivetext
:
1128 case ColorID::MozButtondisabledface
:
1130 case ColorID::Threedlightshadow
:
1131 case ColorID::Threeddarkshadow
:
1132 case ColorID::Threedface
:
1134 case ColorID::MozCombobox
:
1135 case ColorID::MozComboboxtext
:
1137 case ColorID::Field
:
1138 case ColorID::MozDisabledfield
:
1139 case ColorID::Fieldtext
:
1141 case ColorID::Graytext
:
1142 return !aPrefs
.NonNativeThemeShouldBeHighContrast();
1151 ColorScheme
LookAndFeel::sChromeColorScheme
;
1152 ColorScheme
LookAndFeel::sContentColorScheme
;
1153 bool LookAndFeel::sColorSchemeInitialized
;
1154 bool LookAndFeel::sGlobalThemeChanged
;
1156 bool LookAndFeel::IsDarkColor(nscolor aColor
) {
1157 // Given https://www.w3.org/TR/WCAG20/#contrast-ratiodef, this is the
1158 // threshold that tells us whether contrast is better against white or black.
1160 // Contrast ratio against black is: (L + 0.05) / 0.05
1161 // Contrast ratio against white is: 1.05 / (L + 0.05)
1163 // So the intersection is:
1165 // (L + 0.05) / 0.05 = 1.05 / (L + 0.05)
1167 // And the solution to that equation is:
1169 // sqrt(1.05 * 0.05) - 0.05
1171 // So we consider a color dark if the contrast is below this threshold, and
1172 // it's at least half-opaque.
1173 constexpr float kThreshold
= 0.179129;
1174 return NS_GET_A(aColor
) > 127 &&
1175 RelativeLuminanceUtils::Compute(aColor
) < kThreshold
;
1178 auto LookAndFeel::ColorSchemeSettingForChrome() -> ChromeColorSchemeSetting
{
1179 switch (StaticPrefs::browser_theme_toolbar_theme()) {
1181 return ChromeColorSchemeSetting::Dark
;
1183 return ChromeColorSchemeSetting::Light
;
1185 return ChromeColorSchemeSetting::System
;
1189 ColorScheme
LookAndFeel::ThemeDerivedColorSchemeForContent() {
1190 switch (StaticPrefs::browser_theme_content_theme()) {
1192 return ColorScheme::Dark
;
1194 return ColorScheme::Light
;
1196 return SystemColorScheme();
1200 void LookAndFeel::RecomputeColorSchemes() {
1201 sColorSchemeInitialized
= true;
1203 sChromeColorScheme
= [] {
1204 switch (ColorSchemeSettingForChrome()) {
1205 case ChromeColorSchemeSetting::Light
:
1206 return ColorScheme::Light
;
1207 case ChromeColorSchemeSetting::Dark
:
1208 return ColorScheme::Dark
;
1209 case ChromeColorSchemeSetting::System
:
1212 return SystemColorScheme();
1215 sContentColorScheme
= [] {
1216 switch (StaticPrefs::layout_css_prefers_color_scheme_content_override()) {
1218 return ColorScheme::Dark
;
1220 return ColorScheme::Light
;
1222 return SystemColorScheme();
1224 return ThemeDerivedColorSchemeForContent();
1229 ColorScheme
LookAndFeel::ColorSchemeForStyle(
1230 const dom::Document
& aDoc
, const StyleColorSchemeFlags
& aFlags
) {
1231 using Choice
= PreferenceSheet::Prefs::ColorSchemeChoice
;
1233 const auto& prefs
= PreferenceSheet::PrefsFor(aDoc
);
1234 switch (prefs
.mColorSchemeChoice
) {
1235 case Choice::Standard
:
1237 case Choice::UserPreferred
:
1238 return aDoc
.PreferredColorScheme();
1240 return ColorScheme::Light
;
1242 return ColorScheme::Dark
;
1245 StyleColorSchemeFlags
style(aFlags
);
1247 style
.bits
= aDoc
.GetColorSchemeBits();
1249 const bool supportsDark
= bool(style
& StyleColorSchemeFlags::DARK
);
1250 const bool supportsLight
= bool(style
& StyleColorSchemeFlags::LIGHT
);
1251 if (supportsLight
&& supportsDark
) {
1252 // Both color-schemes are explicitly supported, use the preferred one.
1253 return aDoc
.PreferredColorScheme();
1255 if (supportsDark
|| supportsLight
) {
1256 // One color-scheme is explicitly supported and one isn't, so use the one
1257 // the content supports.
1258 return supportsDark
? ColorScheme::Dark
: ColorScheme::Light
;
1260 // No value specified. Chrome docs always supports both, so use the preferred
1262 if (nsContentUtils::IsChromeDoc(&aDoc
)) {
1263 return aDoc
.PreferredColorScheme();
1265 // Default content to light.
1266 return ColorScheme::Light
;
1269 LookAndFeel::ColorScheme
LookAndFeel::ColorSchemeForFrame(
1270 const nsIFrame
* aFrame
) {
1271 return ColorSchemeForStyle(*aFrame
->PresContext()->Document(),
1272 aFrame
->StyleUI()->mColorScheme
.bits
);
1276 Maybe
<nscolor
> LookAndFeel::GetColor(ColorID aId
, ColorScheme aScheme
,
1277 UseStandins aUseStandins
) {
1279 nsresult rv
= nsLookAndFeel::GetInstance()->GetColorValue(
1280 aId
, aScheme
, aUseStandins
, result
);
1281 if (NS_FAILED(rv
)) {
1284 return Some(result
);
1287 // Returns whether there is a CSS color name for this color.
1288 static bool ColorIsCSSAccessible(LookAndFeel::ColorID aId
) {
1289 using ColorID
= LookAndFeel::ColorID
;
1292 case ColorID::TextSelectDisabledBackground
:
1293 case ColorID::TextSelectAttentionBackground
:
1294 case ColorID::TextSelectAttentionForeground
:
1295 case ColorID::TextHighlightBackground
:
1296 case ColorID::TextHighlightForeground
:
1297 case ColorID::ThemedScrollbar
:
1298 case ColorID::ThemedScrollbarInactive
:
1299 case ColorID::ThemedScrollbarThumb
:
1300 case ColorID::ThemedScrollbarThumbActive
:
1301 case ColorID::ThemedScrollbarThumbInactive
:
1302 case ColorID::ThemedScrollbarThumbHover
:
1303 case ColorID::IMERawInputBackground
:
1304 case ColorID::IMERawInputForeground
:
1305 case ColorID::IMERawInputUnderline
:
1306 case ColorID::IMESelectedRawTextBackground
:
1307 case ColorID::IMESelectedRawTextForeground
:
1308 case ColorID::IMESelectedRawTextUnderline
:
1309 case ColorID::IMEConvertedTextBackground
:
1310 case ColorID::IMEConvertedTextForeground
:
1311 case ColorID::IMEConvertedTextUnderline
:
1312 case ColorID::IMESelectedConvertedTextBackground
:
1313 case ColorID::IMESelectedConvertedTextForeground
:
1314 case ColorID::IMESelectedConvertedTextUnderline
:
1315 case ColorID::SpellCheckerUnderline
:
1324 LookAndFeel::UseStandins
LookAndFeel::ShouldUseStandins(
1325 const dom::Document
& aDoc
, ColorID aId
) {
1326 const auto& prefs
= PreferenceSheet::PrefsFor(aDoc
);
1327 if (ShouldUseStandinsForNativeColorForNonNativeTheme(aDoc
, aId
, prefs
)) {
1328 return UseStandins::Yes
;
1330 if (prefs
.mUseStandins
&& ColorIsCSSAccessible(aId
)) {
1331 return UseStandins::Yes
;
1333 return UseStandins::No
;
1336 Maybe
<nscolor
> LookAndFeel::GetColor(ColorID aId
, const nsIFrame
* aFrame
) {
1337 const auto* doc
= aFrame
->PresContext()->Document();
1338 return GetColor(aId
, ColorSchemeForFrame(aFrame
),
1339 ShouldUseStandins(*doc
, aId
));
1343 nsresult
LookAndFeel::GetInt(IntID aID
, int32_t* aResult
) {
1344 return nsLookAndFeel::GetInstance()->GetIntValue(aID
, *aResult
);
1348 nsresult
LookAndFeel::GetFloat(FloatID aID
, float* aResult
) {
1349 return nsLookAndFeel::GetInstance()->GetFloatValue(aID
, *aResult
);
1353 bool LookAndFeel::GetFont(FontID aID
, nsString
& aName
, gfxFontStyle
& aStyle
) {
1354 return nsLookAndFeel::GetInstance()->GetFontValue(aID
, aName
, aStyle
);
1358 char16_t
LookAndFeel::GetPasswordCharacter() {
1359 return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
1363 bool LookAndFeel::GetEchoPassword() {
1364 if (StaticPrefs::editor_password_mask_delay() >= 0) {
1365 return StaticPrefs::editor_password_mask_delay() > 0;
1367 return nsLookAndFeel::GetInstance()->GetEchoPasswordImpl();
1371 uint32_t LookAndFeel::GetPasswordMaskDelay() {
1372 int32_t delay
= StaticPrefs::editor_password_mask_delay();
1374 return nsLookAndFeel::GetInstance()->GetPasswordMaskDelayImpl();
1379 bool LookAndFeel::DrawInTitlebar() {
1380 switch (StaticPrefs::browser_tabs_inTitlebar()) {
1388 return nsLookAndFeel::GetInstance()->GetDefaultDrawInTitlebar();
1391 void LookAndFeel::GetThemeInfo(nsACString
& aOut
) {
1392 nsLookAndFeel::GetInstance()->GetThemeInfo(aOut
);
1396 void LookAndFeel::Refresh() {
1397 nsLookAndFeel::GetInstance()->RefreshImpl();
1398 widget::Theme::LookAndFeelChanged();
1402 void LookAndFeel::NativeInit() { nsLookAndFeel::GetInstance()->NativeInit(); }
1405 void LookAndFeel::SetData(widget::FullLookAndFeel
&& aTables
) {
1406 nsLookAndFeel::GetInstance()->SetDataImpl(std::move(aTables
));
1409 } // namespace mozilla