Bug 1652470 [wpt PR 24579] - Update mozrunner to 8.0.0, a=testonly
[gecko.git] / widget / nsXPLookAndFeel.cpp
blobe3ca45f6ea5d57d5d42d65723950241c0cb7a91c
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"
8 #include "nscore.h"
10 #include "nsXPLookAndFeel.h"
11 #include "nsLookAndFeel.h"
12 #include "HeadlessLookAndFeel.h"
13 #include "nsContentUtils.h"
14 #include "nsCRT.h"
15 #include "nsFont.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"
31 #include "qcms.h"
33 #ifdef DEBUG
34 # include "nsSize.h"
35 #endif
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,
50 false, 0},
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,
55 false, 0},
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,
65 0},
66 {"ui.IMESelectedRawTextUnderlineStyle",
67 IntID::IMESelectedRawTextUnderlineStyle, false, 0},
68 {"ui.IMEConvertedTextUnderlineStyle", IntID::IMEConvertedTextUnderlineStyle,
69 false, 0},
70 {"ui.IMESelectedConvertedTextUnderlineStyle",
71 IntID::IMESelectedConvertedTextUnderline, false, 0},
72 {"ui.SpellCheckerUnderlineStyle", IntID::SpellCheckerUnderlineStyle, false,
73 0},
74 {"ui.scrollbarButtonAutoRepeatBehavior",
75 IntID::ScrollbarButtonAutoRepeatBehavior, false, 0},
76 {"ui.tooltipDelay", IntID::TooltipDelay, false, 0},
77 {"ui.contextMenuOffsetVertical", IntID::ContextMenuOffsetVertical, false,
78 0},
79 {"ui.contextMenuOffsetHorizontal", IntID::ContextMenuOffsetHorizontal,
80 false, 0},
81 {"ui.GtkCSDAvailable", IntID::GTKCSDAvailable, false, 0},
82 {"ui.GtkCSDHideTitlebarByDefault", IntID::GTKCSDHideTitlebarByDefault,
83 false, 0},
84 {"ui.GtkCSDTransparentBackground", IntID::GTKCSDTransparentBackground,
85 false, 0},
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,
99 0},
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",
120 "ui.widget3DShadow",
121 "ui.textBackground",
122 "ui.textForeground",
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",
143 "ui.activeborder",
144 "ui.activecaption",
145 "ui.appworkspace",
146 "ui.background",
147 "ui.buttonface",
148 "ui.buttonhighlight",
149 "ui.buttonshadow",
150 "ui.buttontext",
151 "ui.captiontext",
152 "ui.-moz-field",
153 "ui.-moz-fieldtext",
154 "ui.graytext",
155 "ui.highlight",
156 "ui.highlighttext",
157 "ui.inactiveborder",
158 "ui.inactivecaption",
159 "ui.inactivecaptiontext",
160 "ui.infobackground",
161 "ui.infotext",
162 "ui.menu",
163 "ui.menutext",
164 "ui.scrollbar",
165 "ui.threeddarkshadow",
166 "ui.threedface",
167 "ui.threedhighlight",
168 "ui.threedlightshadow",
169 "ui.threedshadow",
170 "ui.window",
171 "ui.windowframe",
172 "ui.windowtext",
173 "ui.-moz-buttondefault",
174 "ui.-moz-default-color",
175 "ui.-moz-default-background-color",
176 "ui.-moz-dialog",
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",
185 "ui.-moz_menuhover",
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",
223 "ui.-moz-combobox",
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;
236 // static
237 nsXPLookAndFeel* nsXPLookAndFeel::GetInstance() {
238 if (sInstance) {
239 return sInstance;
242 NS_ENSURE_TRUE(!sShutdown, nullptr);
244 if (gfxPlatform::IsHeadless()) {
245 sInstance = new widget::HeadlessLookAndFeel();
246 } else {
247 sInstance = new nsLookAndFeel();
249 return sInstance;
252 // static
253 void nsXPLookAndFeel::Shutdown() {
254 if (sShutdown) {
255 return;
257 sShutdown = true;
258 delete sInstance;
259 sInstance = nullptr;
262 // static
263 void nsXPLookAndFeel::IntPrefChanged(nsLookAndFeelIntPref* data) {
264 if (!data) {
265 return;
268 int32_t intpref;
269 nsresult rv = Preferences::GetInt(data->name, &intpref);
270 if (NS_FAILED(rv)) {
271 data->isSet = false;
273 #ifdef DEBUG_akkana
274 printf("====== Cleared int pref %s\n", data->name);
275 #endif
276 } else {
277 data->intVar = intpref;
278 data->isSet = true;
280 #ifdef DEBUG_akkana
281 printf("====== Changed int pref %s to %d\n", data->name, data->intVar);
282 #endif
285 NotifyChangedAllWindows();
288 // static
289 void nsXPLookAndFeel::FloatPrefChanged(nsLookAndFeelFloatPref* data) {
290 if (!data) {
291 return;
294 int32_t intpref;
295 nsresult rv = Preferences::GetInt(data->name, &intpref);
296 if (NS_FAILED(rv)) {
297 data->isSet = false;
299 #ifdef DEBUG_akkana
300 printf("====== Cleared float pref %s\n", data->name);
301 #endif
302 } else {
303 data->floatVar = (float)intpref / 100.0f;
304 data->isSet = true;
306 #ifdef DEBUG_akkana
307 printf("====== Changed float pref %s to %f\n", data->name);
308 #endif
311 NotifyChangedAllWindows();
314 // static
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()) {
320 nscolor thecolor;
321 if (colorStr[0] == char16_t('#')) {
322 if (NS_HexToRGBA(nsDependentString(colorStr, 1), nsHexColorType::NoAlpha,
323 &thecolor)) {
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);
330 #ifdef DEBUG_akkana
331 printf("====== Changed color pref %s to 0x%lx\n", prefName, thecolor);
332 #endif
334 } else {
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);
340 #ifdef DEBUG_akkana
341 printf("====== Cleared color pref %s\n", prefName);
342 #endif
345 NotifyChangedAllWindows();
348 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelIntPref* aPref) {
349 int32_t intpref;
350 nsresult rv = Preferences::GetInt(aPref->name, &intpref);
351 if (NS_SUCCEEDED(rv)) {
352 aPref->isSet = true;
353 aPref->intVar = intpref;
357 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelFloatPref* aPref) {
358 int32_t intpref;
359 nsresult rv = Preferences::GetInt(aPref->name, &intpref);
360 if (NS_SUCCEEDED(rv)) {
361 aPref->isSet = true;
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()) {
373 return;
375 nscolor thecolor;
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);
387 // static
388 void nsXPLookAndFeel::OnPrefChanged(const char* aPref, void* aClosure) {
389 // looping in the same order as in ::Init
391 nsDependentCString prefName(aPref);
392 unsigned int i;
393 for (i = 0; i < ArrayLength(sIntPrefs); ++i) {
394 if (prefName.Equals(sIntPrefs[i].name)) {
395 IntPrefChanged(&sIntPrefs[i]);
396 return;
400 for (i = 0; i < ArrayLength(sFloatPrefs); ++i) {
401 if (prefName.Equals(sFloatPrefs[i].name)) {
402 FloatPrefChanged(&sFloatPrefs[i]);
403 return;
407 for (i = 0; i < ArrayLength(sColorPrefs); ++i) {
408 if (prefName.Equals(sColorPrefs[i])) {
409 ColorPrefChanged(i, sColorPrefs[i]);
410 return;
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.
426 sInitialized = true;
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");
436 unsigned int i;
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
454 // now.
455 cc->LookAndFeelCache().Clear();
459 nsXPLookAndFeel::~nsXPLookAndFeel() {
460 NS_ASSERTION(sInstance == this,
461 "This destroying instance isn't the singleton instance");
462 sInstance = nullptr;
465 bool nsXPLookAndFeel::IsSpecialColor(ColorID aID, nscolor& aColor) {
466 switch (aID) {
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);
483 default:
485 * In GetColor(), every color that is not a special color is color
486 * corrected. Use false to make other colors color corrected.
488 return false;
490 return false;
493 bool nsXPLookAndFeel::ColorIsNotCSSAccessible(ColorID aID) {
494 bool result = false;
496 switch (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:
526 result = true;
527 break;
528 default:
529 break;
532 return result;
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.
540 switch (aID) {
541 // CSS 2 colors:
542 case ColorID::Activeborder:
543 result = NS_RGB(0xB4, 0xB4, 0xB4);
544 break;
545 case ColorID::Activecaption:
546 result = NS_RGB(0x99, 0xB4, 0xD1);
547 break;
548 case ColorID::Appworkspace:
549 result = NS_RGB(0xAB, 0xAB, 0xAB);
550 break;
551 case ColorID::Background:
552 result = NS_RGB(0x00, 0x00, 0x00);
553 break;
554 case ColorID::Buttonface:
555 result = NS_RGB(0xF0, 0xF0, 0xF0);
556 break;
557 case ColorID::Buttonhighlight:
558 result = NS_RGB(0xFF, 0xFF, 0xFF);
559 break;
560 case ColorID::Buttonshadow:
561 result = NS_RGB(0xA0, 0xA0, 0xA0);
562 break;
563 case ColorID::Buttontext:
564 result = NS_RGB(0x00, 0x00, 0x00);
565 break;
566 case ColorID::Captiontext:
567 result = NS_RGB(0x00, 0x00, 0x00);
568 break;
569 case ColorID::Graytext:
570 result = NS_RGB(0x6D, 0x6D, 0x6D);
571 break;
572 case ColorID::Highlight:
573 result = NS_RGB(0x33, 0x99, 0xFF);
574 break;
575 case ColorID::Highlighttext:
576 result = NS_RGB(0xFF, 0xFF, 0xFF);
577 break;
578 case ColorID::Inactiveborder:
579 result = NS_RGB(0xF4, 0xF7, 0xFC);
580 break;
581 case ColorID::Inactivecaption:
582 result = NS_RGB(0xBF, 0xCD, 0xDB);
583 break;
584 case ColorID::Inactivecaptiontext:
585 result = NS_RGB(0x43, 0x4E, 0x54);
586 break;
587 case ColorID::Infobackground:
588 result = NS_RGB(0xFF, 0xFF, 0xE1);
589 break;
590 case ColorID::Infotext:
591 result = NS_RGB(0x00, 0x00, 0x00);
592 break;
593 case ColorID::Menu:
594 result = NS_RGB(0xF0, 0xF0, 0xF0);
595 break;
596 case ColorID::Menutext:
597 result = NS_RGB(0x00, 0x00, 0x00);
598 break;
599 case ColorID::Scrollbar:
600 result = NS_RGB(0xC8, 0xC8, 0xC8);
601 break;
602 case ColorID::Threeddarkshadow:
603 result = NS_RGB(0x69, 0x69, 0x69);
604 break;
605 case ColorID::Threedface:
606 result = NS_RGB(0xF0, 0xF0, 0xF0);
607 break;
608 case ColorID::Threedhighlight:
609 result = NS_RGB(0xFF, 0xFF, 0xFF);
610 break;
611 case ColorID::Threedlightshadow:
612 result = NS_RGB(0xE3, 0xE3, 0xE3);
613 break;
614 case ColorID::Threedshadow:
615 result = NS_RGB(0xA0, 0xA0, 0xA0);
616 break;
617 case ColorID::Window:
618 result = NS_RGB(0xFF, 0xFF, 0xFF);
619 break;
620 case ColorID::Windowframe:
621 result = NS_RGB(0x64, 0x64, 0x64);
622 break;
623 case ColorID::Windowtext:
624 result = NS_RGB(0x00, 0x00, 0x00);
625 break;
626 case ColorID::MozButtondefault:
627 result = NS_RGB(0x69, 0x69, 0x69);
628 break;
629 case ColorID::Field:
630 result = NS_RGB(0xFF, 0xFF, 0xFF);
631 break;
632 case ColorID::Fieldtext:
633 result = NS_RGB(0x00, 0x00, 0x00);
634 break;
635 case ColorID::MozDialog:
636 result = NS_RGB(0xF0, 0xF0, 0xF0);
637 break;
638 case ColorID::MozDialogtext:
639 case ColorID::MozColheadertext:
640 case ColorID::MozColheaderhovertext:
641 result = NS_RGB(0x00, 0x00, 0x00);
642 break;
643 case ColorID::MozDragtargetzone:
644 result = NS_RGB(0xFF, 0xFF, 0xFF);
645 break;
646 case ColorID::MozCellhighlight:
647 result = NS_RGB(0xF0, 0xF0, 0xF0);
648 break;
649 case ColorID::MozCellhighlighttext:
650 result = NS_RGB(0x00, 0x00, 0x00);
651 break;
652 case ColorID::MozHtmlCellhighlight:
653 result = NS_RGB(0x33, 0x99, 0xFF);
654 break;
655 case ColorID::MozHtmlCellhighlighttext:
656 result = NS_RGB(0xFF, 0xFF, 0xFF);
657 break;
658 case ColorID::MozButtonhoverface:
659 result = NS_RGB(0xF0, 0xF0, 0xF0);
660 break;
661 case ColorID::MozButtonhovertext:
662 result = NS_RGB(0x00, 0x00, 0x00);
663 break;
664 case ColorID::MozMenuhover:
665 result = NS_RGB(0x33, 0x99, 0xFF);
666 break;
667 case ColorID::MozMenuhovertext:
668 result = NS_RGB(0x00, 0x00, 0x00);
669 break;
670 case ColorID::MozMenubartext:
671 result = NS_RGB(0x00, 0x00, 0x00);
672 break;
673 case ColorID::MozMenubarhovertext:
674 result = NS_RGB(0x00, 0x00, 0x00);
675 break;
676 case ColorID::MozOddtreerow:
677 case ColorID::MozGtkButtonactivetext:
678 result = NS_RGB(0xFF, 0xFF, 0xFF);
679 break;
680 case ColorID::MozMacChromeActive:
681 result = NS_RGB(0xB2, 0xB2, 0xB2);
682 break;
683 case ColorID::MozMacChromeInactive:
684 result = NS_RGB(0xE1, 0xE1, 0xE1);
685 break;
686 case ColorID::MozMacFocusring:
687 result = NS_RGB(0x60, 0x9D, 0xD7);
688 break;
689 case ColorID::MozMacMenuselect:
690 result = NS_RGB(0x38, 0x75, 0xD7);
691 break;
692 case ColorID::MozMacMenushadow:
693 result = NS_RGB(0xA3, 0xA3, 0xA3);
694 break;
695 case ColorID::MozMacMenutextdisable:
696 result = NS_RGB(0x88, 0x88, 0x88);
697 break;
698 case ColorID::MozMacMenutextselect:
699 result = NS_RGB(0xFF, 0xFF, 0xFF);
700 break;
701 case ColorID::MozMacDisabledtoolbartext:
702 result = NS_RGB(0x3F, 0x3F, 0x3F);
703 break;
704 case ColorID::MozMacSecondaryhighlight:
705 result = NS_RGB(0xD4, 0xD4, 0xD4);
706 break;
707 case ColorID::MozMacVibrancyLight:
708 case ColorID::MozMacVibrantTitlebarLight:
709 result = NS_RGB(0xf7, 0xf7, 0xf7);
710 break;
711 case ColorID::MozMacVibrancyDark:
712 case ColorID::MozMacVibrantTitlebarDark:
713 result = NS_RGB(0x28, 0x28, 0x28);
714 break;
715 case ColorID::MozMacMenupopup:
716 result = NS_RGB(0xe6, 0xe6, 0xe6);
717 break;
718 case ColorID::MozMacMenuitem:
719 result = NS_RGB(0xe6, 0xe6, 0xe6);
720 break;
721 case ColorID::MozMacActiveMenuitem:
722 result = NS_RGB(0x0a, 0x64, 0xdc);
723 break;
724 case ColorID::MozMacSourceList:
725 result = NS_RGB(0xf7, 0xf7, 0xf7);
726 break;
727 case ColorID::MozMacSourceListSelection:
728 result = NS_RGB(0xc8, 0xc8, 0xc8);
729 break;
730 case ColorID::MozMacActiveSourceListSelection:
731 result = NS_RGB(0x0a, 0x64, 0xdc);
732 break;
733 case ColorID::MozMacTooltip:
734 result = NS_RGB(0xf7, 0xf7, 0xf7);
735 break;
736 case ColorID::MozWinAccentcolor:
737 // Seems to be the default color (hardcoded because of bug 1065998)
738 result = NS_RGB(0x9E, 0x9E, 0x9E);
739 break;
740 case ColorID::MozWinAccentcolortext:
741 result = NS_RGB(0x00, 0x00, 0x00);
742 break;
743 case ColorID::MozWinMediatext:
744 result = NS_RGB(0xFF, 0xFF, 0xFF);
745 break;
746 case ColorID::MozWinCommunicationstext:
747 result = NS_RGB(0xFF, 0xFF, 0xFF);
748 break;
749 case ColorID::MozNativehyperlinktext:
750 result = NS_RGB(0x00, 0x66, 0xCC);
751 break;
752 case ColorID::MozComboboxtext:
753 result = NS_RGB(0x00, 0x00, 0x00);
754 break;
755 case ColorID::MozCombobox:
756 result = NS_RGB(0xFF, 0xFF, 0xFF);
757 break;
758 default:
759 break;
762 return result;
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,
773 nscolor& aResult) {
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
785 nsresult rv = NS_OK;
786 switch (aID) {
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);
793 break;
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);
800 break;
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);
807 break;
809 case ColorID::Infobackground:
810 // tooltip background color
811 case ColorID::Infotext:
812 // tooltip text color
813 aResult = NS_RGB(0x00, 0xff, 0x00);
814 break;
816 case ColorID::Menu:
817 // menu background
818 case ColorID::Menutext:
819 // menu text
820 aResult = NS_RGB(0x00, 0xff, 0xff);
821 break;
823 case ColorID::Threedface:
824 case ColorID::Buttonface:
825 // 3-D face color
826 case ColorID::Buttontext:
827 // text on push buttons
828 aResult = NS_RGB(0x00, 0x66, 0x66);
829 break;
831 case ColorID::Window:
832 case ColorID::Windowtext:
833 aResult = NS_RGB(0x00, 0x00, 0xff);
834 break;
836 // from the CSS3 working draft (not yet finalized)
837 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
839 case ColorID::Field:
840 case ColorID::Fieldtext:
841 aResult = NS_RGB(0xff, 0x00, 0xff);
842 break;
844 case ColorID::MozDialog:
845 case ColorID::MozDialogtext:
846 aResult = NS_RGB(0x66, 0x00, 0x66);
847 break;
849 default:
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)];
864 return NS_OK;
867 // There are no system color settings for these, so set them manually
868 #ifndef XP_MACOSX
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);
873 return NS_OK;
875 #endif
877 if (aID == ColorID::TextSelectBackgroundAttention) {
878 if (StaticPrefs::findbar_modalHighlight() && !mozilla::FissionAutostart()) {
879 aResult = NS_RGBA(0, 0, 0, 0);
880 return NS_OK;
883 // This makes the selection stand out when typeaheadfind is on
884 // Used with nsISelectionController::SELECTION_ATTENTION
885 aResult = NS_RGB(0x38, 0xd8, 0x78);
886 return NS_OK;
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);
893 return NS_OK;
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);
900 return NS_OK;
903 if (StaticPrefs::ui_use_native_colors() && aUseStandinsForNativeColors) {
904 aResult = GetStandinForNativeColor(aID);
905 return NS_OK;
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();
915 if (transform) {
916 uint8_t color[4];
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);
928 return NS_OK;
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.
939 switch (aID) {
940 case IntID::ScrollButtonLeftMouseButtonAction:
941 aResult = 0;
942 return NS_OK;
943 case IntID::ScrollButtonMiddleMouseButtonAction:
944 aResult = 3;
945 return NS_OK;
946 case IntID::ScrollButtonRightMouseButtonAction:
947 aResult = 3;
948 return NS_OK;
949 default:
951 * The metrics above are hardcoded platform defaults. All the other
952 * metrics are stored in sIntPrefs and can be changed at runtime.
954 break;
957 for (unsigned int i = 0; i < ArrayLength(sIntPrefs); ++i) {
958 if (sIntPrefs[i].isSet && (sIntPrefs[i].id == aID)) {
959 aResult = sIntPrefs[i].intVar;
960 return NS_OK;
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;
973 return NS_OK;
977 return NS_ERROR_NOT_AVAILABLE;
980 void nsXPLookAndFeel::RefreshImpl() {
981 // Wipe out our color cache.
982 uint32_t i;
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) {
1004 return;
1007 sRecordedLookAndFeelTelemetry = true;
1009 int32_t i;
1010 Telemetry::ScalarSet(
1011 Telemetry::ScalarID::WIDGET_DARK_MODE,
1012 NS_SUCCEEDED(GetIntImpl(IntID::SystemUsesDarkTheme, i)) && i != 0);
1015 namespace mozilla {
1017 // static
1018 void LookAndFeel::NotifyChangedAllWindows() {
1019 if (nsCOMPtr<nsIObserverService> obs = services::GetObserverService()) {
1020 obs->NotifyObservers(nullptr, "look-and-feel-changed", nullptr);
1024 // static
1025 nsresult LookAndFeel::GetColor(ColorID aID, nscolor* aResult) {
1026 return nsLookAndFeel::GetInstance()->GetColorImpl(aID, false, *aResult);
1029 nsresult LookAndFeel::GetColor(ColorID aID, bool aUseStandinsForNativeColors,
1030 nscolor* aResult) {
1031 return nsLookAndFeel::GetInstance()->GetColorImpl(
1032 aID, aUseStandinsForNativeColors, *aResult);
1035 // static
1036 nsresult LookAndFeel::GetInt(IntID aID, int32_t* aResult) {
1037 return nsLookAndFeel::GetInstance()->GetIntImpl(aID, *aResult);
1040 // static
1041 nsresult LookAndFeel::GetFloat(FloatID aID, float* aResult) {
1042 return nsLookAndFeel::GetInstance()->GetFloatImpl(aID, *aResult);
1045 // static
1046 bool LookAndFeel::GetFont(FontID aID, nsString& aName, gfxFontStyle& aStyle) {
1047 return nsLookAndFeel::GetInstance()->GetFontImpl(aID, aName, aStyle);
1050 // static
1051 char16_t LookAndFeel::GetPasswordCharacter() {
1052 return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
1055 // static
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();
1063 // static
1064 uint32_t LookAndFeel::GetPasswordMaskDelay() {
1065 int32_t delay = StaticPrefs::editor_password_mask_delay();
1066 if (delay < 0) {
1067 return nsLookAndFeel::GetInstance()->GetPasswordMaskDelayImpl();
1069 return delay;
1072 // static
1073 void LookAndFeel::Refresh() { nsLookAndFeel::GetInstance()->RefreshImpl(); }
1075 // static
1076 void LookAndFeel::NativeInit() { nsLookAndFeel::GetInstance()->NativeInit(); }
1078 // static
1079 nsTArray<LookAndFeelInt> LookAndFeel::GetIntCache() {
1080 return nsLookAndFeel::GetInstance()->GetIntCacheImpl();
1083 // static
1084 void LookAndFeel::SetIntCache(
1085 const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache) {
1086 return nsLookAndFeel::GetInstance()->SetIntCacheImpl(aLookAndFeelIntCache);
1089 } // namespace mozilla