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"
15 #include "mozilla/dom/ContentChild.h"
16 #include "mozilla/Preferences.h"
17 #include "mozilla/Services.h"
18 #include "mozilla/ServoStyleSet.h"
19 #include "mozilla/StaticPrefs_editor.h"
20 #include "mozilla/StaticPrefs_findbar.h"
21 #include "mozilla/StaticPrefs_fission.h"
22 #include "mozilla/StaticPrefs_ui.h"
23 #include "mozilla/gfx/2D.h"
24 #include "mozilla/widget/WidgetMessageUtils.h"
25 #include "mozilla/Telemetry.h"
26 #include "mozilla/TelemetryScalarEnums.h"
28 #include "gfxPlatform.h"
36 using namespace mozilla
;
38 nsLookAndFeelIntPref
nsXPLookAndFeel::sIntPrefs
[] = {
39 {"ui.caretBlinkTime", eIntID_CaretBlinkTime
, false, 0},
40 {"ui.caretWidth", eIntID_CaretWidth
, false, 0},
41 {"ui.caretVisibleWithSelection", eIntID_ShowCaretDuringSelection
, false, 0},
42 {"ui.submenuDelay", eIntID_SubmenuDelay
, false, 0},
43 {"ui.dragThresholdX", eIntID_DragThresholdX
, false, 0},
44 {"ui.dragThresholdY", eIntID_DragThresholdY
, false, 0},
45 {"ui.useAccessibilityTheme", eIntID_UseAccessibilityTheme
, false, 0},
46 {"ui.menusCanOverlapOSBar", eIntID_MenusCanOverlapOSBar
, false, 0},
47 {"ui.useOverlayScrollbars", eIntID_UseOverlayScrollbars
, false, 0},
48 {"ui.scrollbarDisplayOnMouseMove", eIntID_ScrollbarDisplayOnMouseMove
,
50 {"ui.scrollbarFadeBeginDelay", eIntID_ScrollbarFadeBeginDelay
, false, 0},
51 {"ui.scrollbarFadeDuration", eIntID_ScrollbarFadeDuration
, false, 0},
52 {"ui.showHideScrollbars", eIntID_ShowHideScrollbars
, false, 0},
53 {"ui.skipNavigatingDisabledMenuItem", eIntID_SkipNavigatingDisabledMenuItem
,
55 {"ui.treeOpenDelay", eIntID_TreeOpenDelay
, false, 0},
56 {"ui.treeCloseDelay", eIntID_TreeCloseDelay
, false, 0},
57 {"ui.treeLazyScrollDelay", eIntID_TreeLazyScrollDelay
, false, 0},
58 {"ui.treeScrollDelay", eIntID_TreeScrollDelay
, false, 0},
59 {"ui.treeScrollLinesMax", eIntID_TreeScrollLinesMax
, false, 0},
60 {"accessibility.tabfocus", eIntID_TabFocusModel
, false, 0},
61 {"ui.alertNotificationOrigin", eIntID_AlertNotificationOrigin
, false, 0},
62 {"ui.scrollToClick", eIntID_ScrollToClick
, false, 0},
63 {"ui.IMERawInputUnderlineStyle", eIntID_IMERawInputUnderlineStyle
, false,
65 {"ui.IMESelectedRawTextUnderlineStyle",
66 eIntID_IMESelectedRawTextUnderlineStyle
, false, 0},
67 {"ui.IMEConvertedTextUnderlineStyle", eIntID_IMEConvertedTextUnderlineStyle
,
69 {"ui.IMESelectedConvertedTextUnderlineStyle",
70 eIntID_IMESelectedConvertedTextUnderline
, false, 0},
71 {"ui.SpellCheckerUnderlineStyle", eIntID_SpellCheckerUnderlineStyle
, false,
73 {"ui.scrollbarButtonAutoRepeatBehavior",
74 eIntID_ScrollbarButtonAutoRepeatBehavior
, false, 0},
75 {"ui.tooltipDelay", eIntID_TooltipDelay
, false, 0},
76 {"ui.contextMenuOffsetVertical", eIntID_ContextMenuOffsetVertical
, false,
78 {"ui.contextMenuOffsetHorizontal", eIntID_ContextMenuOffsetHorizontal
,
80 {"ui.GtkCSDAvailable", eIntID_GTKCSDAvailable
, false, 0},
81 {"ui.GtkCSDHideTitlebarByDefault", eIntID_GTKCSDHideTitlebarByDefault
,
83 {"ui.GtkCSDTransparentBackground", eIntID_GTKCSDTransparentBackground
,
85 {"ui.GtkCSDMinimizeButton", eIntID_GTKCSDMinimizeButton
, false, 0},
86 {"ui.GtkCSDMaximizeButton", eIntID_GTKCSDMaximizeButton
, false, 0},
87 {"ui.GtkCSDCloseButton", eIntID_GTKCSDCloseButton
, false, 0},
88 {"ui.systemUsesDarkTheme", eIntID_SystemUsesDarkTheme
, false, 0},
89 {"ui.prefersReducedMotion", eIntID_PrefersReducedMotion
, false, 0},
90 {"ui.primaryPointerCapabilities", eIntID_PrimaryPointerCapabilities
, false,
91 6 /* fine and hover-capable pointer, i.e. mouse-type */},
92 {"ui.allPointerCapabilities", eIntID_AllPointerCapabilities
, false,
93 6 /* fine and hover-capable pointer, i.e. mouse-type */},
96 nsLookAndFeelFloatPref
nsXPLookAndFeel::sFloatPrefs
[] = {
97 {"ui.IMEUnderlineRelativeSize", eFloatID_IMEUnderlineRelativeSize
, false,
99 {"ui.SpellCheckerUnderlineRelativeSize",
100 eFloatID_SpellCheckerUnderlineRelativeSize
, false, 0},
101 {"ui.caretAspectRatio", eFloatID_CaretAspectRatio
, false, 0},
104 // This array MUST be kept in the same order as the color list in
105 // specified/color.rs
106 /* XXX If you add any strings longer than
107 * "ui.-moz-mac-active-source-list-selection"
108 * to the following array then you MUST update the
109 * sizes of the sColorPrefs array in nsXPLookAndFeel.h
111 const char nsXPLookAndFeel::sColorPrefs
[][41] = {
112 "ui.windowBackground",
113 "ui.windowForeground",
114 "ui.widgetBackground",
115 "ui.widgetForeground",
116 "ui.widgetSelectBackground",
117 "ui.widgetSelectForeground",
118 "ui.widget3DHighlight",
122 "ui.textSelectBackground",
123 "ui.textSelectForeground",
124 "ui.textSelectForegroundCustom",
125 "ui.textSelectBackgroundDisabled",
126 "ui.textSelectBackgroundAttention",
127 "ui.textHighlightBackground",
128 "ui.textHighlightForeground",
129 "ui.IMERawInputBackground",
130 "ui.IMERawInputForeground",
131 "ui.IMERawInputUnderline",
132 "ui.IMESelectedRawTextBackground",
133 "ui.IMESelectedRawTextForeground",
134 "ui.IMESelectedRawTextUnderline",
135 "ui.IMEConvertedTextBackground",
136 "ui.IMEConvertedTextForeground",
137 "ui.IMEConvertedTextUnderline",
138 "ui.IMESelectedConvertedTextBackground",
139 "ui.IMESelectedConvertedTextForeground",
140 "ui.IMESelectedConvertedTextUnderline",
141 "ui.SpellCheckerUnderline",
147 "ui.buttonhighlight",
157 "ui.inactivecaption",
158 "ui.inactivecaptiontext",
164 "ui.threeddarkshadow",
166 "ui.threedhighlight",
167 "ui.threedlightshadow",
172 "ui.-moz-buttondefault",
173 "ui.-moz-default-color",
174 "ui.-moz-default-background-color",
176 "ui.-moz-dialogtext",
177 "ui.-moz-dragtargetzone",
178 "ui.-moz-cellhighlight",
179 "ui.-moz_cellhighlighttext",
180 "ui.-moz-html-cellhighlight",
181 "ui.-moz-html-cellhighlighttext",
182 "ui.-moz-buttonhoverface",
183 "ui.-moz_buttonhovertext",
185 "ui.-moz_menuhovertext",
186 "ui.-moz_menubartext",
187 "ui.-moz_menubarhovertext",
188 "ui.-moz_eventreerow",
189 "ui.-moz_oddtreerow",
190 "ui.-moz-gtk-buttonactivetext",
191 "ui.-moz-mac-buttonactivetext",
192 "ui.-moz_mac_chrome_active",
193 "ui.-moz_mac_chrome_inactive",
194 "ui.-moz-mac-defaultbuttontext",
195 "ui.-moz-mac-focusring",
196 "ui.-moz-mac-menuselect",
197 "ui.-moz-mac-menushadow",
198 "ui.-moz-mac-menutextdisable",
199 "ui.-moz-mac-menutextselect",
200 "ui.-moz_mac_disabledtoolbartext",
201 "ui.-moz-mac-secondaryhighlight",
202 "ui.-moz-mac-vibrancy-light",
203 "ui.-moz-mac-vibrancy-dark",
204 "ui.-moz-mac-vibrant-titlebar-light",
205 "ui.-moz-mac-vibrant-titlebar-dark",
206 "ui.-moz-mac-menupopup",
207 "ui.-moz-mac-menuitem",
208 "ui.-moz-mac-active-menuitem",
209 "ui.-moz-mac-source-list",
210 "ui.-moz-mac-source-list-selection",
211 "ui.-moz-mac-active-source-list-selection",
212 "ui.-moz-mac-tooltip",
213 "ui.-moz-win-accentcolor",
214 "ui.-moz-win-accentcolortext",
215 "ui.-moz-win-mediatext",
216 "ui.-moz-win-communicationstext",
217 "ui.-moz-nativehyperlinktext",
218 "ui.-moz-hyperlinktext",
219 "ui.-moz-activehyperlinktext",
220 "ui.-moz-visitedhyperlinktext",
221 "ui.-moz-comboboxtext",
223 "ui.-moz-gtk-info-bar-text"};
225 int32_t nsXPLookAndFeel::sCachedColors
[size_t(LookAndFeel::ColorID::End
)] = {0};
226 int32_t nsXPLookAndFeel::sCachedColorBits
[COLOR_CACHE_SIZE
] = {0};
228 bool nsXPLookAndFeel::sInitialized
= false;
230 nsXPLookAndFeel
* nsXPLookAndFeel::sInstance
= nullptr;
231 bool nsXPLookAndFeel::sShutdown
= false;
234 nsXPLookAndFeel
* nsXPLookAndFeel::GetInstance() {
239 NS_ENSURE_TRUE(!sShutdown
, nullptr);
241 if (gfxPlatform::IsHeadless()) {
242 sInstance
= new widget::HeadlessLookAndFeel();
244 sInstance
= new nsLookAndFeel();
250 void nsXPLookAndFeel::Shutdown() {
260 void nsXPLookAndFeel::IntPrefChanged(nsLookAndFeelIntPref
* data
) {
266 nsresult rv
= Preferences::GetInt(data
->name
, &intpref
);
271 printf("====== Cleared int pref %s\n", data
->name
);
274 data
->intVar
= intpref
;
278 printf("====== Changed int pref %s to %d\n", data
->name
, data
->intVar
);
286 void nsXPLookAndFeel::FloatPrefChanged(nsLookAndFeelFloatPref
* data
) {
292 nsresult rv
= Preferences::GetInt(data
->name
, &intpref
);
297 printf("====== Cleared float pref %s\n", data
->name
);
300 data
->floatVar
= (float)intpref
/ 100.0f
;
304 printf("====== Changed float pref %s to %f\n", data
->name
);
312 void nsXPLookAndFeel::ColorPrefChanged(unsigned int index
,
313 const char* prefName
) {
314 nsAutoString colorStr
;
315 nsresult rv
= Preferences::GetString(prefName
, colorStr
);
316 if (NS_SUCCEEDED(rv
) && !colorStr
.IsEmpty()) {
318 if (colorStr
[0] == char16_t('#')) {
319 if (NS_HexToRGBA(nsDependentString(colorStr
, 1), nsHexColorType::NoAlpha
,
321 int32_t id
= NS_PTR_TO_INT32(index
);
322 CACHE_COLOR(id
, thecolor
);
324 } else if (NS_ColorNameToRGB(colorStr
, &thecolor
)) {
325 int32_t id
= NS_PTR_TO_INT32(index
);
326 CACHE_COLOR(id
, thecolor
);
328 printf("====== Changed color pref %s to 0x%lx\n", prefName
, thecolor
);
332 // Reset to the default color, by clearing the cache
333 // to force lookup when the color is next used
334 int32_t id
= NS_PTR_TO_INT32(index
);
335 CLEAR_COLOR_CACHE(id
);
338 printf("====== Cleared color pref %s\n", prefName
);
346 void nsXPLookAndFeel::NotifyPrefChanged() {
347 nsCOMPtr
<nsIObserverService
> obs
= services::GetObserverService();
349 obs
->NotifyObservers(nullptr, "look-and-feel-pref-changed", nullptr);
353 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelIntPref
* aPref
) {
355 nsresult rv
= Preferences::GetInt(aPref
->name
, &intpref
);
356 if (NS_SUCCEEDED(rv
)) {
358 aPref
->intVar
= intpref
;
362 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelFloatPref
* aPref
) {
364 nsresult rv
= Preferences::GetInt(aPref
->name
, &intpref
);
365 if (NS_SUCCEEDED(rv
)) {
367 aPref
->floatVar
= (float)intpref
/ 100.0f
;
371 void nsXPLookAndFeel::InitColorFromPref(int32_t i
) {
372 static_assert(ArrayLength(sColorPrefs
) == size_t(ColorID::End
),
373 "Should have a pref for each color value");
375 nsAutoString colorStr
;
376 nsresult rv
= Preferences::GetString(sColorPrefs
[i
], colorStr
);
377 if (NS_FAILED(rv
) || colorStr
.IsEmpty()) {
381 if (colorStr
[0] == char16_t('#')) {
382 nsAutoString hexString
;
383 colorStr
.Right(hexString
, colorStr
.Length() - 1);
384 if (NS_HexToRGBA(hexString
, nsHexColorType::NoAlpha
, &thecolor
)) {
385 CACHE_COLOR(i
, thecolor
);
387 } else if (NS_ColorNameToRGB(colorStr
, &thecolor
)) {
388 CACHE_COLOR(i
, thecolor
);
393 void nsXPLookAndFeel::OnPrefChanged(const char* aPref
, void* aClosure
) {
394 // looping in the same order as in ::Init
396 nsDependentCString
prefName(aPref
);
398 for (i
= 0; i
< ArrayLength(sIntPrefs
); ++i
) {
399 if (prefName
.Equals(sIntPrefs
[i
].name
)) {
400 IntPrefChanged(&sIntPrefs
[i
]);
405 for (i
= 0; i
< ArrayLength(sFloatPrefs
); ++i
) {
406 if (prefName
.Equals(sFloatPrefs
[i
].name
)) {
407 FloatPrefChanged(&sFloatPrefs
[i
]);
412 for (i
= 0; i
< ArrayLength(sColorPrefs
); ++i
) {
413 if (prefName
.Equals(sColorPrefs
[i
])) {
414 ColorPrefChanged(i
, sColorPrefs
[i
]);
421 // Read values from the user's preferences.
422 // This is done once at startup, but since the user's preferences
423 // haven't actually been read yet at that time, we also have to
424 // set a callback to inform us of changes to each pref.
426 void nsXPLookAndFeel::Init() {
427 MOZ_RELEASE_ASSERT(NS_IsMainThread());
429 // Say we're already initialized, and take the chance that it might fail;
430 // protects against some other process writing to our static variables.
433 // XXX If we could reorganize the pref names, we should separate the branch
434 // for each types. Then, we could reduce the unnecessary loop from
435 // nsXPLookAndFeel::OnPrefChanged().
436 Preferences::RegisterPrefixCallback(OnPrefChanged
, "ui.");
437 // We really do just want the accessibility.tabfocus pref, not other prefs
438 // that start with that string.
439 Preferences::RegisterCallback(OnPrefChanged
, "accessibility.tabfocus");
442 for (i
= 0; i
< ArrayLength(sIntPrefs
); ++i
) {
443 InitFromPref(&sIntPrefs
[i
]);
446 for (i
= 0; i
< ArrayLength(sFloatPrefs
); ++i
) {
447 InitFromPref(&sFloatPrefs
[i
]);
450 for (i
= 0; i
< ArrayLength(sColorPrefs
); ++i
) {
451 InitColorFromPref(i
);
454 if (XRE_IsContentProcess()) {
455 mozilla::dom::ContentChild
* cc
= mozilla::dom::ContentChild::GetSingleton();
457 LookAndFeel::SetIntCache(cc
->LookAndFeelCache());
458 // This is only ever used once during initialization, and can be cleared
460 cc
->LookAndFeelCache().Clear();
464 nsXPLookAndFeel::~nsXPLookAndFeel() {
465 NS_ASSERTION(sInstance
== this,
466 "This destroying instance isn't the singleton instance");
470 bool nsXPLookAndFeel::IsSpecialColor(ColorID aID
, nscolor
& aColor
) {
472 case ColorID::TextSelectForeground
:
473 return (aColor
== NS_DONT_CHANGE_COLOR
);
474 case ColorID::IMESelectedRawTextBackground
:
475 case ColorID::IMESelectedConvertedTextBackground
:
476 case ColorID::IMERawInputBackground
:
477 case ColorID::IMEConvertedTextBackground
:
478 case ColorID::IMESelectedRawTextForeground
:
479 case ColorID::IMESelectedConvertedTextForeground
:
480 case ColorID::IMERawInputForeground
:
481 case ColorID::IMEConvertedTextForeground
:
482 case ColorID::IMERawInputUnderline
:
483 case ColorID::IMEConvertedTextUnderline
:
484 case ColorID::IMESelectedRawTextUnderline
:
485 case ColorID::IMESelectedConvertedTextUnderline
:
486 case ColorID::SpellCheckerUnderline
:
487 return NS_IS_SELECTION_SPECIAL_COLOR(aColor
);
490 * In GetColor(), every color that is not a special color is color
491 * corrected. Use false to make other colors color corrected.
498 bool nsXPLookAndFeel::ColorIsNotCSSAccessible(ColorID aID
) {
502 case ColorID::WindowBackground
:
503 case ColorID::WindowForeground
:
504 case ColorID::WidgetBackground
:
505 case ColorID::WidgetForeground
:
506 case ColorID::WidgetSelectBackground
:
507 case ColorID::WidgetSelectForeground
:
508 case ColorID::Widget3DHighlight
:
509 case ColorID::Widget3DShadow
:
510 case ColorID::TextBackground
:
511 case ColorID::TextForeground
:
512 case ColorID::TextSelectBackground
:
513 case ColorID::TextSelectForeground
:
514 case ColorID::TextSelectBackgroundDisabled
:
515 case ColorID::TextSelectBackgroundAttention
:
516 case ColorID::TextHighlightBackground
:
517 case ColorID::TextHighlightForeground
:
518 case ColorID::IMERawInputBackground
:
519 case ColorID::IMERawInputForeground
:
520 case ColorID::IMERawInputUnderline
:
521 case ColorID::IMESelectedRawTextBackground
:
522 case ColorID::IMESelectedRawTextForeground
:
523 case ColorID::IMESelectedRawTextUnderline
:
524 case ColorID::IMEConvertedTextBackground
:
525 case ColorID::IMEConvertedTextForeground
:
526 case ColorID::IMEConvertedTextUnderline
:
527 case ColorID::IMESelectedConvertedTextBackground
:
528 case ColorID::IMESelectedConvertedTextForeground
:
529 case ColorID::IMESelectedConvertedTextUnderline
:
530 case ColorID::SpellCheckerUnderline
:
540 nscolor
nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID
) {
541 nscolor result
= NS_RGB(0xFF, 0xFF, 0xFF);
543 // The stand-in colors are taken from the Windows 7 Aero theme
544 // except Mac-specific colors which are taken from Mac OS 10.7.
547 case ColorID::Activeborder
:
548 result
= NS_RGB(0xB4, 0xB4, 0xB4);
550 case ColorID::Activecaption
:
551 result
= NS_RGB(0x99, 0xB4, 0xD1);
553 case ColorID::Appworkspace
:
554 result
= NS_RGB(0xAB, 0xAB, 0xAB);
556 case ColorID::Background
:
557 result
= NS_RGB(0x00, 0x00, 0x00);
559 case ColorID::Buttonface
:
560 result
= NS_RGB(0xF0, 0xF0, 0xF0);
562 case ColorID::Buttonhighlight
:
563 result
= NS_RGB(0xFF, 0xFF, 0xFF);
565 case ColorID::Buttonshadow
:
566 result
= NS_RGB(0xA0, 0xA0, 0xA0);
568 case ColorID::Buttontext
:
569 result
= NS_RGB(0x00, 0x00, 0x00);
571 case ColorID::Captiontext
:
572 result
= NS_RGB(0x00, 0x00, 0x00);
574 case ColorID::Graytext
:
575 result
= NS_RGB(0x6D, 0x6D, 0x6D);
577 case ColorID::Highlight
:
578 result
= NS_RGB(0x33, 0x99, 0xFF);
580 case ColorID::Highlighttext
:
581 result
= NS_RGB(0xFF, 0xFF, 0xFF);
583 case ColorID::Inactiveborder
:
584 result
= NS_RGB(0xF4, 0xF7, 0xFC);
586 case ColorID::Inactivecaption
:
587 result
= NS_RGB(0xBF, 0xCD, 0xDB);
589 case ColorID::Inactivecaptiontext
:
590 result
= NS_RGB(0x43, 0x4E, 0x54);
592 case ColorID::Infobackground
:
593 result
= NS_RGB(0xFF, 0xFF, 0xE1);
595 case ColorID::Infotext
:
596 result
= NS_RGB(0x00, 0x00, 0x00);
599 result
= NS_RGB(0xF0, 0xF0, 0xF0);
601 case ColorID::Menutext
:
602 result
= NS_RGB(0x00, 0x00, 0x00);
604 case ColorID::Scrollbar
:
605 result
= NS_RGB(0xC8, 0xC8, 0xC8);
607 case ColorID::Threeddarkshadow
:
608 result
= NS_RGB(0x69, 0x69, 0x69);
610 case ColorID::Threedface
:
611 result
= NS_RGB(0xF0, 0xF0, 0xF0);
613 case ColorID::Threedhighlight
:
614 result
= NS_RGB(0xFF, 0xFF, 0xFF);
616 case ColorID::Threedlightshadow
:
617 result
= NS_RGB(0xE3, 0xE3, 0xE3);
619 case ColorID::Threedshadow
:
620 result
= NS_RGB(0xA0, 0xA0, 0xA0);
622 case ColorID::Window
:
623 result
= NS_RGB(0xFF, 0xFF, 0xFF);
625 case ColorID::Windowframe
:
626 result
= NS_RGB(0x64, 0x64, 0x64);
628 case ColorID::Windowtext
:
629 result
= NS_RGB(0x00, 0x00, 0x00);
631 case ColorID::MozButtondefault
:
632 result
= NS_RGB(0x69, 0x69, 0x69);
635 result
= NS_RGB(0xFF, 0xFF, 0xFF);
637 case ColorID::Fieldtext
:
638 result
= NS_RGB(0x00, 0x00, 0x00);
640 case ColorID::MozDialog
:
641 result
= NS_RGB(0xF0, 0xF0, 0xF0);
643 case ColorID::MozDialogtext
:
644 result
= NS_RGB(0x00, 0x00, 0x00);
646 case ColorID::MozDragtargetzone
:
647 result
= NS_RGB(0xFF, 0xFF, 0xFF);
649 case ColorID::MozCellhighlight
:
650 result
= NS_RGB(0xF0, 0xF0, 0xF0);
652 case ColorID::MozCellhighlighttext
:
653 result
= NS_RGB(0x00, 0x00, 0x00);
655 case ColorID::MozHtmlCellhighlight
:
656 result
= NS_RGB(0x33, 0x99, 0xFF);
658 case ColorID::MozHtmlCellhighlighttext
:
659 result
= NS_RGB(0xFF, 0xFF, 0xFF);
661 case ColorID::MozButtonhoverface
:
662 result
= NS_RGB(0xF0, 0xF0, 0xF0);
664 case ColorID::MozButtonhovertext
:
665 result
= NS_RGB(0x00, 0x00, 0x00);
667 case ColorID::MozMenuhover
:
668 result
= NS_RGB(0x33, 0x99, 0xFF);
670 case ColorID::MozMenuhovertext
:
671 result
= NS_RGB(0x00, 0x00, 0x00);
673 case ColorID::MozMenubartext
:
674 result
= NS_RGB(0x00, 0x00, 0x00);
676 case ColorID::MozMenubarhovertext
:
677 result
= NS_RGB(0x00, 0x00, 0x00);
679 case ColorID::MozOddtreerow
:
680 case ColorID::MozGtkButtonactivetext
:
681 result
= NS_RGB(0xFF, 0xFF, 0xFF);
683 case ColorID::MozMacChromeActive
:
684 result
= NS_RGB(0xB2, 0xB2, 0xB2);
686 case ColorID::MozMacChromeInactive
:
687 result
= NS_RGB(0xE1, 0xE1, 0xE1);
689 case ColorID::MozMacFocusring
:
690 result
= NS_RGB(0x60, 0x9D, 0xD7);
692 case ColorID::MozMacMenuselect
:
693 result
= NS_RGB(0x38, 0x75, 0xD7);
695 case ColorID::MozMacMenushadow
:
696 result
= NS_RGB(0xA3, 0xA3, 0xA3);
698 case ColorID::MozMacMenutextdisable
:
699 result
= NS_RGB(0x88, 0x88, 0x88);
701 case ColorID::MozMacMenutextselect
:
702 result
= NS_RGB(0xFF, 0xFF, 0xFF);
704 case ColorID::MozMacDisabledtoolbartext
:
705 result
= NS_RGB(0x3F, 0x3F, 0x3F);
707 case ColorID::MozMacSecondaryhighlight
:
708 result
= NS_RGB(0xD4, 0xD4, 0xD4);
710 case ColorID::MozMacVibrancyLight
:
711 case ColorID::MozMacVibrantTitlebarLight
:
712 result
= NS_RGB(0xf7, 0xf7, 0xf7);
714 case ColorID::MozMacVibrancyDark
:
715 case ColorID::MozMacVibrantTitlebarDark
:
716 result
= NS_RGB(0x28, 0x28, 0x28);
718 case ColorID::MozMacMenupopup
:
719 result
= NS_RGB(0xe6, 0xe6, 0xe6);
721 case ColorID::MozMacMenuitem
:
722 result
= NS_RGB(0xe6, 0xe6, 0xe6);
724 case ColorID::MozMacActiveMenuitem
:
725 result
= NS_RGB(0x0a, 0x64, 0xdc);
727 case ColorID::MozMacSourceList
:
728 result
= NS_RGB(0xf7, 0xf7, 0xf7);
730 case ColorID::MozMacSourceListSelection
:
731 result
= NS_RGB(0xc8, 0xc8, 0xc8);
733 case ColorID::MozMacActiveSourceListSelection
:
734 result
= NS_RGB(0x0a, 0x64, 0xdc);
736 case ColorID::MozMacTooltip
:
737 result
= NS_RGB(0xf7, 0xf7, 0xf7);
739 case ColorID::MozWinAccentcolor
:
740 // Seems to be the default color (hardcoded because of bug 1065998)
741 result
= NS_RGB(0x9E, 0x9E, 0x9E);
743 case ColorID::MozWinAccentcolortext
:
744 result
= NS_RGB(0x00, 0x00, 0x00);
746 case ColorID::MozWinMediatext
:
747 result
= NS_RGB(0xFF, 0xFF, 0xFF);
749 case ColorID::MozWinCommunicationstext
:
750 result
= NS_RGB(0xFF, 0xFF, 0xFF);
752 case ColorID::MozNativehyperlinktext
:
753 result
= NS_RGB(0x00, 0x66, 0xCC);
755 case ColorID::MozComboboxtext
:
756 result
= NS_RGB(0x00, 0x00, 0x00);
758 case ColorID::MozCombobox
:
759 result
= NS_RGB(0xFF, 0xFF, 0xFF);
769 // All these routines will return NS_OK if they have a value,
770 // in which case the nsLookAndFeel should use that value;
771 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
772 // platform-specific nsLookAndFeel should use its own values instead.
774 nsresult
nsXPLookAndFeel::GetColorImpl(ColorID aID
,
775 bool aUseStandinsForNativeColors
,
777 if (!sInitialized
) Init();
779 // define DEBUG_SYSTEM_COLOR_USE if you want to debug system color
780 // use in a skin that uses them. When set, it will make all system
781 // color pairs that are appropriate for foreground/background
782 // pairing the same. This means if the skin is using system colors
783 // correctly you will not be able to see *any* text.
784 #undef DEBUG_SYSTEM_COLOR_USE
786 #ifdef DEBUG_SYSTEM_COLOR_USE
790 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
791 case ColorID::Activecaption
:
792 // active window caption background
793 case ColorID::Captiontext
:
794 // text in active window caption
795 aResult
= NS_RGB(0xff, 0x00, 0x00);
798 case ColorID::Highlight
:
799 // background of selected item
800 case ColorID::Highlighttext
:
801 // text of selected item
802 aResult
= NS_RGB(0xff, 0xff, 0x00);
805 case ColorID::Inactivecaption
:
806 // inactive window caption
807 case ColorID::Inactivecaptiontext
:
808 // text in inactive window caption
809 aResult
= NS_RGB(0x66, 0x66, 0x00);
812 case ColorID::Infobackground
:
813 // tooltip background color
814 case ColorID::Infotext
:
815 // tooltip text color
816 aResult
= NS_RGB(0x00, 0xff, 0x00);
821 case ColorID::Menutext
:
823 aResult
= NS_RGB(0x00, 0xff, 0xff);
826 case ColorID::Threedface
:
827 case ColorID::Buttonface
:
829 case ColorID::Buttontext
:
830 // text on push buttons
831 aResult
= NS_RGB(0x00, 0x66, 0x66);
834 case ColorID::Window
:
835 case ColorID::Windowtext
:
836 aResult
= NS_RGB(0x00, 0x00, 0xff);
839 // from the CSS3 working draft (not yet finalized)
840 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
843 case ColorID::Fieldtext
:
844 aResult
= NS_RGB(0xff, 0x00, 0xff);
847 case ColorID::MozDialog
:
848 case ColorID::MozDialogtext
:
849 aResult
= NS_RGB(0x66, 0x00, 0x66);
853 rv
= NS_ERROR_NOT_AVAILABLE
;
855 if (NS_SUCCEEDED(rv
)) return rv
;
857 #endif // DEBUG_SYSTEM_COLOR_USE
859 if (aUseStandinsForNativeColors
&&
860 (ColorIsNotCSSAccessible(aID
) ||
861 !nsContentUtils::UseStandinsForNativeColors())) {
862 aUseStandinsForNativeColors
= false;
865 if (!aUseStandinsForNativeColors
&& IS_COLOR_CACHED(aID
)) {
866 aResult
= sCachedColors
[uint32_t(aID
)];
870 // There are no system color settings for these, so set them manually
872 if (aID
== ColorID::TextSelectBackgroundDisabled
) {
873 // This is used to gray out the selection when it's not focused
874 // Used with nsISelectionController::SELECTION_DISABLED
875 aResult
= NS_RGB(0xb0, 0xb0, 0xb0);
880 if (aID
== ColorID::TextSelectBackgroundAttention
) {
881 if (StaticPrefs::findbar_modalHighlight() &&
882 !StaticPrefs::fission_autostart()) {
883 aResult
= NS_RGBA(0, 0, 0, 0);
887 // This makes the selection stand out when typeaheadfind is on
888 // Used with nsISelectionController::SELECTION_ATTENTION
889 aResult
= NS_RGB(0x38, 0xd8, 0x78);
893 if (aID
== ColorID::TextHighlightBackground
) {
894 // This makes the matched text stand out when findbar highlighting is on
895 // Used with nsISelectionController::SELECTION_FIND
896 aResult
= NS_RGB(0xef, 0x0f, 0xff);
900 if (aID
== ColorID::TextHighlightForeground
) {
901 // The foreground color for the matched text in findbar highlighting
902 // Used with nsISelectionController::SELECTION_FIND
903 aResult
= NS_RGB(0xff, 0xff, 0xff);
907 if (StaticPrefs::ui_use_native_colors() && aUseStandinsForNativeColors
) {
908 aResult
= GetStandinForNativeColor(aID
);
912 if (StaticPrefs::ui_use_native_colors() &&
913 NS_SUCCEEDED(NativeGetColor(aID
, aResult
))) {
914 if (!mozilla::ServoStyleSet::IsInServoTraversal()) {
915 MOZ_ASSERT(NS_IsMainThread());
916 if ((gfxPlatform::GetCMSMode() == eCMSMode_All
) &&
917 !IsSpecialColor(aID
, aResult
)) {
918 qcms_transform
* transform
= gfxPlatform::GetCMSInverseRGBTransform();
921 color
[0] = NS_GET_R(aResult
);
922 color
[1] = NS_GET_G(aResult
);
923 color
[2] = NS_GET_B(aResult
);
924 color
[3] = NS_GET_A(aResult
);
925 qcms_transform_data(transform
, color
, color
, 1);
926 aResult
= NS_RGBA(color
[0], color
[1], color
[2], color
[3]);
930 CACHE_COLOR(aID
, aResult
);
935 return NS_ERROR_NOT_AVAILABLE
;
938 nsresult
nsXPLookAndFeel::GetIntImpl(IntID aID
, int32_t& aResult
) {
939 if (!sInitialized
) Init();
941 // Set the default values for these prefs. but allow different platforms
942 // to override them in their nsLookAndFeel if desired.
944 case eIntID_ScrollButtonLeftMouseButtonAction
:
947 case eIntID_ScrollButtonMiddleMouseButtonAction
:
950 case eIntID_ScrollButtonRightMouseButtonAction
:
955 * The metrics above are hardcoded platform defaults. All the other
956 * metrics are stored in sIntPrefs and can be changed at runtime.
961 for (unsigned int i
= 0; i
< ArrayLength(sIntPrefs
); ++i
) {
962 if (sIntPrefs
[i
].isSet
&& (sIntPrefs
[i
].id
== aID
)) {
963 aResult
= sIntPrefs
[i
].intVar
;
968 return NS_ERROR_NOT_AVAILABLE
;
971 nsresult
nsXPLookAndFeel::GetFloatImpl(FloatID aID
, float& aResult
) {
972 if (!sInitialized
) Init();
974 for (unsigned int i
= 0; i
< ArrayLength(sFloatPrefs
); ++i
) {
975 if (sFloatPrefs
[i
].isSet
&& sFloatPrefs
[i
].id
== aID
) {
976 aResult
= sFloatPrefs
[i
].floatVar
;
981 return NS_ERROR_NOT_AVAILABLE
;
984 void nsXPLookAndFeel::RefreshImpl() {
985 // Wipe out our color cache.
987 for (i
= 0; i
< uint32_t(ColorID::End
); i
++) {
988 sCachedColors
[i
] = 0;
990 for (i
= 0; i
< COLOR_CACHE_SIZE
; i
++) {
991 sCachedColorBits
[i
] = 0;
994 // Reinit color cache from prefs.
995 for (i
= 0; i
< uint32_t(ColorID::End
); ++i
) {
996 InitColorFromPref(i
);
1000 nsTArray
<LookAndFeelInt
> nsXPLookAndFeel::GetIntCacheImpl() {
1001 return nsTArray
<LookAndFeelInt
>();
1004 static bool sRecordedLookAndFeelTelemetry
= false;
1006 void nsXPLookAndFeel::RecordTelemetry() {
1007 if (sRecordedLookAndFeelTelemetry
) {
1011 sRecordedLookAndFeelTelemetry
= true;
1014 Telemetry::ScalarSet(
1015 Telemetry::ScalarID::WIDGET_DARK_MODE
,
1016 NS_SUCCEEDED(GetIntImpl(eIntID_SystemUsesDarkTheme
, i
)) && i
!= 0);
1022 nsresult
LookAndFeel::GetColor(ColorID aID
, nscolor
* aResult
) {
1023 return nsLookAndFeel::GetInstance()->GetColorImpl(aID
, false, *aResult
);
1026 nsresult
LookAndFeel::GetColor(ColorID aID
, bool aUseStandinsForNativeColors
,
1028 return nsLookAndFeel::GetInstance()->GetColorImpl(
1029 aID
, aUseStandinsForNativeColors
, *aResult
);
1033 nsresult
LookAndFeel::GetInt(IntID aID
, int32_t* aResult
) {
1034 return nsLookAndFeel::GetInstance()->GetIntImpl(aID
, *aResult
);
1038 nsresult
LookAndFeel::GetFloat(FloatID aID
, float* aResult
) {
1039 return nsLookAndFeel::GetInstance()->GetFloatImpl(aID
, *aResult
);
1043 bool LookAndFeel::GetFont(FontID aID
, nsString
& aName
, gfxFontStyle
& aStyle
) {
1044 return nsLookAndFeel::GetInstance()->GetFontImpl(aID
, aName
, aStyle
);
1048 char16_t
LookAndFeel::GetPasswordCharacter() {
1049 return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
1053 bool LookAndFeel::GetEchoPassword() {
1054 if (StaticPrefs::editor_password_mask_delay() >= 0) {
1055 return StaticPrefs::editor_password_mask_delay() > 0;
1057 return nsLookAndFeel::GetInstance()->GetEchoPasswordImpl();
1061 uint32_t LookAndFeel::GetPasswordMaskDelay() {
1062 int32_t delay
= StaticPrefs::editor_password_mask_delay();
1064 return nsLookAndFeel::GetInstance()->GetPasswordMaskDelayImpl();
1070 void LookAndFeel::Refresh() { nsLookAndFeel::GetInstance()->RefreshImpl(); }
1073 void LookAndFeel::NativeInit() { nsLookAndFeel::GetInstance()->NativeInit(); }
1076 nsTArray
<LookAndFeelInt
> LookAndFeel::GetIntCache() {
1077 return nsLookAndFeel::GetInstance()->GetIntCacheImpl();
1081 void LookAndFeel::SetIntCache(
1082 const nsTArray
<LookAndFeelInt
>& aLookAndFeelIntCache
) {
1083 return nsLookAndFeel::GetInstance()->SetIntCacheImpl(aLookAndFeelIntCache
);
1087 void LookAndFeel::SetShouldRetainCacheForTest(bool aValue
) {
1088 nsLookAndFeel::GetInstance()->SetShouldRetainCacheImplForTest(aValue
);
1092 void LookAndFeel::SetPrefersReducedMotionOverrideForTest(bool aValue
) {
1093 // Tell that the cache value we are going to set isn't cleared via
1094 // nsPresContext::ThemeChangedInternal which is called right before
1095 // we queue the media feature value change for this prefers-reduced-motion
1097 SetShouldRetainCacheForTest(true);
1099 int32_t value
= aValue
? 1 : 0;
1101 AutoTArray
<LookAndFeelInt
, 1> lookAndFeelCache
;
1102 lookAndFeelCache
.AppendElement(
1103 LookAndFeelInt
{.id
= eIntID_PrefersReducedMotion
, .value
= value
});
1105 SetIntCache(lookAndFeelCache
);
1109 void LookAndFeel::ResetPrefersReducedMotionOverrideForTest() {
1110 SetShouldRetainCacheForTest(false);
1113 } // namespace mozilla