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 "nsIXULRuntime.h"
16 #include "mozilla/dom/ContentChild.h"
17 #include "mozilla/Preferences.h"
18 #include "mozilla/Services.h"
19 #include "mozilla/ServoStyleSet.h"
20 #include "mozilla/StaticPrefs_editor.h"
21 #include "mozilla/StaticPrefs_findbar.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", IntID::CaretBlinkTime
, false, 0},
40 {"ui.caretWidth", IntID::CaretWidth
, false, 0},
41 {"ui.caretVisibleWithSelection", IntID::ShowCaretDuringSelection
, false, 0},
42 {"ui.submenuDelay", IntID::SubmenuDelay
, false, 0},
43 {"ui.dragThresholdX", IntID::DragThresholdX
, false, 0},
44 {"ui.dragThresholdY", IntID::DragThresholdY
, false, 0},
45 {"ui.useAccessibilityTheme", IntID::UseAccessibilityTheme
, false, 0},
46 {"ui.menusCanOverlapOSBar", IntID::MenusCanOverlapOSBar
, false, 0},
47 {"ui.useOverlayScrollbars", IntID::UseOverlayScrollbars
, false, 0},
48 {"ui.scrollbarDisplayOnMouseMove", IntID::ScrollbarDisplayOnMouseMove
,
50 {"ui.scrollbarFadeBeginDelay", IntID::ScrollbarFadeBeginDelay
, false, 0},
51 {"ui.scrollbarFadeDuration", IntID::ScrollbarFadeDuration
, false, 0},
52 {"ui.showHideScrollbars", IntID::ShowHideScrollbars
, false, 0},
53 {"ui.skipNavigatingDisabledMenuItem", IntID::SkipNavigatingDisabledMenuItem
,
55 {"ui.treeOpenDelay", IntID::TreeOpenDelay
, false, 0},
56 {"ui.treeCloseDelay", IntID::TreeCloseDelay
, false, 0},
57 {"ui.treeLazyScrollDelay", IntID::TreeLazyScrollDelay
, false, 0},
58 {"ui.treeScrollDelay", IntID::TreeScrollDelay
, false, 0},
59 {"ui.treeScrollLinesMax", IntID::TreeScrollLinesMax
, false, 0},
60 {"accessibility.tabfocus", IntID::TabFocusModel
, false, 0},
61 {"ui.alertNotificationOrigin", IntID::AlertNotificationOrigin
, false, 0},
62 {"ui.scrollToClick", IntID::ScrollToClick
, false, 0},
63 {"ui.IMERawInputUnderlineStyle", IntID::IMERawInputUnderlineStyle
, false,
65 {"ui.IMESelectedRawTextUnderlineStyle",
66 IntID::IMESelectedRawTextUnderlineStyle
, false, 0},
67 {"ui.IMEConvertedTextUnderlineStyle", IntID::IMEConvertedTextUnderlineStyle
,
69 {"ui.IMESelectedConvertedTextUnderlineStyle",
70 IntID::IMESelectedConvertedTextUnderline
, false, 0},
71 {"ui.SpellCheckerUnderlineStyle", IntID::SpellCheckerUnderlineStyle
, false,
73 {"ui.scrollbarButtonAutoRepeatBehavior",
74 IntID::ScrollbarButtonAutoRepeatBehavior
, false, 0},
75 {"ui.tooltipDelay", IntID::TooltipDelay
, false, 0},
76 {"ui.contextMenuOffsetVertical", IntID::ContextMenuOffsetVertical
, false,
78 {"ui.contextMenuOffsetHorizontal", IntID::ContextMenuOffsetHorizontal
,
80 {"ui.GtkCSDAvailable", IntID::GTKCSDAvailable
, false, 0},
81 {"ui.GtkCSDHideTitlebarByDefault", IntID::GTKCSDHideTitlebarByDefault
,
83 {"ui.GtkCSDTransparentBackground", IntID::GTKCSDTransparentBackground
,
85 {"ui.GtkCSDMinimizeButton", IntID::GTKCSDMinimizeButton
, false, 0},
86 {"ui.GtkCSDMaximizeButton", IntID::GTKCSDMaximizeButton
, false, 0},
87 {"ui.GtkCSDCloseButton", IntID::GTKCSDCloseButton
, false, 0},
88 {"ui.systemUsesDarkTheme", IntID::SystemUsesDarkTheme
, false, 0},
89 {"ui.prefersReducedMotion", IntID::PrefersReducedMotion
, false, 0},
90 {"ui.primaryPointerCapabilities", IntID::PrimaryPointerCapabilities
, false,
91 6 /* fine and hover-capable pointer, i.e. mouse-type */},
92 {"ui.allPointerCapabilities", IntID::AllPointerCapabilities
, false,
93 6 /* fine and hover-capable pointer, i.e. mouse-type */},
96 nsLookAndFeelFloatPref
nsXPLookAndFeel::sFloatPrefs
[] = {
97 {"ui.IMEUnderlineRelativeSize", FloatID::IMEUnderlineRelativeSize
, false,
99 {"ui.SpellCheckerUnderlineRelativeSize",
100 FloatID::SpellCheckerUnderlineRelativeSize
, false, 0},
101 {"ui.caretAspectRatio", FloatID::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",
224 "ui.-moz-colheadertext",
225 "ui.-moz-colheaderhovertext"};
227 int32_t nsXPLookAndFeel::sCachedColors
[size_t(LookAndFeel::ColorID::End
)] = {0};
228 int32_t nsXPLookAndFeel::sCachedColorBits
[COLOR_CACHE_SIZE
] = {0};
230 bool nsXPLookAndFeel::sInitialized
= false;
232 nsXPLookAndFeel
* nsXPLookAndFeel::sInstance
= nullptr;
233 bool nsXPLookAndFeel::sShutdown
= false;
236 nsXPLookAndFeel
* nsXPLookAndFeel::GetInstance() {
241 NS_ENSURE_TRUE(!sShutdown
, nullptr);
243 if (gfxPlatform::IsHeadless()) {
244 sInstance
= new widget::HeadlessLookAndFeel();
246 sInstance
= new nsLookAndFeel();
252 void nsXPLookAndFeel::Shutdown() {
262 void nsXPLookAndFeel::IntPrefChanged(nsLookAndFeelIntPref
* data
) {
268 nsresult rv
= Preferences::GetInt(data
->name
, &intpref
);
273 printf("====== Cleared int pref %s\n", data
->name
);
276 data
->intVar
= intpref
;
280 printf("====== Changed int pref %s to %d\n", data
->name
, data
->intVar
);
284 NotifyChangedAllWindows();
288 void nsXPLookAndFeel::FloatPrefChanged(nsLookAndFeelFloatPref
* data
) {
294 nsresult rv
= Preferences::GetInt(data
->name
, &intpref
);
299 printf("====== Cleared float pref %s\n", data
->name
);
302 data
->floatVar
= (float)intpref
/ 100.0f
;
306 printf("====== Changed float pref %s to %f\n", data
->name
);
310 NotifyChangedAllWindows();
314 void nsXPLookAndFeel::ColorPrefChanged(unsigned int index
,
315 const char* prefName
) {
316 nsAutoString colorStr
;
317 nsresult rv
= Preferences::GetString(prefName
, colorStr
);
318 if (NS_SUCCEEDED(rv
) && !colorStr
.IsEmpty()) {
320 if (colorStr
[0] == char16_t('#')) {
321 if (NS_HexToRGBA(nsDependentString(colorStr
, 1), nsHexColorType::NoAlpha
,
323 int32_t id
= NS_PTR_TO_INT32(index
);
324 CACHE_COLOR(id
, thecolor
);
326 } else if (NS_ColorNameToRGB(colorStr
, &thecolor
)) {
327 int32_t id
= NS_PTR_TO_INT32(index
);
328 CACHE_COLOR(id
, thecolor
);
330 printf("====== Changed color pref %s to 0x%lx\n", prefName
, thecolor
);
334 // Reset to the default color, by clearing the cache
335 // to force lookup when the color is next used
336 int32_t id
= NS_PTR_TO_INT32(index
);
337 CLEAR_COLOR_CACHE(id
);
340 printf("====== Cleared color pref %s\n", prefName
);
344 NotifyChangedAllWindows();
347 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelIntPref
* aPref
) {
349 nsresult rv
= Preferences::GetInt(aPref
->name
, &intpref
);
350 if (NS_SUCCEEDED(rv
)) {
352 aPref
->intVar
= intpref
;
356 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelFloatPref
* aPref
) {
358 nsresult rv
= Preferences::GetInt(aPref
->name
, &intpref
);
359 if (NS_SUCCEEDED(rv
)) {
361 aPref
->floatVar
= (float)intpref
/ 100.0f
;
365 void nsXPLookAndFeel::InitColorFromPref(int32_t i
) {
366 static_assert(ArrayLength(sColorPrefs
) == size_t(ColorID::End
),
367 "Should have a pref for each color value");
369 nsAutoString colorStr
;
370 nsresult rv
= Preferences::GetString(sColorPrefs
[i
], colorStr
);
371 if (NS_FAILED(rv
) || colorStr
.IsEmpty()) {
375 if (colorStr
[0] == char16_t('#')) {
376 nsAutoString hexString
;
377 colorStr
.Right(hexString
, colorStr
.Length() - 1);
378 if (NS_HexToRGBA(hexString
, nsHexColorType::NoAlpha
, &thecolor
)) {
379 CACHE_COLOR(i
, thecolor
);
381 } else if (NS_ColorNameToRGB(colorStr
, &thecolor
)) {
382 CACHE_COLOR(i
, thecolor
);
387 void nsXPLookAndFeel::OnPrefChanged(const char* aPref
, void* aClosure
) {
388 // looping in the same order as in ::Init
390 nsDependentCString
prefName(aPref
);
392 for (i
= 0; i
< ArrayLength(sIntPrefs
); ++i
) {
393 if (prefName
.Equals(sIntPrefs
[i
].name
)) {
394 IntPrefChanged(&sIntPrefs
[i
]);
399 for (i
= 0; i
< ArrayLength(sFloatPrefs
); ++i
) {
400 if (prefName
.Equals(sFloatPrefs
[i
].name
)) {
401 FloatPrefChanged(&sFloatPrefs
[i
]);
406 for (i
= 0; i
< ArrayLength(sColorPrefs
); ++i
) {
407 if (prefName
.Equals(sColorPrefs
[i
])) {
408 ColorPrefChanged(i
, sColorPrefs
[i
]);
415 // Read values from the user's preferences.
416 // This is done once at startup, but since the user's preferences
417 // haven't actually been read yet at that time, we also have to
418 // set a callback to inform us of changes to each pref.
420 void nsXPLookAndFeel::Init() {
421 MOZ_RELEASE_ASSERT(NS_IsMainThread());
423 // Say we're already initialized, and take the chance that it might fail;
424 // protects against some other process writing to our static variables.
427 // XXX If we could reorganize the pref names, we should separate the branch
428 // for each types. Then, we could reduce the unnecessary loop from
429 // nsXPLookAndFeel::OnPrefChanged().
430 Preferences::RegisterPrefixCallback(OnPrefChanged
, "ui.");
431 // We really do just want the accessibility.tabfocus pref, not other prefs
432 // that start with that string.
433 Preferences::RegisterCallback(OnPrefChanged
, "accessibility.tabfocus");
436 for (i
= 0; i
< ArrayLength(sIntPrefs
); ++i
) {
437 InitFromPref(&sIntPrefs
[i
]);
440 for (i
= 0; i
< ArrayLength(sFloatPrefs
); ++i
) {
441 InitFromPref(&sFloatPrefs
[i
]);
444 for (i
= 0; i
< ArrayLength(sColorPrefs
); ++i
) {
445 InitColorFromPref(i
);
448 if (XRE_IsContentProcess()) {
449 mozilla::dom::ContentChild
* cc
= mozilla::dom::ContentChild::GetSingleton();
451 LookAndFeel::SetIntCache(cc
->LookAndFeelCache());
452 // This is only ever used once during initialization, and can be cleared
454 cc
->LookAndFeelCache().Clear();
458 nsXPLookAndFeel::~nsXPLookAndFeel() {
459 NS_ASSERTION(sInstance
== this,
460 "This destroying instance isn't the singleton instance");
464 bool nsXPLookAndFeel::IsSpecialColor(ColorID aID
, nscolor
& aColor
) {
466 case ColorID::TextSelectForeground
:
467 return (aColor
== NS_DONT_CHANGE_COLOR
);
468 case ColorID::IMESelectedRawTextBackground
:
469 case ColorID::IMESelectedConvertedTextBackground
:
470 case ColorID::IMERawInputBackground
:
471 case ColorID::IMEConvertedTextBackground
:
472 case ColorID::IMESelectedRawTextForeground
:
473 case ColorID::IMESelectedConvertedTextForeground
:
474 case ColorID::IMERawInputForeground
:
475 case ColorID::IMEConvertedTextForeground
:
476 case ColorID::IMERawInputUnderline
:
477 case ColorID::IMEConvertedTextUnderline
:
478 case ColorID::IMESelectedRawTextUnderline
:
479 case ColorID::IMESelectedConvertedTextUnderline
:
480 case ColorID::SpellCheckerUnderline
:
481 return NS_IS_SELECTION_SPECIAL_COLOR(aColor
);
484 * In GetColor(), every color that is not a special color is color
485 * corrected. Use false to make other colors color corrected.
492 bool nsXPLookAndFeel::ColorIsNotCSSAccessible(ColorID aID
) {
496 case ColorID::WindowBackground
:
497 case ColorID::WindowForeground
:
498 case ColorID::WidgetBackground
:
499 case ColorID::WidgetForeground
:
500 case ColorID::WidgetSelectBackground
:
501 case ColorID::WidgetSelectForeground
:
502 case ColorID::Widget3DHighlight
:
503 case ColorID::Widget3DShadow
:
504 case ColorID::TextBackground
:
505 case ColorID::TextForeground
:
506 case ColorID::TextSelectBackground
:
507 case ColorID::TextSelectForeground
:
508 case ColorID::TextSelectBackgroundDisabled
:
509 case ColorID::TextSelectBackgroundAttention
:
510 case ColorID::TextHighlightBackground
:
511 case ColorID::TextHighlightForeground
:
512 case ColorID::IMERawInputBackground
:
513 case ColorID::IMERawInputForeground
:
514 case ColorID::IMERawInputUnderline
:
515 case ColorID::IMESelectedRawTextBackground
:
516 case ColorID::IMESelectedRawTextForeground
:
517 case ColorID::IMESelectedRawTextUnderline
:
518 case ColorID::IMEConvertedTextBackground
:
519 case ColorID::IMEConvertedTextForeground
:
520 case ColorID::IMEConvertedTextUnderline
:
521 case ColorID::IMESelectedConvertedTextBackground
:
522 case ColorID::IMESelectedConvertedTextForeground
:
523 case ColorID::IMESelectedConvertedTextUnderline
:
524 case ColorID::SpellCheckerUnderline
:
534 nscolor
nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID
) {
535 nscolor result
= NS_RGB(0xFF, 0xFF, 0xFF);
537 // The stand-in colors are taken from the Windows 7 Aero theme
538 // except Mac-specific colors which are taken from Mac OS 10.7.
541 case ColorID::Activeborder
:
542 result
= NS_RGB(0xB4, 0xB4, 0xB4);
544 case ColorID::Activecaption
:
545 result
= NS_RGB(0x99, 0xB4, 0xD1);
547 case ColorID::Appworkspace
:
548 result
= NS_RGB(0xAB, 0xAB, 0xAB);
550 case ColorID::Background
:
551 result
= NS_RGB(0x00, 0x00, 0x00);
553 case ColorID::Buttonface
:
554 result
= NS_RGB(0xF0, 0xF0, 0xF0);
556 case ColorID::Buttonhighlight
:
557 result
= NS_RGB(0xFF, 0xFF, 0xFF);
559 case ColorID::Buttonshadow
:
560 result
= NS_RGB(0xA0, 0xA0, 0xA0);
562 case ColorID::Buttontext
:
563 result
= NS_RGB(0x00, 0x00, 0x00);
565 case ColorID::Captiontext
:
566 result
= NS_RGB(0x00, 0x00, 0x00);
568 case ColorID::Graytext
:
569 result
= NS_RGB(0x6D, 0x6D, 0x6D);
571 case ColorID::Highlight
:
572 result
= NS_RGB(0x33, 0x99, 0xFF);
574 case ColorID::Highlighttext
:
575 result
= NS_RGB(0xFF, 0xFF, 0xFF);
577 case ColorID::Inactiveborder
:
578 result
= NS_RGB(0xF4, 0xF7, 0xFC);
580 case ColorID::Inactivecaption
:
581 result
= NS_RGB(0xBF, 0xCD, 0xDB);
583 case ColorID::Inactivecaptiontext
:
584 result
= NS_RGB(0x43, 0x4E, 0x54);
586 case ColorID::Infobackground
:
587 result
= NS_RGB(0xFF, 0xFF, 0xE1);
589 case ColorID::Infotext
:
590 result
= NS_RGB(0x00, 0x00, 0x00);
593 result
= NS_RGB(0xF0, 0xF0, 0xF0);
595 case ColorID::Menutext
:
596 result
= NS_RGB(0x00, 0x00, 0x00);
598 case ColorID::Scrollbar
:
599 result
= NS_RGB(0xC8, 0xC8, 0xC8);
601 case ColorID::Threeddarkshadow
:
602 result
= NS_RGB(0x69, 0x69, 0x69);
604 case ColorID::Threedface
:
605 result
= NS_RGB(0xF0, 0xF0, 0xF0);
607 case ColorID::Threedhighlight
:
608 result
= NS_RGB(0xFF, 0xFF, 0xFF);
610 case ColorID::Threedlightshadow
:
611 result
= NS_RGB(0xE3, 0xE3, 0xE3);
613 case ColorID::Threedshadow
:
614 result
= NS_RGB(0xA0, 0xA0, 0xA0);
616 case ColorID::Window
:
617 result
= NS_RGB(0xFF, 0xFF, 0xFF);
619 case ColorID::Windowframe
:
620 result
= NS_RGB(0x64, 0x64, 0x64);
622 case ColorID::Windowtext
:
623 result
= NS_RGB(0x00, 0x00, 0x00);
625 case ColorID::MozButtondefault
:
626 result
= NS_RGB(0x69, 0x69, 0x69);
629 result
= NS_RGB(0xFF, 0xFF, 0xFF);
631 case ColorID::Fieldtext
:
632 result
= NS_RGB(0x00, 0x00, 0x00);
634 case ColorID::MozDialog
:
635 result
= NS_RGB(0xF0, 0xF0, 0xF0);
637 case ColorID::MozDialogtext
:
638 case ColorID::MozColheadertext
:
639 case ColorID::MozColheaderhovertext
:
640 result
= NS_RGB(0x00, 0x00, 0x00);
642 case ColorID::MozDragtargetzone
:
643 result
= NS_RGB(0xFF, 0xFF, 0xFF);
645 case ColorID::MozCellhighlight
:
646 result
= NS_RGB(0xF0, 0xF0, 0xF0);
648 case ColorID::MozCellhighlighttext
:
649 result
= NS_RGB(0x00, 0x00, 0x00);
651 case ColorID::MozHtmlCellhighlight
:
652 result
= NS_RGB(0x33, 0x99, 0xFF);
654 case ColorID::MozHtmlCellhighlighttext
:
655 result
= NS_RGB(0xFF, 0xFF, 0xFF);
657 case ColorID::MozButtonhoverface
:
658 result
= NS_RGB(0xF0, 0xF0, 0xF0);
660 case ColorID::MozButtonhovertext
:
661 result
= NS_RGB(0x00, 0x00, 0x00);
663 case ColorID::MozMenuhover
:
664 result
= NS_RGB(0x33, 0x99, 0xFF);
666 case ColorID::MozMenuhovertext
:
667 result
= NS_RGB(0x00, 0x00, 0x00);
669 case ColorID::MozMenubartext
:
670 result
= NS_RGB(0x00, 0x00, 0x00);
672 case ColorID::MozMenubarhovertext
:
673 result
= NS_RGB(0x00, 0x00, 0x00);
675 case ColorID::MozOddtreerow
:
676 case ColorID::MozGtkButtonactivetext
:
677 result
= NS_RGB(0xFF, 0xFF, 0xFF);
679 case ColorID::MozMacChromeActive
:
680 result
= NS_RGB(0xB2, 0xB2, 0xB2);
682 case ColorID::MozMacChromeInactive
:
683 result
= NS_RGB(0xE1, 0xE1, 0xE1);
685 case ColorID::MozMacFocusring
:
686 result
= NS_RGB(0x60, 0x9D, 0xD7);
688 case ColorID::MozMacMenuselect
:
689 result
= NS_RGB(0x38, 0x75, 0xD7);
691 case ColorID::MozMacMenushadow
:
692 result
= NS_RGB(0xA3, 0xA3, 0xA3);
694 case ColorID::MozMacMenutextdisable
:
695 result
= NS_RGB(0x88, 0x88, 0x88);
697 case ColorID::MozMacMenutextselect
:
698 result
= NS_RGB(0xFF, 0xFF, 0xFF);
700 case ColorID::MozMacDisabledtoolbartext
:
701 result
= NS_RGB(0x3F, 0x3F, 0x3F);
703 case ColorID::MozMacSecondaryhighlight
:
704 result
= NS_RGB(0xD4, 0xD4, 0xD4);
706 case ColorID::MozMacVibrancyLight
:
707 case ColorID::MozMacVibrantTitlebarLight
:
708 result
= NS_RGB(0xf7, 0xf7, 0xf7);
710 case ColorID::MozMacVibrancyDark
:
711 case ColorID::MozMacVibrantTitlebarDark
:
712 result
= NS_RGB(0x28, 0x28, 0x28);
714 case ColorID::MozMacMenupopup
:
715 result
= NS_RGB(0xe6, 0xe6, 0xe6);
717 case ColorID::MozMacMenuitem
:
718 result
= NS_RGB(0xe6, 0xe6, 0xe6);
720 case ColorID::MozMacActiveMenuitem
:
721 result
= NS_RGB(0x0a, 0x64, 0xdc);
723 case ColorID::MozMacSourceList
:
724 result
= NS_RGB(0xf7, 0xf7, 0xf7);
726 case ColorID::MozMacSourceListSelection
:
727 result
= NS_RGB(0xc8, 0xc8, 0xc8);
729 case ColorID::MozMacActiveSourceListSelection
:
730 result
= NS_RGB(0x0a, 0x64, 0xdc);
732 case ColorID::MozMacTooltip
:
733 result
= NS_RGB(0xf7, 0xf7, 0xf7);
735 case ColorID::MozWinAccentcolor
:
736 // Seems to be the default color (hardcoded because of bug 1065998)
737 result
= NS_RGB(0x9E, 0x9E, 0x9E);
739 case ColorID::MozWinAccentcolortext
:
740 result
= NS_RGB(0x00, 0x00, 0x00);
742 case ColorID::MozWinMediatext
:
743 result
= NS_RGB(0xFF, 0xFF, 0xFF);
745 case ColorID::MozWinCommunicationstext
:
746 result
= NS_RGB(0xFF, 0xFF, 0xFF);
748 case ColorID::MozNativehyperlinktext
:
749 result
= NS_RGB(0x00, 0x66, 0xCC);
751 case ColorID::MozComboboxtext
:
752 result
= NS_RGB(0x00, 0x00, 0x00);
754 case ColorID::MozCombobox
:
755 result
= NS_RGB(0xFF, 0xFF, 0xFF);
765 // All these routines will return NS_OK if they have a value,
766 // in which case the nsLookAndFeel should use that value;
767 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
768 // platform-specific nsLookAndFeel should use its own values instead.
770 nsresult
nsXPLookAndFeel::GetColorImpl(ColorID aID
,
771 bool aUseStandinsForNativeColors
,
773 if (!sInitialized
) Init();
775 // define DEBUG_SYSTEM_COLOR_USE if you want to debug system color
776 // use in a skin that uses them. When set, it will make all system
777 // color pairs that are appropriate for foreground/background
778 // pairing the same. This means if the skin is using system colors
779 // correctly you will not be able to see *any* text.
780 #undef DEBUG_SYSTEM_COLOR_USE
782 #ifdef DEBUG_SYSTEM_COLOR_USE
786 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
787 case ColorID::Activecaption
:
788 // active window caption background
789 case ColorID::Captiontext
:
790 // text in active window caption
791 aResult
= NS_RGB(0xff, 0x00, 0x00);
794 case ColorID::Highlight
:
795 // background of selected item
796 case ColorID::Highlighttext
:
797 // text of selected item
798 aResult
= NS_RGB(0xff, 0xff, 0x00);
801 case ColorID::Inactivecaption
:
802 // inactive window caption
803 case ColorID::Inactivecaptiontext
:
804 // text in inactive window caption
805 aResult
= NS_RGB(0x66, 0x66, 0x00);
808 case ColorID::Infobackground
:
809 // tooltip background color
810 case ColorID::Infotext
:
811 // tooltip text color
812 aResult
= NS_RGB(0x00, 0xff, 0x00);
817 case ColorID::Menutext
:
819 aResult
= NS_RGB(0x00, 0xff, 0xff);
822 case ColorID::Threedface
:
823 case ColorID::Buttonface
:
825 case ColorID::Buttontext
:
826 // text on push buttons
827 aResult
= NS_RGB(0x00, 0x66, 0x66);
830 case ColorID::Window
:
831 case ColorID::Windowtext
:
832 aResult
= NS_RGB(0x00, 0x00, 0xff);
835 // from the CSS3 working draft (not yet finalized)
836 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
839 case ColorID::Fieldtext
:
840 aResult
= NS_RGB(0xff, 0x00, 0xff);
843 case ColorID::MozDialog
:
844 case ColorID::MozDialogtext
:
845 aResult
= NS_RGB(0x66, 0x00, 0x66);
849 rv
= NS_ERROR_NOT_AVAILABLE
;
851 if (NS_SUCCEEDED(rv
)) return rv
;
853 #endif // DEBUG_SYSTEM_COLOR_USE
855 if (aUseStandinsForNativeColors
&&
856 (ColorIsNotCSSAccessible(aID
) ||
857 !nsContentUtils::UseStandinsForNativeColors())) {
858 aUseStandinsForNativeColors
= false;
861 if (!aUseStandinsForNativeColors
&& IS_COLOR_CACHED(aID
)) {
862 aResult
= sCachedColors
[uint32_t(aID
)];
866 // There are no system color settings for these, so set them manually
868 if (aID
== ColorID::TextSelectBackgroundDisabled
) {
869 // This is used to gray out the selection when it's not focused
870 // Used with nsISelectionController::SELECTION_DISABLED
871 aResult
= NS_RGB(0xb0, 0xb0, 0xb0);
876 if (aID
== ColorID::TextSelectBackgroundAttention
) {
877 if (StaticPrefs::findbar_modalHighlight() && !mozilla::FissionAutostart()) {
878 aResult
= NS_RGBA(0, 0, 0, 0);
882 // This makes the selection stand out when typeaheadfind is on
883 // Used with nsISelectionController::SELECTION_ATTENTION
884 aResult
= NS_RGB(0x38, 0xd8, 0x78);
888 if (aID
== ColorID::TextHighlightBackground
) {
889 // This makes the matched text stand out when findbar highlighting is on
890 // Used with nsISelectionController::SELECTION_FIND
891 aResult
= NS_RGB(0xef, 0x0f, 0xff);
895 if (aID
== ColorID::TextHighlightForeground
) {
896 // The foreground color for the matched text in findbar highlighting
897 // Used with nsISelectionController::SELECTION_FIND
898 aResult
= NS_RGB(0xff, 0xff, 0xff);
902 if (StaticPrefs::ui_use_native_colors() && aUseStandinsForNativeColors
) {
903 aResult
= GetStandinForNativeColor(aID
);
907 if (StaticPrefs::ui_use_native_colors() &&
908 NS_SUCCEEDED(NativeGetColor(aID
, aResult
))) {
909 if (!mozilla::ServoStyleSet::IsInServoTraversal()) {
910 MOZ_ASSERT(NS_IsMainThread());
911 if ((gfxPlatform::GetCMSMode() == eCMSMode_All
) &&
912 !IsSpecialColor(aID
, aResult
)) {
913 qcms_transform
* transform
= gfxPlatform::GetCMSInverseRGBTransform();
916 color
[0] = NS_GET_R(aResult
);
917 color
[1] = NS_GET_G(aResult
);
918 color
[2] = NS_GET_B(aResult
);
919 color
[3] = NS_GET_A(aResult
);
920 qcms_transform_data(transform
, color
, color
, 1);
921 aResult
= NS_RGBA(color
[0], color
[1], color
[2], color
[3]);
925 CACHE_COLOR(aID
, aResult
);
930 return NS_ERROR_NOT_AVAILABLE
;
933 nsresult
nsXPLookAndFeel::GetIntImpl(IntID aID
, int32_t& aResult
) {
934 if (!sInitialized
) Init();
936 // Set the default values for these prefs. but allow different platforms
937 // to override them in their nsLookAndFeel if desired.
939 case IntID::ScrollButtonLeftMouseButtonAction
:
942 case IntID::ScrollButtonMiddleMouseButtonAction
:
945 case IntID::ScrollButtonRightMouseButtonAction
:
950 * The metrics above are hardcoded platform defaults. All the other
951 * metrics are stored in sIntPrefs and can be changed at runtime.
956 for (unsigned int i
= 0; i
< ArrayLength(sIntPrefs
); ++i
) {
957 if (sIntPrefs
[i
].isSet
&& (sIntPrefs
[i
].id
== aID
)) {
958 aResult
= sIntPrefs
[i
].intVar
;
963 return NS_ERROR_NOT_AVAILABLE
;
966 nsresult
nsXPLookAndFeel::GetFloatImpl(FloatID aID
, float& aResult
) {
967 if (!sInitialized
) Init();
969 for (unsigned int i
= 0; i
< ArrayLength(sFloatPrefs
); ++i
) {
970 if (sFloatPrefs
[i
].isSet
&& sFloatPrefs
[i
].id
== aID
) {
971 aResult
= sFloatPrefs
[i
].floatVar
;
976 return NS_ERROR_NOT_AVAILABLE
;
979 void nsXPLookAndFeel::RefreshImpl() {
980 // Wipe out our color cache.
982 for (i
= 0; i
< uint32_t(ColorID::End
); i
++) {
983 sCachedColors
[i
] = 0;
985 for (i
= 0; i
< COLOR_CACHE_SIZE
; i
++) {
986 sCachedColorBits
[i
] = 0;
989 // Reinit color cache from prefs.
990 for (i
= 0; i
< uint32_t(ColorID::End
); ++i
) {
991 InitColorFromPref(i
);
995 nsTArray
<LookAndFeelInt
> nsXPLookAndFeel::GetIntCacheImpl() {
996 return nsTArray
<LookAndFeelInt
>();
999 static bool sRecordedLookAndFeelTelemetry
= false;
1001 void nsXPLookAndFeel::RecordTelemetry() {
1002 if (sRecordedLookAndFeelTelemetry
) {
1006 sRecordedLookAndFeelTelemetry
= true;
1009 Telemetry::ScalarSet(
1010 Telemetry::ScalarID::WIDGET_DARK_MODE
,
1011 NS_SUCCEEDED(GetIntImpl(IntID::SystemUsesDarkTheme
, i
)) && i
!= 0);
1017 void LookAndFeel::NotifyChangedAllWindows() {
1018 if (nsCOMPtr
<nsIObserverService
> obs
= services::GetObserverService()) {
1019 obs
->NotifyObservers(nullptr, "look-and-feel-changed", nullptr);
1024 nsresult
LookAndFeel::GetColor(ColorID aID
, nscolor
* aResult
) {
1025 return nsLookAndFeel::GetInstance()->GetColorImpl(aID
, false, *aResult
);
1028 nsresult
LookAndFeel::GetColor(ColorID aID
, bool aUseStandinsForNativeColors
,
1030 return nsLookAndFeel::GetInstance()->GetColorImpl(
1031 aID
, aUseStandinsForNativeColors
, *aResult
);
1035 nsresult
LookAndFeel::GetInt(IntID aID
, int32_t* aResult
) {
1036 return nsLookAndFeel::GetInstance()->GetIntImpl(aID
, *aResult
);
1040 nsresult
LookAndFeel::GetFloat(FloatID aID
, float* aResult
) {
1041 return nsLookAndFeel::GetInstance()->GetFloatImpl(aID
, *aResult
);
1045 bool LookAndFeel::GetFont(FontID aID
, nsString
& aName
, gfxFontStyle
& aStyle
) {
1046 return nsLookAndFeel::GetInstance()->GetFontImpl(aID
, aName
, aStyle
);
1050 char16_t
LookAndFeel::GetPasswordCharacter() {
1051 return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
1055 bool LookAndFeel::GetEchoPassword() {
1056 if (StaticPrefs::editor_password_mask_delay() >= 0) {
1057 return StaticPrefs::editor_password_mask_delay() > 0;
1059 return nsLookAndFeel::GetInstance()->GetEchoPasswordImpl();
1063 uint32_t LookAndFeel::GetPasswordMaskDelay() {
1064 int32_t delay
= StaticPrefs::editor_password_mask_delay();
1066 return nsLookAndFeel::GetInstance()->GetPasswordMaskDelayImpl();
1072 void LookAndFeel::Refresh() { nsLookAndFeel::GetInstance()->RefreshImpl(); }
1075 void LookAndFeel::NativeInit() { nsLookAndFeel::GetInstance()->NativeInit(); }
1078 nsTArray
<LookAndFeelInt
> LookAndFeel::GetIntCache() {
1079 return nsLookAndFeel::GetInstance()->GetIntCacheImpl();
1083 void LookAndFeel::SetIntCache(
1084 const nsTArray
<LookAndFeelInt
>& aLookAndFeelIntCache
) {
1085 return nsLookAndFeel::GetInstance()->SetIntCacheImpl(aLookAndFeelIntCache
);
1088 } // namespace mozilla