Bug 1468402 - Part 3: Add test for subgrids in the grid list. r=pbro
[gecko.git] / widget / nsXPLookAndFeel.cpp
blobe99aac5bdec93fa954cb4f5e089192184b478ac7
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 "nsCRT.h"
14 #include "nsFont.h"
15 #include "mozilla/dom/ContentChild.h"
16 #include "mozilla/Preferences.h"
17 #include "mozilla/ServoStyleSet.h"
18 #include "mozilla/gfx/2D.h"
19 #include "mozilla/widget/WidgetMessageUtils.h"
21 #include "gfxPlatform.h"
22 #include "gfxPrefs.h"
23 #include "qcms.h"
25 #ifdef DEBUG
26 # include "nsSize.h"
27 #endif
29 using namespace mozilla;
31 nsLookAndFeelIntPref nsXPLookAndFeel::sIntPrefs[] = {
32 {"ui.caretBlinkTime", eIntID_CaretBlinkTime, false, 0},
33 {"ui.caretWidth", eIntID_CaretWidth, false, 0},
34 {"ui.caretVisibleWithSelection", eIntID_ShowCaretDuringSelection, false, 0},
35 {"ui.submenuDelay", eIntID_SubmenuDelay, false, 0},
36 {"ui.dragThresholdX", eIntID_DragThresholdX, false, 0},
37 {"ui.dragThresholdY", eIntID_DragThresholdY, false, 0},
38 {"ui.useAccessibilityTheme", eIntID_UseAccessibilityTheme, false, 0},
39 {"ui.menusCanOverlapOSBar", eIntID_MenusCanOverlapOSBar, false, 0},
40 {"ui.useOverlayScrollbars", eIntID_UseOverlayScrollbars, false, 0},
41 {"ui.scrollbarDisplayOnMouseMove", eIntID_ScrollbarDisplayOnMouseMove,
42 false, 0},
43 {"ui.scrollbarFadeBeginDelay", eIntID_ScrollbarFadeBeginDelay, false, 0},
44 {"ui.scrollbarFadeDuration", eIntID_ScrollbarFadeDuration, false, 0},
45 {"ui.showHideScrollbars", eIntID_ShowHideScrollbars, false, 0},
46 {"ui.skipNavigatingDisabledMenuItem", eIntID_SkipNavigatingDisabledMenuItem,
47 false, 0},
48 {"ui.treeOpenDelay", eIntID_TreeOpenDelay, false, 0},
49 {"ui.treeCloseDelay", eIntID_TreeCloseDelay, false, 0},
50 {"ui.treeLazyScrollDelay", eIntID_TreeLazyScrollDelay, false, 0},
51 {"ui.treeScrollDelay", eIntID_TreeScrollDelay, false, 0},
52 {"ui.treeScrollLinesMax", eIntID_TreeScrollLinesMax, false, 0},
53 {"accessibility.tabfocus", eIntID_TabFocusModel, false, 0},
54 {"ui.alertNotificationOrigin", eIntID_AlertNotificationOrigin, false, 0},
55 {"ui.scrollToClick", eIntID_ScrollToClick, false, 0},
56 {"ui.IMERawInputUnderlineStyle", eIntID_IMERawInputUnderlineStyle, false,
57 0},
58 {"ui.IMESelectedRawTextUnderlineStyle",
59 eIntID_IMESelectedRawTextUnderlineStyle, false, 0},
60 {"ui.IMEConvertedTextUnderlineStyle", eIntID_IMEConvertedTextUnderlineStyle,
61 false, 0},
62 {"ui.IMESelectedConvertedTextUnderlineStyle",
63 eIntID_IMESelectedConvertedTextUnderline, false, 0},
64 {"ui.SpellCheckerUnderlineStyle", eIntID_SpellCheckerUnderlineStyle, false,
65 0},
66 {"ui.scrollbarButtonAutoRepeatBehavior",
67 eIntID_ScrollbarButtonAutoRepeatBehavior, false, 0},
68 {"ui.tooltipDelay", eIntID_TooltipDelay, false, 0},
69 {"ui.contextMenuOffsetVertical", eIntID_ContextMenuOffsetVertical, false,
70 0},
71 {"ui.contextMenuOffsetHorizontal", eIntID_ContextMenuOffsetHorizontal,
72 false, 0},
73 {"ui.GtkCSDAvailable", eIntID_GTKCSDAvailable, false, 0},
74 {"ui.GtkCSDHideTitlebarByDefault", eIntID_GTKCSDHideTitlebarByDefault,
75 false, 0},
76 {"ui.GtkCSDTransparentBackground", eIntID_GTKCSDTransparentBackground,
77 false, 0},
78 {"ui.GtkCSDMinimizeButton", eIntID_GTKCSDMinimizeButton, false, 0},
79 {"ui.GtkCSDMaximizeButton", eIntID_GTKCSDMaximizeButton, false, 0},
80 {"ui.GtkCSDCloseButton", eIntID_GTKCSDCloseButton, false, 0},
81 {"ui.systemUsesDarkTheme", eIntID_SystemUsesDarkTheme, false, 0},
82 {"ui.prefersReducedMotion", eIntID_PrefersReducedMotion, false, 0},
83 {"ui.primaryPointerCapabilities", eIntID_PrimaryPointerCapabilities, false,
84 6 /* fine and hover-capable pointer, i.e. mouse-type */},
85 {"ui.allPointerCapabilities", eIntID_AllPointerCapabilities, false,
86 6 /* fine and hover-capable pointer, i.e. mouse-type */},
89 nsLookAndFeelFloatPref nsXPLookAndFeel::sFloatPrefs[] = {
90 {"ui.IMEUnderlineRelativeSize", eFloatID_IMEUnderlineRelativeSize, false,
91 0},
92 {"ui.SpellCheckerUnderlineRelativeSize",
93 eFloatID_SpellCheckerUnderlineRelativeSize, false, 0},
94 {"ui.caretAspectRatio", eFloatID_CaretAspectRatio, false, 0},
97 // This array MUST be kept in the same order as the color list in LookAndFeel.h.
98 /* XXX If you add any strings longer than
99 * "ui.-moz-mac-active-source-list-selection"
100 * to the following array then you MUST update the
101 * sizes of the sColorPrefs array in nsXPLookAndFeel.h
103 const char nsXPLookAndFeel::sColorPrefs[][41] = {
104 "ui.windowBackground",
105 "ui.windowForeground",
106 "ui.widgetBackground",
107 "ui.widgetForeground",
108 "ui.widgetSelectBackground",
109 "ui.widgetSelectForeground",
110 "ui.widget3DHighlight",
111 "ui.widget3DShadow",
112 "ui.textBackground",
113 "ui.textForeground",
114 "ui.textSelectBackground",
115 "ui.textSelectForeground",
116 "ui.textSelectForegroundCustom",
117 "ui.textSelectBackgroundDisabled",
118 "ui.textSelectBackgroundAttention",
119 "ui.textHighlightBackground",
120 "ui.textHighlightForeground",
121 "ui.IMERawInputBackground",
122 "ui.IMERawInputForeground",
123 "ui.IMERawInputUnderline",
124 "ui.IMESelectedRawTextBackground",
125 "ui.IMESelectedRawTextForeground",
126 "ui.IMESelectedRawTextUnderline",
127 "ui.IMEConvertedTextBackground",
128 "ui.IMEConvertedTextForeground",
129 "ui.IMEConvertedTextUnderline",
130 "ui.IMESelectedConvertedTextBackground",
131 "ui.IMESelectedConvertedTextForeground",
132 "ui.IMESelectedConvertedTextUnderline",
133 "ui.SpellCheckerUnderline",
134 "ui.activeborder",
135 "ui.activecaption",
136 "ui.appworkspace",
137 "ui.background",
138 "ui.buttonface",
139 "ui.buttonhighlight",
140 "ui.buttonshadow",
141 "ui.buttontext",
142 "ui.captiontext",
143 "ui.graytext",
144 "ui.highlight",
145 "ui.highlighttext",
146 "ui.inactiveborder",
147 "ui.inactivecaption",
148 "ui.inactivecaptiontext",
149 "ui.infobackground",
150 "ui.infotext",
151 "ui.menu",
152 "ui.menutext",
153 "ui.scrollbar",
154 "ui.threeddarkshadow",
155 "ui.threedface",
156 "ui.threedhighlight",
157 "ui.threedlightshadow",
158 "ui.threedshadow",
159 "ui.window",
160 "ui.windowframe",
161 "ui.windowtext",
162 "ui.-moz-buttondefault",
163 "ui.-moz-field",
164 "ui.-moz-fieldtext",
165 "ui.-moz-dialog",
166 "ui.-moz-dialogtext",
167 "ui.-moz-dragtargetzone",
168 "ui.-moz-cellhighlight",
169 "ui.-moz_cellhighlighttext",
170 "ui.-moz-html-cellhighlight",
171 "ui.-moz-html-cellhighlighttext",
172 "ui.-moz-buttonhoverface",
173 "ui.-moz_buttonhovertext",
174 "ui.-moz_menuhover",
175 "ui.-moz_menuhovertext",
176 "ui.-moz_menubartext",
177 "ui.-moz_menubarhovertext",
178 "ui.-moz_eventreerow",
179 "ui.-moz_oddtreerow",
180 "ui.-moz-mac-buttonactivetext",
181 "ui.-moz_mac_chrome_active",
182 "ui.-moz_mac_chrome_inactive",
183 "ui.-moz-mac-defaultbuttontext",
184 "ui.-moz-mac-focusring",
185 "ui.-moz-mac-menuselect",
186 "ui.-moz-mac-menushadow",
187 "ui.-moz-mac-menutextdisable",
188 "ui.-moz-mac-menutextselect",
189 "ui.-moz_mac_disabledtoolbartext",
190 "ui.-moz-mac-secondaryhighlight",
191 "ui.-moz-mac-vibrancy-light",
192 "ui.-moz-mac-vibrancy-dark",
193 "ui.-moz-mac-vibrant-titlebar-light",
194 "ui.-moz-mac-vibrant-titlebar-dark",
195 "ui.-moz-mac-menupopup",
196 "ui.-moz-mac-menuitem",
197 "ui.-moz-mac-active-menuitem",
198 "ui.-moz-mac-source-list",
199 "ui.-moz-mac-source-list-selection",
200 "ui.-moz-mac-active-source-list-selection",
201 "ui.-moz-mac-tooltip",
202 "ui.-moz-win-accentcolor",
203 "ui.-moz-win-accentcolortext",
204 "ui.-moz-win-mediatext",
205 "ui.-moz-win-communicationstext",
206 "ui.-moz-nativehyperlinktext",
207 "ui.-moz-comboboxtext",
208 "ui.-moz-combobox",
209 "ui.-moz-gtk-info-bar-text"};
211 int32_t nsXPLookAndFeel::sCachedColors[LookAndFeel::eColorID_LAST_COLOR] = {0};
212 int32_t nsXPLookAndFeel::sCachedColorBits[COLOR_CACHE_SIZE] = {0};
214 bool nsXPLookAndFeel::sInitialized = false;
215 bool nsXPLookAndFeel::sUseNativeColors = true;
216 bool nsXPLookAndFeel::sFindbarModalHighlight = false;
217 bool nsXPLookAndFeel::sIsInPrefersReducedMotionForTest = false;
218 bool nsXPLookAndFeel::sPrefersReducedMotionForTest = false;
220 nsXPLookAndFeel* nsXPLookAndFeel::sInstance = nullptr;
221 bool nsXPLookAndFeel::sShutdown = false;
223 // static
224 nsXPLookAndFeel* nsXPLookAndFeel::GetInstance() {
225 if (sInstance) {
226 return sInstance;
229 NS_ENSURE_TRUE(!sShutdown, nullptr);
231 if (gfxPlatform::IsHeadless()) {
232 sInstance = new widget::HeadlessLookAndFeel();
233 } else {
234 sInstance = new nsLookAndFeel();
236 return sInstance;
239 // static
240 void nsXPLookAndFeel::Shutdown() {
241 if (sShutdown) {
242 return;
244 sShutdown = true;
245 delete sInstance;
246 sInstance = nullptr;
249 nsXPLookAndFeel::nsXPLookAndFeel()
250 : LookAndFeel(), mShouldRetainCacheForTest(false) {}
252 // static
253 void nsXPLookAndFeel::IntPrefChanged(nsLookAndFeelIntPref* data) {
254 if (!data) {
255 return;
258 int32_t intpref;
259 nsresult rv = Preferences::GetInt(data->name, &intpref);
260 if (NS_FAILED(rv)) {
261 return;
263 data->intVar = intpref;
264 data->isSet = true;
265 #ifdef DEBUG_akkana
266 printf("====== Changed int pref %s to %d\n", data->name, data->intVar);
267 #endif
270 // static
271 void nsXPLookAndFeel::FloatPrefChanged(nsLookAndFeelFloatPref* data) {
272 if (!data) {
273 return;
276 int32_t intpref;
277 nsresult rv = Preferences::GetInt(data->name, &intpref);
278 if (NS_FAILED(rv)) {
279 return;
281 data->floatVar = (float)intpref / 100.0f;
282 data->isSet = true;
283 #ifdef DEBUG_akkana
284 printf("====== Changed float pref %s to %f\n", data->name, data->floatVar);
285 #endif
288 // static
289 void nsXPLookAndFeel::ColorPrefChanged(unsigned int index,
290 const char* prefName) {
291 nsAutoString colorStr;
292 nsresult rv = Preferences::GetString(prefName, colorStr);
293 if (NS_FAILED(rv)) {
294 return;
296 if (!colorStr.IsEmpty()) {
297 nscolor thecolor;
298 if (colorStr[0] == char16_t('#')) {
299 if (NS_HexToRGBA(nsDependentString(colorStr, 1), nsHexColorType::NoAlpha,
300 &thecolor)) {
301 int32_t id = NS_PTR_TO_INT32(index);
302 CACHE_COLOR(id, thecolor);
304 } else if (NS_ColorNameToRGB(colorStr, &thecolor)) {
305 int32_t id = NS_PTR_TO_INT32(index);
306 CACHE_COLOR(id, thecolor);
307 #ifdef DEBUG_akkana
308 printf("====== Changed color pref %s to 0x%lx\n", prefName, thecolor);
309 #endif
311 } else {
312 // Reset to the default color, by clearing the cache
313 // to force lookup when the color is next used
314 int32_t id = NS_PTR_TO_INT32(index);
315 CLEAR_COLOR_CACHE(id);
319 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelIntPref* aPref) {
320 int32_t intpref;
321 nsresult rv = Preferences::GetInt(aPref->name, &intpref);
322 if (NS_SUCCEEDED(rv)) {
323 aPref->isSet = true;
324 aPref->intVar = intpref;
328 void nsXPLookAndFeel::InitFromPref(nsLookAndFeelFloatPref* aPref) {
329 int32_t intpref;
330 nsresult rv = Preferences::GetInt(aPref->name, &intpref);
331 if (NS_SUCCEEDED(rv)) {
332 aPref->isSet = true;
333 aPref->floatVar = (float)intpref / 100.0f;
337 void nsXPLookAndFeel::InitColorFromPref(int32_t i) {
338 nsAutoString colorStr;
339 nsresult rv = Preferences::GetString(sColorPrefs[i], colorStr);
340 if (NS_FAILED(rv) || colorStr.IsEmpty()) {
341 return;
343 nscolor thecolor;
344 if (colorStr[0] == char16_t('#')) {
345 nsAutoString hexString;
346 colorStr.Right(hexString, colorStr.Length() - 1);
347 if (NS_HexToRGBA(hexString, nsHexColorType::NoAlpha, &thecolor)) {
348 CACHE_COLOR(i, thecolor);
350 } else if (NS_ColorNameToRGB(colorStr, &thecolor)) {
351 CACHE_COLOR(i, thecolor);
355 // static
356 void nsXPLookAndFeel::OnPrefChanged(const char* aPref, void* aClosure) {
357 // looping in the same order as in ::Init
359 nsDependentCString prefName(aPref);
360 unsigned int i;
361 for (i = 0; i < ArrayLength(sIntPrefs); ++i) {
362 if (prefName.Equals(sIntPrefs[i].name)) {
363 IntPrefChanged(&sIntPrefs[i]);
364 return;
368 for (i = 0; i < ArrayLength(sFloatPrefs); ++i) {
369 if (prefName.Equals(sFloatPrefs[i].name)) {
370 FloatPrefChanged(&sFloatPrefs[i]);
371 return;
375 for (i = 0; i < ArrayLength(sColorPrefs); ++i) {
376 if (prefName.Equals(sColorPrefs[i])) {
377 ColorPrefChanged(i, sColorPrefs[i]);
378 return;
384 // Read values from the user's preferences.
385 // This is done once at startup, but since the user's preferences
386 // haven't actually been read yet at that time, we also have to
387 // set a callback to inform us of changes to each pref.
389 void nsXPLookAndFeel::Init() {
390 MOZ_RELEASE_ASSERT(NS_IsMainThread());
392 // Say we're already initialized, and take the chance that it might fail;
393 // protects against some other process writing to our static variables.
394 sInitialized = true;
396 // XXX If we could reorganize the pref names, we should separate the branch
397 // for each types. Then, we could reduce the unnecessary loop from
398 // nsXPLookAndFeel::OnPrefChanged().
399 Preferences::RegisterPrefixCallback(OnPrefChanged, "ui.");
400 // We really do just want the accessibility.tabfocus pref, not other prefs
401 // that start with that string.
402 Preferences::RegisterCallback(OnPrefChanged, "accessibility.tabfocus");
404 unsigned int i;
405 for (i = 0; i < ArrayLength(sIntPrefs); ++i) {
406 InitFromPref(&sIntPrefs[i]);
409 for (i = 0; i < ArrayLength(sFloatPrefs); ++i) {
410 InitFromPref(&sFloatPrefs[i]);
413 for (i = 0; i < ArrayLength(sColorPrefs); ++i) {
414 InitColorFromPref(i);
417 Preferences::AddBoolVarCache(&sUseNativeColors, "ui.use_native_colors",
418 sUseNativeColors);
419 Preferences::AddBoolVarCache(&sFindbarModalHighlight,
420 "findbar.modalHighlight",
421 sFindbarModalHighlight);
423 if (XRE_IsContentProcess()) {
424 mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
426 LookAndFeel::SetIntCache(cc->LookAndFeelCache());
427 // This is only ever used once during initialization, and can be cleared
428 // now.
429 cc->LookAndFeelCache().Clear();
433 nsXPLookAndFeel::~nsXPLookAndFeel() {
434 NS_ASSERTION(sInstance == this,
435 "This destroying instance isn't the singleton instance");
436 sInstance = nullptr;
439 bool nsXPLookAndFeel::IsSpecialColor(ColorID aID, nscolor& aColor) {
440 switch (aID) {
441 case eColorID_TextSelectForeground:
442 return (aColor == NS_DONT_CHANGE_COLOR);
443 case eColorID_IMESelectedRawTextBackground:
444 case eColorID_IMESelectedConvertedTextBackground:
445 case eColorID_IMERawInputBackground:
446 case eColorID_IMEConvertedTextBackground:
447 case eColorID_IMESelectedRawTextForeground:
448 case eColorID_IMESelectedConvertedTextForeground:
449 case eColorID_IMERawInputForeground:
450 case eColorID_IMEConvertedTextForeground:
451 case eColorID_IMERawInputUnderline:
452 case eColorID_IMEConvertedTextUnderline:
453 case eColorID_IMESelectedRawTextUnderline:
454 case eColorID_IMESelectedConvertedTextUnderline:
455 case eColorID_SpellCheckerUnderline:
456 return NS_IS_SELECTION_SPECIAL_COLOR(aColor);
457 default:
459 * In GetColor(), every color that is not a special color is color
460 * corrected. Use false to make other colors color corrected.
462 return false;
464 return false;
467 bool nsXPLookAndFeel::ColorIsNotCSSAccessible(ColorID aID) {
468 bool result = false;
470 switch (aID) {
471 case eColorID_WindowBackground:
472 case eColorID_WindowForeground:
473 case eColorID_WidgetBackground:
474 case eColorID_WidgetForeground:
475 case eColorID_WidgetSelectBackground:
476 case eColorID_WidgetSelectForeground:
477 case eColorID_Widget3DHighlight:
478 case eColorID_Widget3DShadow:
479 case eColorID_TextBackground:
480 case eColorID_TextForeground:
481 case eColorID_TextSelectBackground:
482 case eColorID_TextSelectForeground:
483 case eColorID_TextSelectBackgroundDisabled:
484 case eColorID_TextSelectBackgroundAttention:
485 case eColorID_TextHighlightBackground:
486 case eColorID_TextHighlightForeground:
487 case eColorID_IMERawInputBackground:
488 case eColorID_IMERawInputForeground:
489 case eColorID_IMERawInputUnderline:
490 case eColorID_IMESelectedRawTextBackground:
491 case eColorID_IMESelectedRawTextForeground:
492 case eColorID_IMESelectedRawTextUnderline:
493 case eColorID_IMEConvertedTextBackground:
494 case eColorID_IMEConvertedTextForeground:
495 case eColorID_IMEConvertedTextUnderline:
496 case eColorID_IMESelectedConvertedTextBackground:
497 case eColorID_IMESelectedConvertedTextForeground:
498 case eColorID_IMESelectedConvertedTextUnderline:
499 case eColorID_SpellCheckerUnderline:
500 result = true;
501 break;
502 default:
503 break;
506 return result;
509 nscolor nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID) {
510 nscolor result = NS_RGB(0xFF, 0xFF, 0xFF);
512 // The stand-in colors are taken from the Windows 7 Aero theme
513 // except Mac-specific colors which are taken from Mac OS 10.7.
514 switch (aID) {
515 // CSS 2 colors:
516 case eColorID_activeborder:
517 result = NS_RGB(0xB4, 0xB4, 0xB4);
518 break;
519 case eColorID_activecaption:
520 result = NS_RGB(0x99, 0xB4, 0xD1);
521 break;
522 case eColorID_appworkspace:
523 result = NS_RGB(0xAB, 0xAB, 0xAB);
524 break;
525 case eColorID_background:
526 result = NS_RGB(0x00, 0x00, 0x00);
527 break;
528 case eColorID_buttonface:
529 result = NS_RGB(0xF0, 0xF0, 0xF0);
530 break;
531 case eColorID_buttonhighlight:
532 result = NS_RGB(0xFF, 0xFF, 0xFF);
533 break;
534 case eColorID_buttonshadow:
535 result = NS_RGB(0xA0, 0xA0, 0xA0);
536 break;
537 case eColorID_buttontext:
538 result = NS_RGB(0x00, 0x00, 0x00);
539 break;
540 case eColorID_captiontext:
541 result = NS_RGB(0x00, 0x00, 0x00);
542 break;
543 case eColorID_graytext:
544 result = NS_RGB(0x6D, 0x6D, 0x6D);
545 break;
546 case eColorID_highlight:
547 result = NS_RGB(0x33, 0x99, 0xFF);
548 break;
549 case eColorID_highlighttext:
550 result = NS_RGB(0xFF, 0xFF, 0xFF);
551 break;
552 case eColorID_inactiveborder:
553 result = NS_RGB(0xF4, 0xF7, 0xFC);
554 break;
555 case eColorID_inactivecaption:
556 result = NS_RGB(0xBF, 0xCD, 0xDB);
557 break;
558 case eColorID_inactivecaptiontext:
559 result = NS_RGB(0x43, 0x4E, 0x54);
560 break;
561 case eColorID_infobackground:
562 result = NS_RGB(0xFF, 0xFF, 0xE1);
563 break;
564 case eColorID_infotext:
565 result = NS_RGB(0x00, 0x00, 0x00);
566 break;
567 case eColorID_menu:
568 result = NS_RGB(0xF0, 0xF0, 0xF0);
569 break;
570 case eColorID_menutext:
571 result = NS_RGB(0x00, 0x00, 0x00);
572 break;
573 case eColorID_scrollbar:
574 result = NS_RGB(0xC8, 0xC8, 0xC8);
575 break;
576 case eColorID_threeddarkshadow:
577 result = NS_RGB(0x69, 0x69, 0x69);
578 break;
579 case eColorID_threedface:
580 result = NS_RGB(0xF0, 0xF0, 0xF0);
581 break;
582 case eColorID_threedhighlight:
583 result = NS_RGB(0xFF, 0xFF, 0xFF);
584 break;
585 case eColorID_threedlightshadow:
586 result = NS_RGB(0xE3, 0xE3, 0xE3);
587 break;
588 case eColorID_threedshadow:
589 result = NS_RGB(0xA0, 0xA0, 0xA0);
590 break;
591 case eColorID_window:
592 result = NS_RGB(0xFF, 0xFF, 0xFF);
593 break;
594 case eColorID_windowframe:
595 result = NS_RGB(0x64, 0x64, 0x64);
596 break;
597 case eColorID_windowtext:
598 result = NS_RGB(0x00, 0x00, 0x00);
599 break;
600 case eColorID__moz_buttondefault:
601 result = NS_RGB(0x69, 0x69, 0x69);
602 break;
603 case eColorID__moz_field:
604 result = NS_RGB(0xFF, 0xFF, 0xFF);
605 break;
606 case eColorID__moz_fieldtext:
607 result = NS_RGB(0x00, 0x00, 0x00);
608 break;
609 case eColorID__moz_dialog:
610 result = NS_RGB(0xF0, 0xF0, 0xF0);
611 break;
612 case eColorID__moz_dialogtext:
613 result = NS_RGB(0x00, 0x00, 0x00);
614 break;
615 case eColorID__moz_dragtargetzone:
616 result = NS_RGB(0xFF, 0xFF, 0xFF);
617 break;
618 case eColorID__moz_cellhighlight:
619 result = NS_RGB(0xF0, 0xF0, 0xF0);
620 break;
621 case eColorID__moz_cellhighlighttext:
622 result = NS_RGB(0x00, 0x00, 0x00);
623 break;
624 case eColorID__moz_html_cellhighlight:
625 result = NS_RGB(0x33, 0x99, 0xFF);
626 break;
627 case eColorID__moz_html_cellhighlighttext:
628 result = NS_RGB(0xFF, 0xFF, 0xFF);
629 break;
630 case eColorID__moz_buttonhoverface:
631 result = NS_RGB(0xF0, 0xF0, 0xF0);
632 break;
633 case eColorID__moz_buttonhovertext:
634 result = NS_RGB(0x00, 0x00, 0x00);
635 break;
636 case eColorID__moz_menuhover:
637 result = NS_RGB(0x33, 0x99, 0xFF);
638 break;
639 case eColorID__moz_menuhovertext:
640 result = NS_RGB(0x00, 0x00, 0x00);
641 break;
642 case eColorID__moz_menubartext:
643 result = NS_RGB(0x00, 0x00, 0x00);
644 break;
645 case eColorID__moz_menubarhovertext:
646 result = NS_RGB(0x00, 0x00, 0x00);
647 break;
648 case eColorID__moz_oddtreerow:
649 result = NS_RGB(0xFF, 0xFF, 0xFF);
650 break;
651 case eColorID__moz_mac_chrome_active:
652 result = NS_RGB(0xB2, 0xB2, 0xB2);
653 break;
654 case eColorID__moz_mac_chrome_inactive:
655 result = NS_RGB(0xE1, 0xE1, 0xE1);
656 break;
657 case eColorID__moz_mac_focusring:
658 result = NS_RGB(0x60, 0x9D, 0xD7);
659 break;
660 case eColorID__moz_mac_menuselect:
661 result = NS_RGB(0x38, 0x75, 0xD7);
662 break;
663 case eColorID__moz_mac_menushadow:
664 result = NS_RGB(0xA3, 0xA3, 0xA3);
665 break;
666 case eColorID__moz_mac_menutextdisable:
667 result = NS_RGB(0x88, 0x88, 0x88);
668 break;
669 case eColorID__moz_mac_menutextselect:
670 result = NS_RGB(0xFF, 0xFF, 0xFF);
671 break;
672 case eColorID__moz_mac_disabledtoolbartext:
673 result = NS_RGB(0x3F, 0x3F, 0x3F);
674 break;
675 case eColorID__moz_mac_secondaryhighlight:
676 result = NS_RGB(0xD4, 0xD4, 0xD4);
677 break;
678 case eColorID__moz_mac_vibrancy_light:
679 case eColorID__moz_mac_vibrant_titlebar_light:
680 result = NS_RGB(0xf7, 0xf7, 0xf7);
681 break;
682 case eColorID__moz_mac_vibrancy_dark:
683 case eColorID__moz_mac_vibrant_titlebar_dark:
684 result = NS_RGB(0x28, 0x28, 0x28);
685 break;
686 case eColorID__moz_mac_menupopup:
687 result = NS_RGB(0xe6, 0xe6, 0xe6);
688 break;
689 case eColorID__moz_mac_menuitem:
690 result = NS_RGB(0xe6, 0xe6, 0xe6);
691 break;
692 case eColorID__moz_mac_active_menuitem:
693 result = NS_RGB(0x0a, 0x64, 0xdc);
694 break;
695 case eColorID__moz_mac_source_list:
696 result = NS_RGB(0xf7, 0xf7, 0xf7);
697 break;
698 case eColorID__moz_mac_source_list_selection:
699 result = NS_RGB(0xc8, 0xc8, 0xc8);
700 break;
701 case eColorID__moz_mac_active_source_list_selection:
702 result = NS_RGB(0x0a, 0x64, 0xdc);
703 break;
704 case eColorID__moz_mac_tooltip:
705 result = NS_RGB(0xf7, 0xf7, 0xf7);
706 break;
707 case eColorID__moz_win_accentcolor:
708 // Seems to be the default color (hardcoded because of bug 1065998)
709 result = NS_RGB(0x9E, 0x9E, 0x9E);
710 break;
711 case eColorID__moz_win_accentcolortext:
712 result = NS_RGB(0x00, 0x00, 0x00);
713 break;
714 case eColorID__moz_win_mediatext:
715 result = NS_RGB(0xFF, 0xFF, 0xFF);
716 break;
717 case eColorID__moz_win_communicationstext:
718 result = NS_RGB(0xFF, 0xFF, 0xFF);
719 break;
720 case eColorID__moz_nativehyperlinktext:
721 result = NS_RGB(0x00, 0x66, 0xCC);
722 break;
723 case eColorID__moz_comboboxtext:
724 result = NS_RGB(0x00, 0x00, 0x00);
725 break;
726 case eColorID__moz_combobox:
727 result = NS_RGB(0xFF, 0xFF, 0xFF);
728 break;
729 default:
730 break;
733 return result;
737 // All these routines will return NS_OK if they have a value,
738 // in which case the nsLookAndFeel should use that value;
739 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
740 // platform-specific nsLookAndFeel should use its own values instead.
742 nsresult nsXPLookAndFeel::GetColorImpl(ColorID aID,
743 bool aUseStandinsForNativeColors,
744 nscolor& aResult) {
745 if (!sInitialized) Init();
747 // define DEBUG_SYSTEM_COLOR_USE if you want to debug system color
748 // use in a skin that uses them. When set, it will make all system
749 // color pairs that are appropriate for foreground/background
750 // pairing the same. This means if the skin is using system colors
751 // correctly you will not be able to see *any* text.
752 #undef DEBUG_SYSTEM_COLOR_USE
754 #ifdef DEBUG_SYSTEM_COLOR_USE
756 nsresult rv = NS_OK;
757 switch (aID) {
758 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
759 case eColorID_activecaption:
760 // active window caption background
761 case eColorID_captiontext:
762 // text in active window caption
763 aResult = NS_RGB(0xff, 0x00, 0x00);
764 break;
766 case eColorID_highlight:
767 // background of selected item
768 case eColorID_highlighttext:
769 // text of selected item
770 aResult = NS_RGB(0xff, 0xff, 0x00);
771 break;
773 case eColorID_inactivecaption:
774 // inactive window caption
775 case eColorID_inactivecaptiontext:
776 // text in inactive window caption
777 aResult = NS_RGB(0x66, 0x66, 0x00);
778 break;
780 case eColorID_infobackground:
781 // tooltip background color
782 case eColorID_infotext:
783 // tooltip text color
784 aResult = NS_RGB(0x00, 0xff, 0x00);
785 break;
787 case eColorID_menu:
788 // menu background
789 case eColorID_menutext:
790 // menu text
791 aResult = NS_RGB(0x00, 0xff, 0xff);
792 break;
794 case eColorID_threedface:
795 case eColorID_buttonface:
796 // 3-D face color
797 case eColorID_buttontext:
798 // text on push buttons
799 aResult = NS_RGB(0x00, 0x66, 0x66);
800 break;
802 case eColorID_window:
803 case eColorID_windowtext:
804 aResult = NS_RGB(0x00, 0x00, 0xff);
805 break;
807 // from the CSS3 working draft (not yet finalized)
808 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
810 case eColorID__moz_field:
811 case eColorID__moz_fieldtext:
812 aResult = NS_RGB(0xff, 0x00, 0xff);
813 break;
815 case eColorID__moz_dialog:
816 case eColorID__moz_dialogtext:
817 aResult = NS_RGB(0x66, 0x00, 0x66);
818 break;
820 default:
821 rv = NS_ERROR_NOT_AVAILABLE;
823 if (NS_SUCCEEDED(rv)) return rv;
825 #endif // DEBUG_SYSTEM_COLOR_USE
827 if (aUseStandinsForNativeColors &&
828 (ColorIsNotCSSAccessible(aID) ||
829 !nsContentUtils::UseStandinsForNativeColors())) {
830 aUseStandinsForNativeColors = false;
833 if (!aUseStandinsForNativeColors && IS_COLOR_CACHED(aID)) {
834 aResult = sCachedColors[aID];
835 return NS_OK;
838 // There are no system color settings for these, so set them manually
839 #ifndef XP_MACOSX
840 if (aID == eColorID_TextSelectBackgroundDisabled) {
841 // This is used to gray out the selection when it's not focused
842 // Used with nsISelectionController::SELECTION_DISABLED
843 aResult = NS_RGB(0xb0, 0xb0, 0xb0);
844 return NS_OK;
846 #endif
848 if (aID == eColorID_TextSelectBackgroundAttention) {
849 if (sFindbarModalHighlight) {
850 aResult = NS_RGBA(0, 0, 0, 0);
851 return NS_OK;
854 // This makes the selection stand out when typeaheadfind is on
855 // Used with nsISelectionController::SELECTION_ATTENTION
856 aResult = NS_RGB(0x38, 0xd8, 0x78);
857 return NS_OK;
860 if (aID == eColorID_TextHighlightBackground) {
861 // This makes the matched text stand out when findbar highlighting is on
862 // Used with nsISelectionController::SELECTION_FIND
863 aResult = NS_RGB(0xef, 0x0f, 0xff);
864 return NS_OK;
867 if (aID == eColorID_TextHighlightForeground) {
868 // The foreground color for the matched text in findbar highlighting
869 // Used with nsISelectionController::SELECTION_FIND
870 aResult = NS_RGB(0xff, 0xff, 0xff);
871 return NS_OK;
874 if (sUseNativeColors && aUseStandinsForNativeColors) {
875 aResult = GetStandinForNativeColor(aID);
876 return NS_OK;
879 if (sUseNativeColors && NS_SUCCEEDED(NativeGetColor(aID, aResult))) {
880 if (!mozilla::ServoStyleSet::IsInServoTraversal()) {
881 MOZ_ASSERT(NS_IsMainThread());
882 // Make sure the preferences are initialized. In the normal run,
883 // they would already be, because gfxPlatform would have been created,
884 // but with some addon, that is not the case. See Bug 1357307.
885 gfxPrefs::GetSingleton();
886 if ((gfxPlatform::GetCMSMode() == eCMSMode_All) &&
887 !IsSpecialColor(aID, aResult)) {
888 qcms_transform* transform = gfxPlatform::GetCMSInverseRGBTransform();
889 if (transform) {
890 uint8_t color[3];
891 color[0] = NS_GET_R(aResult);
892 color[1] = NS_GET_G(aResult);
893 color[2] = NS_GET_B(aResult);
894 qcms_transform_data(transform, color, color, 1);
895 aResult = NS_RGB(color[0], color[1], color[2]);
899 CACHE_COLOR(aID, aResult);
901 return NS_OK;
904 return NS_ERROR_NOT_AVAILABLE;
907 nsresult nsXPLookAndFeel::GetIntImpl(IntID aID, int32_t& aResult) {
908 if (!sInitialized) Init();
910 // Set the default values for these prefs. but allow different platforms
911 // to override them in their nsLookAndFeel if desired.
912 switch (aID) {
913 case eIntID_ScrollButtonLeftMouseButtonAction:
914 aResult = 0;
915 return NS_OK;
916 case eIntID_ScrollButtonMiddleMouseButtonAction:
917 aResult = 3;
918 return NS_OK;
919 case eIntID_ScrollButtonRightMouseButtonAction:
920 aResult = 3;
921 return NS_OK;
922 default:
924 * The metrics above are hardcoded platform defaults. All the other
925 * metrics are stored in sIntPrefs and can be changed at runtime.
927 break;
930 for (unsigned int i = 0; i < ArrayLength(sIntPrefs); ++i) {
931 if (sIntPrefs[i].isSet && (sIntPrefs[i].id == aID)) {
932 aResult = sIntPrefs[i].intVar;
933 return NS_OK;
937 return NS_ERROR_NOT_AVAILABLE;
940 nsresult nsXPLookAndFeel::GetFloatImpl(FloatID aID, float& aResult) {
941 if (!sInitialized) Init();
943 for (unsigned int i = 0; i < ArrayLength(sFloatPrefs); ++i) {
944 if (sFloatPrefs[i].isSet && sFloatPrefs[i].id == aID) {
945 aResult = sFloatPrefs[i].floatVar;
946 return NS_OK;
950 return NS_ERROR_NOT_AVAILABLE;
953 void nsXPLookAndFeel::RefreshImpl() {
954 // Wipe out our color cache.
955 uint32_t i;
956 for (i = 0; i < eColorID_LAST_COLOR; i++) sCachedColors[i] = 0;
957 for (i = 0; i < COLOR_CACHE_SIZE; i++) sCachedColorBits[i] = 0;
960 nsTArray<LookAndFeelInt> nsXPLookAndFeel::GetIntCacheImpl() {
961 return nsTArray<LookAndFeelInt>();
964 namespace mozilla {
966 // static
967 nsresult LookAndFeel::GetColor(ColorID aID, nscolor* aResult) {
968 return nsLookAndFeel::GetInstance()->GetColorImpl(aID, false, *aResult);
971 nsresult LookAndFeel::GetColor(ColorID aID, bool aUseStandinsForNativeColors,
972 nscolor* aResult) {
973 return nsLookAndFeel::GetInstance()->GetColorImpl(
974 aID, aUseStandinsForNativeColors, *aResult);
977 // static
978 nsresult LookAndFeel::GetInt(IntID aID, int32_t* aResult) {
979 return nsLookAndFeel::GetInstance()->GetIntImpl(aID, *aResult);
982 // static
983 nsresult LookAndFeel::GetFloat(FloatID aID, float* aResult) {
984 return nsLookAndFeel::GetInstance()->GetFloatImpl(aID, *aResult);
987 // static
988 bool LookAndFeel::GetFont(FontID aID, nsString& aName, gfxFontStyle& aStyle) {
989 return nsLookAndFeel::GetInstance()->GetFontImpl(aID, aName, aStyle);
992 // static
993 char16_t LookAndFeel::GetPasswordCharacter() {
994 return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
997 // static
998 bool LookAndFeel::GetEchoPassword() {
999 return nsLookAndFeel::GetInstance()->GetEchoPasswordImpl();
1002 // static
1003 uint32_t LookAndFeel::GetPasswordMaskDelay() {
1004 return nsLookAndFeel::GetInstance()->GetPasswordMaskDelayImpl();
1007 // static
1008 void LookAndFeel::Refresh() { nsLookAndFeel::GetInstance()->RefreshImpl(); }
1010 // static
1011 void LookAndFeel::NativeInit() { nsLookAndFeel::GetInstance()->NativeInit(); }
1013 // static
1014 nsTArray<LookAndFeelInt> LookAndFeel::GetIntCache() {
1015 return nsLookAndFeel::GetInstance()->GetIntCacheImpl();
1018 // static
1019 void LookAndFeel::SetIntCache(
1020 const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache) {
1021 return nsLookAndFeel::GetInstance()->SetIntCacheImpl(aLookAndFeelIntCache);
1024 // static
1025 void LookAndFeel::SetShouldRetainCacheForTest(bool aValue) {
1026 nsLookAndFeel::GetInstance()->SetShouldRetainCacheImplForTest(aValue);
1029 } // namespace mozilla