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 "nsContentUtils.h"
16 #include "nsIXULRuntime.h"
17 #include "mozilla/dom/ContentChild.h"
18 #include "mozilla/Preferences.h"
19 #include "mozilla/Services.h"
20 #include "mozilla/ServoStyleSet.h"
21 #include "mozilla/StaticPrefs_editor.h"
22 #include "mozilla/StaticPrefs_findbar.h"
23 #include "mozilla/StaticPrefs_ui.h"
24 #include "mozilla/gfx/2D.h"
25 #include "mozilla/widget/WidgetMessageUtils.h"
26 #include "mozilla/Telemetry.h"
27 #include "mozilla/TelemetryScalarEnums.h"
29 #include "gfxPlatform.h"
37 using namespace mozilla
;
39 nsLookAndFeelIntPref
nsXPLookAndFeel::sIntPrefs
[] = {
40 {"ui.caretBlinkTime", IntID::CaretBlinkTime
, false, 0},
41 {"ui.caretWidth", IntID::CaretWidth
, false, 0},
42 {"ui.caretVisibleWithSelection", IntID::ShowCaretDuringSelection
, false, 0},
43 {"ui.submenuDelay", IntID::SubmenuDelay
, false, 0},
44 {"ui.dragThresholdX", IntID::DragThresholdX
, false, 0},
45 {"ui.dragThresholdY", IntID::DragThresholdY
, false, 0},
46 {"ui.useAccessibilityTheme", IntID::UseAccessibilityTheme
, false, 0},
47 {"ui.menusCanOverlapOSBar", IntID::MenusCanOverlapOSBar
, false, 0},
48 {"ui.useOverlayScrollbars", IntID::UseOverlayScrollbars
, false, 0},
49 {"ui.scrollbarDisplayOnMouseMove", IntID::ScrollbarDisplayOnMouseMove
,
51 {"ui.scrollbarFadeBeginDelay", IntID::ScrollbarFadeBeginDelay
, false, 0},
52 {"ui.scrollbarFadeDuration", IntID::ScrollbarFadeDuration
, false, 0},
53 {"ui.showHideScrollbars", IntID::ShowHideScrollbars
, false, 0},
54 {"ui.skipNavigatingDisabledMenuItem", IntID::SkipNavigatingDisabledMenuItem
,
56 {"ui.treeOpenDelay", IntID::TreeOpenDelay
, false, 0},
57 {"ui.treeCloseDelay", IntID::TreeCloseDelay
, false, 0},
58 {"ui.treeLazyScrollDelay", IntID::TreeLazyScrollDelay
, false, 0},
59 {"ui.treeScrollDelay", IntID::TreeScrollDelay
, false, 0},
60 {"ui.treeScrollLinesMax", IntID::TreeScrollLinesMax
, false, 0},
61 {"accessibility.tabfocus", IntID::TabFocusModel
, false, 0},
62 {"ui.alertNotificationOrigin", IntID::AlertNotificationOrigin
, false, 0},
63 {"ui.scrollToClick", IntID::ScrollToClick
, false, 0},
64 {"ui.IMERawInputUnderlineStyle", IntID::IMERawInputUnderlineStyle
, false,
66 {"ui.IMESelectedRawTextUnderlineStyle",
67 IntID::IMESelectedRawTextUnderlineStyle
, false, 0},
68 {"ui.IMEConvertedTextUnderlineStyle", IntID::IMEConvertedTextUnderlineStyle
,
70 {"ui.IMESelectedConvertedTextUnderlineStyle",
71 IntID::IMESelectedConvertedTextUnderline
, false, 0},
72 {"ui.SpellCheckerUnderlineStyle", IntID::SpellCheckerUnderlineStyle
, false,
74 {"ui.scrollbarButtonAutoRepeatBehavior",
75 IntID::ScrollbarButtonAutoRepeatBehavior
, false, 0},
76 {"ui.tooltipDelay", IntID::TooltipDelay
, false, 0},
77 {"ui.contextMenuOffsetVertical", IntID::ContextMenuOffsetVertical
, false,
79 {"ui.contextMenuOffsetHorizontal", IntID::ContextMenuOffsetHorizontal
,
81 {"ui.GtkCSDAvailable", IntID::GTKCSDAvailable
, false, 0},
82 {"ui.GtkCSDHideTitlebarByDefault", IntID::GTKCSDHideTitlebarByDefault
,
84 {"ui.GtkCSDTransparentBackground", IntID::GTKCSDTransparentBackground
,
86 {"ui.GtkCSDMinimizeButton", IntID::GTKCSDMinimizeButton
, false, 0},
87 {"ui.GtkCSDMaximizeButton", IntID::GTKCSDMaximizeButton
, false, 0},
88 {"ui.GtkCSDCloseButton", IntID::GTKCSDCloseButton
, false, 0},
89 {"ui.systemUsesDarkTheme", IntID::SystemUsesDarkTheme
, false, 0},
90 {"ui.prefersReducedMotion", IntID::PrefersReducedMotion
, false, 0},
91 {"ui.primaryPointerCapabilities", IntID::PrimaryPointerCapabilities
, false,
92 6 /* fine and hover-capable pointer, i.e. mouse-type */},
93 {"ui.allPointerCapabilities", IntID::AllPointerCapabilities
, false,
94 6 /* fine and hover-capable pointer, i.e. mouse-type */},
97 nsLookAndFeelFloatPref
nsXPLookAndFeel::sFloatPrefs
[] = {
98 {"ui.IMEUnderlineRelativeSize", FloatID::IMEUnderlineRelativeSize
, false,
100 {"ui.SpellCheckerUnderlineRelativeSize",
101 FloatID::SpellCheckerUnderlineRelativeSize
, false, 0},
102 {"ui.caretAspectRatio", FloatID::CaretAspectRatio
, false, 0},
105 // This array MUST be kept in the same order as the color list in
106 // specified/color.rs
107 /* XXX If you add any strings longer than
108 * "ui.-moz-mac-active-source-list-selection"
109 * to the following array then you MUST update the
110 * sizes of the sColorPrefs array in nsXPLookAndFeel.h
112 const char nsXPLookAndFeel::sColorPrefs
[][41] = {
113 "ui.windowBackground",
114 "ui.windowForeground",
115 "ui.widgetBackground",
116 "ui.widgetForeground",
117 "ui.widgetSelectBackground",
118 "ui.widgetSelectForeground",
119 "ui.widget3DHighlight",
123 "ui.textSelectBackground",
124 "ui.textSelectForeground",
125 "ui.textSelectForegroundCustom",
126 "ui.textSelectBackgroundDisabled",
127 "ui.textSelectBackgroundAttention",
128 "ui.textHighlightBackground",
129 "ui.textHighlightForeground",
130 "ui.IMERawInputBackground",
131 "ui.IMERawInputForeground",
132 "ui.IMERawInputUnderline",
133 "ui.IMESelectedRawTextBackground",
134 "ui.IMESelectedRawTextForeground",
135 "ui.IMESelectedRawTextUnderline",
136 "ui.IMEConvertedTextBackground",
137 "ui.IMEConvertedTextForeground",
138 "ui.IMEConvertedTextUnderline",
139 "ui.IMESelectedConvertedTextBackground",
140 "ui.IMESelectedConvertedTextForeground",
141 "ui.IMESelectedConvertedTextUnderline",
142 "ui.SpellCheckerUnderline",
148 "ui.buttonhighlight",
158 "ui.inactivecaption",
159 "ui.inactivecaptiontext",
165 "ui.threeddarkshadow",
167 "ui.threedhighlight",
168 "ui.threedlightshadow",
173 "ui.-moz-buttondefault",
174 "ui.-moz-default-color",
175 "ui.-moz-default-background-color",
177 "ui.-moz-dialogtext",
178 "ui.-moz-dragtargetzone",
179 "ui.-moz-cellhighlight",
180 "ui.-moz_cellhighlighttext",
181 "ui.-moz-html-cellhighlight",
182 "ui.-moz-html-cellhighlighttext",
183 "ui.-moz-buttonhoverface",
184 "ui.-moz_buttonhovertext",
186 "ui.-moz_menuhovertext",
187 "ui.-moz_menubartext",
188 "ui.-moz_menubarhovertext",
189 "ui.-moz_eventreerow",
190 "ui.-moz_oddtreerow",
191 "ui.-moz-gtk-buttonactivetext",
192 "ui.-moz-mac-buttonactivetext",
193 "ui.-moz_mac_chrome_active",
194 "ui.-moz_mac_chrome_inactive",
195 "ui.-moz-mac-defaultbuttontext",
196 "ui.-moz-mac-focusring",
197 "ui.-moz-mac-menuselect",
198 "ui.-moz-mac-menushadow",
199 "ui.-moz-mac-menutextdisable",
200 "ui.-moz-mac-menutextselect",
201 "ui.-moz_mac_disabledtoolbartext",
202 "ui.-moz-mac-secondaryhighlight",
203 "ui.-moz-mac-vibrancy-light",
204 "ui.-moz-mac-vibrancy-dark",
205 "ui.-moz-mac-vibrant-titlebar-light",
206 "ui.-moz-mac-vibrant-titlebar-dark",
207 "ui.-moz-mac-menupopup",
208 "ui.-moz-mac-menuitem",
209 "ui.-moz-mac-active-menuitem",
210 "ui.-moz-mac-source-list",
211 "ui.-moz-mac-source-list-selection",
212 "ui.-moz-mac-active-source-list-selection",
213 "ui.-moz-mac-tooltip",
214 "ui.-moz-win-accentcolor",
215 "ui.-moz-win-accentcolortext",
216 "ui.-moz-win-mediatext",
217 "ui.-moz-win-communicationstext",
218 "ui.-moz-nativehyperlinktext",
219 "ui.-moz-hyperlinktext",
220 "ui.-moz-activehyperlinktext",
221 "ui.-moz-visitedhyperlinktext",
222 "ui.-moz-comboboxtext",
224 "ui.-moz-gtk-info-bar-text",
225 "ui.-moz-colheadertext",
226 "ui.-moz-colheaderhovertext"};
228 int32_t nsXPLookAndFeel::sCachedColors
[size_t(LookAndFeel::ColorID::End
)] = {0};
229 int32_t nsXPLookAndFeel::sCachedColorBits
[COLOR_CACHE_SIZE
] = {0};
231 bool nsXPLookAndFeel::sInitialized
= false;
233 nsXPLookAndFeel
* nsXPLookAndFeel::sInstance
= nullptr;
234 bool nsXPLookAndFeel::sShutdown
= false;
237 nsXPLookAndFeel
* nsXPLookAndFeel::GetInstance() {
242 NS_ENSURE_TRUE(!sShutdown
, nullptr);
244 if (gfxPlatform::IsHeadless()) {
245 sInstance
= new widget::HeadlessLookAndFeel();
247 sInstance
= new nsLookAndFeel();
253 void nsXPLookAndFeel::Shutdown() {
263 void nsXPLookAndFeel::IntPrefChanged(nsLookAndFeelIntPref
* data
) {
269 nsresult rv
= Preferences::GetInt(data
->name
, &intpref
);
274 printf("====== Cleared int pref %s\n", data
->name
);
277 data
->intVar
= intpref
;
281 printf("====== Changed int pref %s to %d\n", data
->name
, data
->intVar
);
285 NotifyChangedAllWindows();
289 void nsXPLookAndFeel::FloatPrefChanged(nsLookAndFeelFloatPref
* data
) {
295 nsresult rv
= Preferences::GetInt(data
->name
, &intpref
);
300 printf("====== Cleared float pref %s\n", data
->name
);
303 data
->floatVar
= (float)intpref
/ 100.0f
;
307 printf("====== Changed float pref %s to %f\n", data
->name
);
311 NotifyChangedAllWindows();
315 void nsXPLookAndFeel::ColorPrefChanged(unsigned int index
,
316 const char* prefName
) {
317 nsAutoString colorStr
;
318 nsresult rv
= Preferences::GetString(prefName
, colorStr
);
319 if (NS_SUCCEEDED(rv
) && !colorStr
.IsEmpty()) {
321 if (colorStr
[0] == char16_t('#')) {
322 if (NS_HexToRGBA(nsDependentString(colorStr
, 1), nsHexColorType::NoAlpha
,
324 int32_t id
= NS_PTR_TO_INT32(index
);
325 CACHE_COLOR(id
, thecolor
);
327 } else if (NS_ColorNameToRGB(colorStr
, &thecolor
)) {
328 int32_t id
= NS_PTR_TO_INT32(index
);
329 CACHE_COLOR(id
, thecolor
);
331 printf("====== Changed color pref %s to 0x%lx\n", prefName
, thecolor
);
335 // Reset to the default color, by clearing the cache
336 // to force lookup when the color is next used
337 int32_t id
= NS_PTR_TO_INT32(index
);
338 CLEAR_COLOR_CACHE(id
);
341 printf("====== Cleared color pref %s\n", prefName
);
345 NotifyChangedAllWindows();
348 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelIntPref
* aPref
) {
350 nsresult rv
= Preferences::GetInt(aPref
->name
, &intpref
);
351 if (NS_SUCCEEDED(rv
)) {
353 aPref
->intVar
= intpref
;
357 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelFloatPref
* aPref
) {
359 nsresult rv
= Preferences::GetInt(aPref
->name
, &intpref
);
360 if (NS_SUCCEEDED(rv
)) {
362 aPref
->floatVar
= (float)intpref
/ 100.0f
;
366 void nsXPLookAndFeel::InitColorFromPref(int32_t i
) {
367 static_assert(ArrayLength(sColorPrefs
) == size_t(ColorID::End
),
368 "Should have a pref for each color value");
370 nsAutoString colorStr
;
371 nsresult rv
= Preferences::GetString(sColorPrefs
[i
], colorStr
);
372 if (NS_FAILED(rv
) || colorStr
.IsEmpty()) {
376 if (colorStr
[0] == char16_t('#')) {
377 nsAutoString hexString
;
378 colorStr
.Right(hexString
, colorStr
.Length() - 1);
379 if (NS_HexToRGBA(hexString
, nsHexColorType::NoAlpha
, &thecolor
)) {
380 CACHE_COLOR(i
, thecolor
);
382 } else if (NS_ColorNameToRGB(colorStr
, &thecolor
)) {
383 CACHE_COLOR(i
, thecolor
);
388 void nsXPLookAndFeel::OnPrefChanged(const char* aPref
, void* aClosure
) {
389 // looping in the same order as in ::Init
391 nsDependentCString
prefName(aPref
);
393 for (i
= 0; i
< ArrayLength(sIntPrefs
); ++i
) {
394 if (prefName
.Equals(sIntPrefs
[i
].name
)) {
395 IntPrefChanged(&sIntPrefs
[i
]);
400 for (i
= 0; i
< ArrayLength(sFloatPrefs
); ++i
) {
401 if (prefName
.Equals(sFloatPrefs
[i
].name
)) {
402 FloatPrefChanged(&sFloatPrefs
[i
]);
407 for (i
= 0; i
< ArrayLength(sColorPrefs
); ++i
) {
408 if (prefName
.Equals(sColorPrefs
[i
])) {
409 ColorPrefChanged(i
, sColorPrefs
[i
]);
416 // Read values from the user's preferences.
417 // This is done once at startup, but since the user's preferences
418 // haven't actually been read yet at that time, we also have to
419 // set a callback to inform us of changes to each pref.
421 void nsXPLookAndFeel::Init() {
422 MOZ_RELEASE_ASSERT(NS_IsMainThread());
424 // Say we're already initialized, and take the chance that it might fail;
425 // protects against some other process writing to our static variables.
428 // XXX If we could reorganize the pref names, we should separate the branch
429 // for each types. Then, we could reduce the unnecessary loop from
430 // nsXPLookAndFeel::OnPrefChanged().
431 Preferences::RegisterPrefixCallback(OnPrefChanged
, "ui.");
432 // We really do just want the accessibility.tabfocus pref, not other prefs
433 // that start with that string.
434 Preferences::RegisterCallback(OnPrefChanged
, "accessibility.tabfocus");
437 for (i
= 0; i
< ArrayLength(sIntPrefs
); ++i
) {
438 InitFromPref(&sIntPrefs
[i
]);
441 for (i
= 0; i
< ArrayLength(sFloatPrefs
); ++i
) {
442 InitFromPref(&sFloatPrefs
[i
]);
445 for (i
= 0; i
< ArrayLength(sColorPrefs
); ++i
) {
446 InitColorFromPref(i
);
449 if (XRE_IsContentProcess()) {
450 mozilla::dom::ContentChild
* cc
= mozilla::dom::ContentChild::GetSingleton();
452 LookAndFeel::SetIntCache(cc
->LookAndFeelCache());
453 // This is only ever used once during initialization, and can be cleared
455 cc
->LookAndFeelCache().Clear();
459 nsXPLookAndFeel::~nsXPLookAndFeel() {
460 NS_ASSERTION(sInstance
== this,
461 "This destroying instance isn't the singleton instance");
465 bool nsXPLookAndFeel::IsSpecialColor(ColorID aID
, nscolor
& aColor
) {
467 case ColorID::TextSelectForeground
:
468 return (aColor
== NS_DONT_CHANGE_COLOR
);
469 case ColorID::IMESelectedRawTextBackground
:
470 case ColorID::IMESelectedConvertedTextBackground
:
471 case ColorID::IMERawInputBackground
:
472 case ColorID::IMEConvertedTextBackground
:
473 case ColorID::IMESelectedRawTextForeground
:
474 case ColorID::IMESelectedConvertedTextForeground
:
475 case ColorID::IMERawInputForeground
:
476 case ColorID::IMEConvertedTextForeground
:
477 case ColorID::IMERawInputUnderline
:
478 case ColorID::IMEConvertedTextUnderline
:
479 case ColorID::IMESelectedRawTextUnderline
:
480 case ColorID::IMESelectedConvertedTextUnderline
:
481 case ColorID::SpellCheckerUnderline
:
482 return NS_IS_SELECTION_SPECIAL_COLOR(aColor
);
485 * In GetColor(), every color that is not a special color is color
486 * corrected. Use false to make other colors color corrected.
493 bool nsXPLookAndFeel::ColorIsNotCSSAccessible(ColorID aID
) {
497 case ColorID::WindowBackground
:
498 case ColorID::WindowForeground
:
499 case ColorID::WidgetBackground
:
500 case ColorID::WidgetForeground
:
501 case ColorID::WidgetSelectBackground
:
502 case ColorID::WidgetSelectForeground
:
503 case ColorID::Widget3DHighlight
:
504 case ColorID::Widget3DShadow
:
505 case ColorID::TextBackground
:
506 case ColorID::TextForeground
:
507 case ColorID::TextSelectBackground
:
508 case ColorID::TextSelectForeground
:
509 case ColorID::TextSelectBackgroundDisabled
:
510 case ColorID::TextSelectBackgroundAttention
:
511 case ColorID::TextHighlightBackground
:
512 case ColorID::TextHighlightForeground
:
513 case ColorID::IMERawInputBackground
:
514 case ColorID::IMERawInputForeground
:
515 case ColorID::IMERawInputUnderline
:
516 case ColorID::IMESelectedRawTextBackground
:
517 case ColorID::IMESelectedRawTextForeground
:
518 case ColorID::IMESelectedRawTextUnderline
:
519 case ColorID::IMEConvertedTextBackground
:
520 case ColorID::IMEConvertedTextForeground
:
521 case ColorID::IMEConvertedTextUnderline
:
522 case ColorID::IMESelectedConvertedTextBackground
:
523 case ColorID::IMESelectedConvertedTextForeground
:
524 case ColorID::IMESelectedConvertedTextUnderline
:
525 case ColorID::SpellCheckerUnderline
:
535 nscolor
nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID
) {
536 nscolor result
= NS_RGB(0xFF, 0xFF, 0xFF);
538 // The stand-in colors are taken from the Windows 7 Aero theme
539 // except Mac-specific colors which are taken from Mac OS 10.7.
542 case ColorID::Activeborder
:
543 result
= NS_RGB(0xB4, 0xB4, 0xB4);
545 case ColorID::Activecaption
:
546 result
= NS_RGB(0x99, 0xB4, 0xD1);
548 case ColorID::Appworkspace
:
549 result
= NS_RGB(0xAB, 0xAB, 0xAB);
551 case ColorID::Background
:
552 result
= NS_RGB(0x00, 0x00, 0x00);
554 case ColorID::Buttonface
:
555 result
= NS_RGB(0xF0, 0xF0, 0xF0);
557 case ColorID::Buttonhighlight
:
558 result
= NS_RGB(0xFF, 0xFF, 0xFF);
560 case ColorID::Buttonshadow
:
561 result
= NS_RGB(0xA0, 0xA0, 0xA0);
563 case ColorID::Buttontext
:
564 result
= NS_RGB(0x00, 0x00, 0x00);
566 case ColorID::Captiontext
:
567 result
= NS_RGB(0x00, 0x00, 0x00);
569 case ColorID::Graytext
:
570 result
= NS_RGB(0x6D, 0x6D, 0x6D);
572 case ColorID::Highlight
:
573 result
= NS_RGB(0x33, 0x99, 0xFF);
575 case ColorID::Highlighttext
:
576 result
= NS_RGB(0xFF, 0xFF, 0xFF);
578 case ColorID::Inactiveborder
:
579 result
= NS_RGB(0xF4, 0xF7, 0xFC);
581 case ColorID::Inactivecaption
:
582 result
= NS_RGB(0xBF, 0xCD, 0xDB);
584 case ColorID::Inactivecaptiontext
:
585 result
= NS_RGB(0x43, 0x4E, 0x54);
587 case ColorID::Infobackground
:
588 result
= NS_RGB(0xFF, 0xFF, 0xE1);
590 case ColorID::Infotext
:
591 result
= NS_RGB(0x00, 0x00, 0x00);
594 result
= NS_RGB(0xF0, 0xF0, 0xF0);
596 case ColorID::Menutext
:
597 result
= NS_RGB(0x00, 0x00, 0x00);
599 case ColorID::Scrollbar
:
600 result
= NS_RGB(0xC8, 0xC8, 0xC8);
602 case ColorID::Threeddarkshadow
:
603 result
= NS_RGB(0x69, 0x69, 0x69);
605 case ColorID::Threedface
:
606 result
= NS_RGB(0xF0, 0xF0, 0xF0);
608 case ColorID::Threedhighlight
:
609 result
= NS_RGB(0xFF, 0xFF, 0xFF);
611 case ColorID::Threedlightshadow
:
612 result
= NS_RGB(0xE3, 0xE3, 0xE3);
614 case ColorID::Threedshadow
:
615 result
= NS_RGB(0xA0, 0xA0, 0xA0);
617 case ColorID::Window
:
618 result
= NS_RGB(0xFF, 0xFF, 0xFF);
620 case ColorID::Windowframe
:
621 result
= NS_RGB(0x64, 0x64, 0x64);
623 case ColorID::Windowtext
:
624 result
= NS_RGB(0x00, 0x00, 0x00);
626 case ColorID::MozButtondefault
:
627 result
= NS_RGB(0x69, 0x69, 0x69);
630 result
= NS_RGB(0xFF, 0xFF, 0xFF);
632 case ColorID::Fieldtext
:
633 result
= NS_RGB(0x00, 0x00, 0x00);
635 case ColorID::MozDialog
:
636 result
= NS_RGB(0xF0, 0xF0, 0xF0);
638 case ColorID::MozDialogtext
:
639 case ColorID::MozColheadertext
:
640 case ColorID::MozColheaderhovertext
:
641 result
= NS_RGB(0x00, 0x00, 0x00);
643 case ColorID::MozDragtargetzone
:
644 result
= NS_RGB(0xFF, 0xFF, 0xFF);
646 case ColorID::MozCellhighlight
:
647 result
= NS_RGB(0xF0, 0xF0, 0xF0);
649 case ColorID::MozCellhighlighttext
:
650 result
= NS_RGB(0x00, 0x00, 0x00);
652 case ColorID::MozHtmlCellhighlight
:
653 result
= NS_RGB(0x33, 0x99, 0xFF);
655 case ColorID::MozHtmlCellhighlighttext
:
656 result
= NS_RGB(0xFF, 0xFF, 0xFF);
658 case ColorID::MozButtonhoverface
:
659 result
= NS_RGB(0xF0, 0xF0, 0xF0);
661 case ColorID::MozButtonhovertext
:
662 result
= NS_RGB(0x00, 0x00, 0x00);
664 case ColorID::MozMenuhover
:
665 result
= NS_RGB(0x33, 0x99, 0xFF);
667 case ColorID::MozMenuhovertext
:
668 result
= NS_RGB(0x00, 0x00, 0x00);
670 case ColorID::MozMenubartext
:
671 result
= NS_RGB(0x00, 0x00, 0x00);
673 case ColorID::MozMenubarhovertext
:
674 result
= NS_RGB(0x00, 0x00, 0x00);
676 case ColorID::MozOddtreerow
:
677 case ColorID::MozGtkButtonactivetext
:
678 result
= NS_RGB(0xFF, 0xFF, 0xFF);
680 case ColorID::MozMacChromeActive
:
681 result
= NS_RGB(0xB2, 0xB2, 0xB2);
683 case ColorID::MozMacChromeInactive
:
684 result
= NS_RGB(0xE1, 0xE1, 0xE1);
686 case ColorID::MozMacFocusring
:
687 result
= NS_RGB(0x60, 0x9D, 0xD7);
689 case ColorID::MozMacMenuselect
:
690 result
= NS_RGB(0x38, 0x75, 0xD7);
692 case ColorID::MozMacMenushadow
:
693 result
= NS_RGB(0xA3, 0xA3, 0xA3);
695 case ColorID::MozMacMenutextdisable
:
696 result
= NS_RGB(0x88, 0x88, 0x88);
698 case ColorID::MozMacMenutextselect
:
699 result
= NS_RGB(0xFF, 0xFF, 0xFF);
701 case ColorID::MozMacDisabledtoolbartext
:
702 result
= NS_RGB(0x3F, 0x3F, 0x3F);
704 case ColorID::MozMacSecondaryhighlight
:
705 result
= NS_RGB(0xD4, 0xD4, 0xD4);
707 case ColorID::MozMacVibrancyLight
:
708 case ColorID::MozMacVibrantTitlebarLight
:
709 result
= NS_RGB(0xf7, 0xf7, 0xf7);
711 case ColorID::MozMacVibrancyDark
:
712 case ColorID::MozMacVibrantTitlebarDark
:
713 result
= NS_RGB(0x28, 0x28, 0x28);
715 case ColorID::MozMacMenupopup
:
716 result
= NS_RGB(0xe6, 0xe6, 0xe6);
718 case ColorID::MozMacMenuitem
:
719 result
= NS_RGB(0xe6, 0xe6, 0xe6);
721 case ColorID::MozMacActiveMenuitem
:
722 result
= NS_RGB(0x0a, 0x64, 0xdc);
724 case ColorID::MozMacSourceList
:
725 result
= NS_RGB(0xf7, 0xf7, 0xf7);
727 case ColorID::MozMacSourceListSelection
:
728 result
= NS_RGB(0xc8, 0xc8, 0xc8);
730 case ColorID::MozMacActiveSourceListSelection
:
731 result
= NS_RGB(0x0a, 0x64, 0xdc);
733 case ColorID::MozMacTooltip
:
734 result
= NS_RGB(0xf7, 0xf7, 0xf7);
736 case ColorID::MozWinAccentcolor
:
737 // Seems to be the default color (hardcoded because of bug 1065998)
738 result
= NS_RGB(0x9E, 0x9E, 0x9E);
740 case ColorID::MozWinAccentcolortext
:
741 result
= NS_RGB(0x00, 0x00, 0x00);
743 case ColorID::MozWinMediatext
:
744 result
= NS_RGB(0xFF, 0xFF, 0xFF);
746 case ColorID::MozWinCommunicationstext
:
747 result
= NS_RGB(0xFF, 0xFF, 0xFF);
749 case ColorID::MozNativehyperlinktext
:
750 result
= NS_RGB(0x00, 0x66, 0xCC);
752 case ColorID::MozComboboxtext
:
753 result
= NS_RGB(0x00, 0x00, 0x00);
755 case ColorID::MozCombobox
:
756 result
= NS_RGB(0xFF, 0xFF, 0xFF);
766 // All these routines will return NS_OK if they have a value,
767 // in which case the nsLookAndFeel should use that value;
768 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
769 // platform-specific nsLookAndFeel should use its own values instead.
771 nsresult
nsXPLookAndFeel::GetColorImpl(ColorID aID
,
772 bool aUseStandinsForNativeColors
,
774 if (!sInitialized
) Init();
776 // define DEBUG_SYSTEM_COLOR_USE if you want to debug system color
777 // use in a skin that uses them. When set, it will make all system
778 // color pairs that are appropriate for foreground/background
779 // pairing the same. This means if the skin is using system colors
780 // correctly you will not be able to see *any* text.
781 #undef DEBUG_SYSTEM_COLOR_USE
783 #ifdef DEBUG_SYSTEM_COLOR_USE
787 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
788 case ColorID::Activecaption
:
789 // active window caption background
790 case ColorID::Captiontext
:
791 // text in active window caption
792 aResult
= NS_RGB(0xff, 0x00, 0x00);
795 case ColorID::Highlight
:
796 // background of selected item
797 case ColorID::Highlighttext
:
798 // text of selected item
799 aResult
= NS_RGB(0xff, 0xff, 0x00);
802 case ColorID::Inactivecaption
:
803 // inactive window caption
804 case ColorID::Inactivecaptiontext
:
805 // text in inactive window caption
806 aResult
= NS_RGB(0x66, 0x66, 0x00);
809 case ColorID::Infobackground
:
810 // tooltip background color
811 case ColorID::Infotext
:
812 // tooltip text color
813 aResult
= NS_RGB(0x00, 0xff, 0x00);
818 case ColorID::Menutext
:
820 aResult
= NS_RGB(0x00, 0xff, 0xff);
823 case ColorID::Threedface
:
824 case ColorID::Buttonface
:
826 case ColorID::Buttontext
:
827 // text on push buttons
828 aResult
= NS_RGB(0x00, 0x66, 0x66);
831 case ColorID::Window
:
832 case ColorID::Windowtext
:
833 aResult
= NS_RGB(0x00, 0x00, 0xff);
836 // from the CSS3 working draft (not yet finalized)
837 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
840 case ColorID::Fieldtext
:
841 aResult
= NS_RGB(0xff, 0x00, 0xff);
844 case ColorID::MozDialog
:
845 case ColorID::MozDialogtext
:
846 aResult
= NS_RGB(0x66, 0x00, 0x66);
850 rv
= NS_ERROR_NOT_AVAILABLE
;
852 if (NS_SUCCEEDED(rv
)) return rv
;
854 #endif // DEBUG_SYSTEM_COLOR_USE
856 if (aUseStandinsForNativeColors
&&
857 (ColorIsNotCSSAccessible(aID
) ||
858 !nsContentUtils::UseStandinsForNativeColors())) {
859 aUseStandinsForNativeColors
= false;
862 if (!aUseStandinsForNativeColors
&& IS_COLOR_CACHED(aID
)) {
863 aResult
= sCachedColors
[uint32_t(aID
)];
867 // There are no system color settings for these, so set them manually
869 if (aID
== ColorID::TextSelectBackgroundDisabled
) {
870 // This is used to gray out the selection when it's not focused
871 // Used with nsISelectionController::SELECTION_DISABLED
872 aResult
= NS_RGB(0xb0, 0xb0, 0xb0);
877 if (aID
== ColorID::TextSelectBackgroundAttention
) {
878 if (StaticPrefs::findbar_modalHighlight() && !mozilla::FissionAutostart()) {
879 aResult
= NS_RGBA(0, 0, 0, 0);
883 // This makes the selection stand out when typeaheadfind is on
884 // Used with nsISelectionController::SELECTION_ATTENTION
885 aResult
= NS_RGB(0x38, 0xd8, 0x78);
889 if (aID
== ColorID::TextHighlightBackground
) {
890 // This makes the matched text stand out when findbar highlighting is on
891 // Used with nsISelectionController::SELECTION_FIND
892 aResult
= NS_RGB(0xef, 0x0f, 0xff);
896 if (aID
== ColorID::TextHighlightForeground
) {
897 // The foreground color for the matched text in findbar highlighting
898 // Used with nsISelectionController::SELECTION_FIND
899 aResult
= NS_RGB(0xff, 0xff, 0xff);
903 if (StaticPrefs::ui_use_native_colors() && aUseStandinsForNativeColors
) {
904 aResult
= GetStandinForNativeColor(aID
);
908 if (StaticPrefs::ui_use_native_colors() &&
909 NS_SUCCEEDED(NativeGetColor(aID
, aResult
))) {
910 if (!mozilla::ServoStyleSet::IsInServoTraversal()) {
911 MOZ_ASSERT(NS_IsMainThread());
912 if ((gfxPlatform::GetCMSMode() == eCMSMode_All
) &&
913 !IsSpecialColor(aID
, aResult
)) {
914 qcms_transform
* transform
= gfxPlatform::GetCMSInverseRGBTransform();
917 color
[0] = NS_GET_R(aResult
);
918 color
[1] = NS_GET_G(aResult
);
919 color
[2] = NS_GET_B(aResult
);
920 color
[3] = NS_GET_A(aResult
);
921 qcms_transform_data(transform
, color
, color
, 1);
922 aResult
= NS_RGBA(color
[0], color
[1], color
[2], color
[3]);
926 CACHE_COLOR(aID
, aResult
);
931 return NS_ERROR_NOT_AVAILABLE
;
934 nsresult
nsXPLookAndFeel::GetIntImpl(IntID aID
, int32_t& aResult
) {
935 if (!sInitialized
) Init();
937 // Set the default values for these prefs. but allow different platforms
938 // to override them in their nsLookAndFeel if desired.
940 case IntID::ScrollButtonLeftMouseButtonAction
:
943 case IntID::ScrollButtonMiddleMouseButtonAction
:
946 case IntID::ScrollButtonRightMouseButtonAction
:
951 * The metrics above are hardcoded platform defaults. All the other
952 * metrics are stored in sIntPrefs and can be changed at runtime.
957 for (unsigned int i
= 0; i
< ArrayLength(sIntPrefs
); ++i
) {
958 if (sIntPrefs
[i
].isSet
&& (sIntPrefs
[i
].id
== aID
)) {
959 aResult
= sIntPrefs
[i
].intVar
;
964 return NS_ERROR_NOT_AVAILABLE
;
967 nsresult
nsXPLookAndFeel::GetFloatImpl(FloatID aID
, float& aResult
) {
968 if (!sInitialized
) Init();
970 for (unsigned int i
= 0; i
< ArrayLength(sFloatPrefs
); ++i
) {
971 if (sFloatPrefs
[i
].isSet
&& sFloatPrefs
[i
].id
== aID
) {
972 aResult
= sFloatPrefs
[i
].floatVar
;
977 return NS_ERROR_NOT_AVAILABLE
;
980 void nsXPLookAndFeel::RefreshImpl() {
981 // Wipe out our color cache.
983 for (i
= 0; i
< uint32_t(ColorID::End
); i
++) {
984 sCachedColors
[i
] = 0;
986 for (i
= 0; i
< COLOR_CACHE_SIZE
; i
++) {
987 sCachedColorBits
[i
] = 0;
990 // Reinit color cache from prefs.
991 for (i
= 0; i
< uint32_t(ColorID::End
); ++i
) {
992 InitColorFromPref(i
);
996 nsTArray
<LookAndFeelInt
> nsXPLookAndFeel::GetIntCacheImpl() {
997 return nsTArray
<LookAndFeelInt
>();
1000 static bool sRecordedLookAndFeelTelemetry
= false;
1002 void nsXPLookAndFeel::RecordTelemetry() {
1003 if (sRecordedLookAndFeelTelemetry
) {
1007 sRecordedLookAndFeelTelemetry
= true;
1010 Telemetry::ScalarSet(
1011 Telemetry::ScalarID::WIDGET_DARK_MODE
,
1012 NS_SUCCEEDED(GetIntImpl(IntID::SystemUsesDarkTheme
, i
)) && i
!= 0);
1018 void LookAndFeel::NotifyChangedAllWindows() {
1019 if (nsCOMPtr
<nsIObserverService
> obs
= services::GetObserverService()) {
1020 obs
->NotifyObservers(nullptr, "look-and-feel-changed", nullptr);
1025 nsresult
LookAndFeel::GetColor(ColorID aID
, nscolor
* aResult
) {
1026 return nsLookAndFeel::GetInstance()->GetColorImpl(aID
, false, *aResult
);
1029 nsresult
LookAndFeel::GetColor(ColorID aID
, bool aUseStandinsForNativeColors
,
1031 return nsLookAndFeel::GetInstance()->GetColorImpl(
1032 aID
, aUseStandinsForNativeColors
, *aResult
);
1036 nsresult
LookAndFeel::GetInt(IntID aID
, int32_t* aResult
) {
1037 return nsLookAndFeel::GetInstance()->GetIntImpl(aID
, *aResult
);
1041 nsresult
LookAndFeel::GetFloat(FloatID aID
, float* aResult
) {
1042 return nsLookAndFeel::GetInstance()->GetFloatImpl(aID
, *aResult
);
1046 bool LookAndFeel::GetFont(FontID aID
, nsString
& aName
, gfxFontStyle
& aStyle
) {
1047 return nsLookAndFeel::GetInstance()->GetFontImpl(aID
, aName
, aStyle
);
1051 char16_t
LookAndFeel::GetPasswordCharacter() {
1052 return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
1056 bool LookAndFeel::GetEchoPassword() {
1057 if (StaticPrefs::editor_password_mask_delay() >= 0) {
1058 return StaticPrefs::editor_password_mask_delay() > 0;
1060 return nsLookAndFeel::GetInstance()->GetEchoPasswordImpl();
1064 uint32_t LookAndFeel::GetPasswordMaskDelay() {
1065 int32_t delay
= StaticPrefs::editor_password_mask_delay();
1067 return nsLookAndFeel::GetInstance()->GetPasswordMaskDelayImpl();
1073 void LookAndFeel::Refresh() { nsLookAndFeel::GetInstance()->RefreshImpl(); }
1076 void LookAndFeel::NativeInit() { nsLookAndFeel::GetInstance()->NativeInit(); }
1079 nsTArray
<LookAndFeelInt
> LookAndFeel::GetIntCache() {
1080 return nsLookAndFeel::GetInstance()->GetIntCacheImpl();
1084 void LookAndFeel::SetIntCache(
1085 const nsTArray
<LookAndFeelInt
>& aLookAndFeelIntCache
) {
1086 return nsLookAndFeel::GetInstance()->SetIntCacheImpl(aLookAndFeelIntCache
);
1089 } // namespace mozilla