1 /* -*- Mode: C++; tab-width: 2; 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 "nsLookAndFeel.h"
10 #include "nsStyleConsts.h"
11 #include "nsUXThemeData.h"
12 #include "nsUXThemeConstants.h"
13 #include "nsWindowsHelpers.h"
15 #include "WindowsUIUtils.h"
16 #include "mozilla/FontPropertyTypes.h"
17 #include "mozilla/Telemetry.h"
18 #include "mozilla/WindowsVersion.h"
19 #include "gfxFontConstants.h"
20 #include "gfxWindowsPlatform.h"
22 using namespace mozilla
;
23 using namespace mozilla::widget
;
25 static Maybe
<nscolor
> GetColorFromTheme(nsUXThemeClass cls
, int32_t aPart
,
26 int32_t aState
, int32_t aPropId
) {
28 HRESULT hr
= GetThemeColor(nsUXThemeData::GetTheme(cls
), aPart
, aState
,
31 return Some(COLOREF_2_NSRGB(color
));
36 static int32_t GetSystemParam(long flag
, int32_t def
) {
38 return ::SystemParametersInfo(flag
, 0, &value
, 0) ? value
: def
;
41 static nsresult
SystemWantsDarkTheme(int32_t& darkThemeEnabled
) {
42 if (!IsWin10OrLater()) {
48 nsCOMPtr
<nsIWindowsRegKey
> personalizeKey
=
49 do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv
);
50 if (NS_WARN_IF(NS_FAILED(rv
))) {
54 rv
= personalizeKey
->Open(
55 nsIWindowsRegKey::ROOT_KEY_CURRENT_USER
,
57 u
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"),
58 nsIWindowsRegKey::ACCESS_QUERY_VALUE
);
63 uint32_t lightThemeEnabled
;
65 personalizeKey
->ReadIntValue(u
"AppsUseLightTheme"_ns
, &lightThemeEnabled
);
66 if (NS_SUCCEEDED(rv
)) {
67 darkThemeEnabled
= !lightThemeEnabled
;
73 static int32_t SystemColorFilter() {
75 nsCOMPtr
<nsIWindowsRegKey
> colorFilteringKey
=
76 do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv
);
77 if (NS_WARN_IF(NS_FAILED(rv
))) {
81 rv
= colorFilteringKey
->Open(
82 nsIWindowsRegKey::ROOT_KEY_CURRENT_USER
,
83 u
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Accessibility\\ATConfig\\colorfiltering"_ns
,
84 nsIWindowsRegKey::ACCESS_QUERY_VALUE
);
89 // The Active value is set to 1 when the "Turn on color filters" setting
90 // in the Color filters section of Windows' Ease of Access settings is turned
91 // on. If it is disabled (Active == 0 or does not exist), do not report having
94 rv
= colorFilteringKey
->ReadIntValue(u
"Active"_ns
, &active
);
95 if (NS_FAILED(rv
) || active
== 0) {
99 // The FilterType value is set to whichever filter is enabled.
101 rv
= colorFilteringKey
->ReadIntValue(u
"FilterType"_ns
, &filterType
);
102 if (NS_SUCCEEDED(rv
)) {
109 nsLookAndFeel::nsLookAndFeel() {
110 mozilla::Telemetry::Accumulate(mozilla::Telemetry::TOUCH_ENABLED_DEVICE
,
111 WinUtils::IsTouchDeviceSupportPresent());
114 nsLookAndFeel::~nsLookAndFeel() = default;
116 void nsLookAndFeel::NativeInit() { EnsureInit(); }
119 void nsLookAndFeel::RefreshImpl() {
120 mInitialized
= false; // Fetch system colors next time they're used.
121 nsXPLookAndFeel::RefreshImpl();
124 static bool UseNonNativeMenuColors(ColorScheme aScheme
) {
125 if (!LookAndFeel::WindowsNonNativeMenusEnabled()) {
128 return LookAndFeel::GetInt(LookAndFeel::IntID::WindowsDefaultTheme
) ||
129 aScheme
== ColorScheme::Dark
;
132 nsresult
nsLookAndFeel::NativeGetColor(ColorID aID
, ColorScheme aScheme
,
136 auto IsHighlightColor
= [&] {
138 case ColorID::MozMenuhover
:
139 return !UseNonNativeMenuColors(aScheme
);
140 case ColorID::Highlight
:
141 case ColorID::Selecteditem
:
142 // We prefer the generic dark selection color if we don't have an
144 return aScheme
!= ColorScheme::Dark
|| mDarkHighlight
;
145 case ColorID::IMESelectedRawTextBackground
:
146 case ColorID::IMESelectedConvertedTextBackground
:
153 auto IsHighlightTextColor
= [&] {
155 case ColorID::MozMenubarhovertext
:
156 if (UseNonNativeMenuColors(aScheme
)) {
159 if (!nsUXThemeData::IsAppThemed()) {
160 return nsUXThemeData::AreFlatMenusEnabled();
163 case ColorID::MozMenuhovertext
:
164 if (UseNonNativeMenuColors(aScheme
)) {
167 return !mColorMenuHoverText
;
168 case ColorID::Highlighttext
:
169 case ColorID::Selecteditemtext
:
170 // We prefer the generic dark selection color if we don't have an
172 return aScheme
!= ColorScheme::Dark
|| mDarkHighlightText
;
173 case ColorID::IMESelectedRawTextForeground
:
174 case ColorID::IMESelectedConvertedTextForeground
:
175 case ColorID::MozDragtargetzone
:
182 if (IsHighlightColor()) {
183 if (aScheme
== ColorScheme::Dark
&& mDarkHighlight
) {
184 aColor
= *mDarkHighlight
;
186 aColor
= GetColorForSysColorIndex(COLOR_HIGHLIGHT
);
191 if (IsHighlightTextColor()) {
192 if (aScheme
== ColorScheme::Dark
&& mDarkHighlightText
) {
193 aColor
= *mDarkHighlightText
;
195 aColor
= GetColorForSysColorIndex(COLOR_HIGHLIGHTTEXT
);
200 if (aScheme
== ColorScheme::Dark
) {
201 if (auto color
= GenericDarkColor(aID
)) {
207 static constexpr auto kNonNativeMenuText
= NS_RGB(0x15, 0x14, 0x1a);
208 nsresult res
= NS_OK
;
211 case ColorID::IMERawInputBackground
:
212 case ColorID::IMEConvertedTextBackground
:
213 aColor
= NS_TRANSPARENT
;
215 case ColorID::IMERawInputForeground
:
216 case ColorID::IMEConvertedTextForeground
:
217 aColor
= NS_SAME_AS_FOREGROUND_COLOR
;
219 case ColorID::IMERawInputUnderline
:
220 case ColorID::IMEConvertedTextUnderline
:
221 aColor
= NS_SAME_AS_FOREGROUND_COLOR
;
223 case ColorID::IMESelectedRawTextUnderline
:
224 case ColorID::IMESelectedConvertedTextUnderline
:
225 aColor
= NS_TRANSPARENT
;
228 // New CSS 2 Color definitions
229 case ColorID::Activeborder
:
230 idx
= COLOR_ACTIVEBORDER
;
232 case ColorID::Activecaption
:
233 idx
= COLOR_ACTIVECAPTION
;
235 case ColorID::Appworkspace
:
236 idx
= COLOR_APPWORKSPACE
;
238 case ColorID::Background
:
239 idx
= COLOR_BACKGROUND
;
241 case ColorID::Buttonface
:
242 case ColorID::MozButtonhoverface
:
243 case ColorID::MozButtonactiveface
:
244 case ColorID::MozButtondisabledface
:
247 case ColorID::Buttonhighlight
:
248 idx
= COLOR_BTNHIGHLIGHT
;
250 case ColorID::Buttonshadow
:
251 idx
= COLOR_BTNSHADOW
;
253 case ColorID::Buttontext
:
254 case ColorID::MozButtonhovertext
:
255 case ColorID::MozButtonactivetext
:
258 case ColorID::Captiontext
:
259 idx
= COLOR_CAPTIONTEXT
;
261 case ColorID::MozCellhighlighttext
:
262 aColor
= NS_RGB(0, 0, 0);
264 case ColorID::MozCellhighlight
:
265 aColor
= NS_RGB(206, 206, 206);
267 case ColorID::Graytext
:
268 idx
= COLOR_GRAYTEXT
;
270 case ColorID::MozMenubarhovertext
:
271 if (UseNonNativeMenuColors(aScheme
)) {
272 aColor
= kNonNativeMenuText
;
275 if (!nsUXThemeData::IsAppThemed()) {
276 idx
= COLOR_MENUTEXT
;
280 case ColorID::MozMenuhovertext
:
281 if (UseNonNativeMenuColors(aScheme
)) {
282 aColor
= kNonNativeMenuText
;
285 if (mColorMenuHoverText
) {
286 aColor
= *mColorMenuHoverText
;
289 idx
= COLOR_HIGHLIGHTTEXT
;
291 case ColorID::MozMenuhover
:
292 MOZ_ASSERT(UseNonNativeMenuColors(aScheme
));
293 aColor
= NS_RGB(0xe0, 0xe0, 0xe6);
295 case ColorID::MozMenuhoverdisabled
:
296 if (UseNonNativeMenuColors(aScheme
)) {
297 aColor
= NS_RGB(0xf0, 0xf0, 0xf3);
300 aColor
= NS_TRANSPARENT
;
302 case ColorID::Inactiveborder
:
303 idx
= COLOR_INACTIVEBORDER
;
305 case ColorID::Inactivecaption
:
306 idx
= COLOR_INACTIVECAPTION
;
308 case ColorID::Inactivecaptiontext
:
309 idx
= COLOR_INACTIVECAPTIONTEXT
;
311 case ColorID::Infobackground
:
314 case ColorID::Infotext
:
315 idx
= COLOR_INFOTEXT
;
318 if (UseNonNativeMenuColors(aScheme
)) {
319 aColor
= NS_RGB(0xf9, 0xf9, 0xfb);
324 case ColorID::Menutext
:
325 case ColorID::MozMenubartext
:
326 if (UseNonNativeMenuColors(aScheme
)) {
327 aColor
= kNonNativeMenuText
;
330 idx
= COLOR_MENUTEXT
;
332 case ColorID::Scrollbar
:
333 idx
= COLOR_SCROLLBAR
;
335 case ColorID::Threeddarkshadow
:
336 idx
= COLOR_3DDKSHADOW
;
338 case ColorID::Threedface
:
341 case ColorID::Threedhighlight
:
342 idx
= COLOR_3DHIGHLIGHT
;
344 case ColorID::Threedlightshadow
:
345 case ColorID::Buttonborder
:
346 case ColorID::MozDisabledfield
:
349 case ColorID::Threedshadow
:
350 idx
= COLOR_3DSHADOW
;
352 case ColorID::Window
:
355 case ColorID::Windowframe
:
356 idx
= COLOR_WINDOWFRAME
;
358 case ColorID::Windowtext
:
359 idx
= COLOR_WINDOWTEXT
;
361 case ColorID::MozEventreerow
:
362 case ColorID::MozOddtreerow
:
364 case ColorID::MozCombobox
:
367 case ColorID::Fieldtext
:
368 case ColorID::MozComboboxtext
:
369 idx
= COLOR_WINDOWTEXT
;
371 case ColorID::MozDialog
:
374 case ColorID::Accentcolor
:
376 aColor
= *mColorAccent
;
378 // Seems to be the default color (hardcoded because of bug 1065998)
379 aColor
= NS_RGB(0, 120, 215);
382 case ColorID::Accentcolortext
:
383 if (mColorAccentText
) {
384 aColor
= *mColorAccentText
;
386 aColor
= NS_RGB(255, 255, 255);
389 case ColorID::MozWinMediatext
:
390 if (mColorMediaText
) {
391 aColor
= *mColorMediaText
;
394 // if we've gotten here just return -moz-dialogtext instead
395 idx
= COLOR_WINDOWTEXT
;
397 case ColorID::MozWinCommunicationstext
:
398 if (mColorCommunicationsText
) {
399 aColor
= *mColorCommunicationsText
;
402 // if we've gotten here just return -moz-dialogtext instead
403 idx
= COLOR_WINDOWTEXT
;
405 case ColorID::MozDialogtext
:
406 case ColorID::MozColheadertext
:
407 case ColorID::MozColheaderhovertext
:
408 idx
= COLOR_WINDOWTEXT
;
410 case ColorID::MozButtondefault
:
411 idx
= COLOR_3DDKSHADOW
;
413 case ColorID::MozNativehyperlinktext
:
414 idx
= COLOR_HOTLIGHT
;
416 case ColorID::Marktext
:
418 case ColorID::SpellCheckerUnderline
:
419 aColor
= GetStandinForNativeColor(aID
, aScheme
);
423 res
= NS_ERROR_FAILURE
;
427 aColor
= GetColorForSysColorIndex(idx
);
432 nsresult
nsLookAndFeel::NativeGetInt(IntID aID
, int32_t& aResult
) {
434 nsresult res
= NS_OK
;
437 case IntID::ScrollButtonLeftMouseButtonAction
:
440 case IntID::ScrollButtonMiddleMouseButtonAction
:
441 case IntID::ScrollButtonRightMouseButtonAction
:
444 case IntID::CaretBlinkTime
:
445 aResult
= static_cast<int32_t>(::GetCaretBlinkTime());
447 case IntID::CaretBlinkCount
: {
448 int32_t timeout
= GetSystemParam(SPI_GETCARETTIMEOUT
, 5000);
449 auto blinkTime
= ::GetCaretBlinkTime();
450 if (timeout
<= 0 || blinkTime
<= 0) {
454 // 2 * blinkTime because this integer is a full blink cycle.
455 aResult
= std::ceil(float(timeout
) / (2.0f
* float(blinkTime
)));
459 case IntID::CaretWidth
:
462 case IntID::ShowCaretDuringSelection
:
465 case IntID::SelectTextfieldsOnKeyFocus
:
466 // Select textfield content when focused by kbd
467 // used by EventStateManager::sTextfieldSelectModel
470 case IntID::SubmenuDelay
:
471 // This will default to the Windows' default
473 aResult
= GetSystemParam(SPI_GETMENUSHOWDELAY
, 400);
475 case IntID::TooltipDelay
:
478 case IntID::MenusCanOverlapOSBar
:
479 // we want XUL popups to be able to overlap the task bar.
482 case IntID::DragThresholdX
:
483 // The system metric is the number of pixels at which a drag should
484 // start. Our look and feel metric is the number of pixels you can
485 // move before starting a drag, so subtract 1.
486 aResult
= ::GetSystemMetrics(SM_CXDRAG
) - 1;
488 case IntID::DragThresholdY
:
489 aResult
= ::GetSystemMetrics(SM_CYDRAG
) - 1;
491 case IntID::UseAccessibilityTheme
:
492 // High contrast is a misnomer under Win32 -- any theme can be used with
493 // it, e.g. normal contrast with large fonts, low contrast, etc. The high
494 // contrast flag really means -- use this theme and don't override it.
495 aResult
= nsUXThemeData::IsHighContrastOn();
497 case IntID::ScrollArrowStyle
:
498 aResult
= eScrollArrowStyle_Single
;
500 case IntID::TreeOpenDelay
:
503 case IntID::TreeCloseDelay
:
506 case IntID::TreeLazyScrollDelay
:
509 case IntID::TreeScrollDelay
:
512 case IntID::TreeScrollLinesMax
:
515 case IntID::WindowsClassic
:
516 aResult
= !nsUXThemeData::IsAppThemed();
518 case IntID::WindowsDefaultTheme
:
519 aResult
= nsUXThemeData::IsDefaultWindowTheme();
521 case IntID::DWMCompositor
:
522 aResult
= gfxWindowsPlatform::GetPlatform()->DwmCompositionEnabled();
524 case IntID::WindowsAccentColorInTitlebar
: {
526 if (NS_WARN_IF(!mColorAccent
)) {
531 mDwmKey
= do_CreateInstance("@mozilla.org/windows-registry-key;1");
536 uint32_t colorPrevalence
;
537 nsresult rv
= mDwmKey
->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER
,
538 u
"SOFTWARE\\Microsoft\\Windows\\DWM"_ns
,
539 nsIWindowsRegKey::ACCESS_QUERY_VALUE
);
540 if (NS_WARN_IF(NS_FAILED(rv
))) {
544 // The ColorPrevalence value is set to 1 when the "Show color on title
545 // bar" setting in the Color section of Window's Personalization settings
547 aResult
= (NS_SUCCEEDED(mDwmKey
->ReadIntValue(u
"ColorPrevalence"_ns
,
548 &colorPrevalence
)) &&
549 colorPrevalence
== 1)
555 case IntID::WindowsGlass
:
556 // Aero Glass is only available prior to Windows 8 when DWM is used.
557 aResult
= (gfxWindowsPlatform::GetPlatform()->DwmCompositionEnabled() &&
560 case IntID::AlertNotificationOrigin
:
563 // Get task bar window handle
564 HWND shellWindow
= FindWindowW(L
"Shell_TrayWnd", nullptr);
566 if (shellWindow
!= nullptr) {
567 // Determine position
568 APPBARDATA appBarData
;
569 appBarData
.hWnd
= shellWindow
;
570 appBarData
.cbSize
= sizeof(appBarData
);
571 if (SHAppBarMessage(ABM_GETTASKBARPOS
, &appBarData
)) {
572 // Set alert origin as a bit field - see LookAndFeel.h
573 // 0 represents bottom right, sliding vertically.
574 switch (appBarData
.uEdge
) {
576 aResult
= NS_ALERT_HORIZONTAL
| NS_ALERT_LEFT
;
579 aResult
= NS_ALERT_HORIZONTAL
;
582 aResult
= NS_ALERT_TOP
;
585 // If the task bar is right-to-left,
586 // move the origin to the left
587 if (::GetWindowLong(shellWindow
, GWL_EXSTYLE
) & WS_EX_LAYOUTRTL
)
588 aResult
|= NS_ALERT_LEFT
;
595 case IntID::IMERawInputUnderlineStyle
:
596 case IntID::IMEConvertedTextUnderlineStyle
:
597 aResult
= static_cast<int32_t>(StyleTextDecorationStyle::Dashed
);
599 case IntID::IMESelectedRawTextUnderlineStyle
:
600 case IntID::IMESelectedConvertedTextUnderline
:
601 aResult
= static_cast<int32_t>(StyleTextDecorationStyle::None
);
603 case IntID::SpellCheckerUnderlineStyle
:
604 aResult
= static_cast<int32_t>(StyleTextDecorationStyle::Wavy
);
606 case IntID::ScrollbarButtonAutoRepeatBehavior
:
609 case IntID::SwipeAnimationEnabled
:
610 // Forcibly enable the swipe animation on Windows. It doesn't matter on
611 // platforms where "Drag two fingers to scroll" isn't supported since on
612 // the platforms we will never generate any swipe gesture events.
615 case IntID::UseOverlayScrollbars
:
616 aResult
= WindowsUIUtils::ComputeOverlayScrollbars();
618 case IntID::AllowOverlayScrollbarsOverlap
:
621 case IntID::ScrollbarDisplayOnMouseMove
:
624 case IntID::ScrollbarFadeBeginDelay
:
627 case IntID::ScrollbarFadeDuration
:
630 case IntID::ContextMenuOffsetVertical
:
631 case IntID::ContextMenuOffsetHorizontal
:
634 case IntID::SystemUsesDarkTheme
:
635 res
= SystemWantsDarkTheme(aResult
);
637 case IntID::SystemScrollbarSize
:
638 aResult
= std::max(WinUtils::GetSystemMetricsForDpi(SM_CXVSCROLL
, 96),
639 WinUtils::GetSystemMetricsForDpi(SM_CXHSCROLL
, 96));
641 case IntID::PrefersReducedMotion
: {
643 ::SystemParametersInfoW(SPI_GETCLIENTAREAANIMATION
, 0, &enable
, 0);
647 case IntID::PrefersReducedTransparency
: {
648 // Prefers reduced transparency if the option for "Transparency Effects"
650 aResult
= !WindowsUIUtils::ComputeTransparencyEffects();
653 case IntID::InvertedColors
: {
654 int32_t colorFilter
= SystemColorFilter();
656 // Color filter values
658 // 2: Grayscale inverted
659 aResult
= colorFilter
== 1 || colorFilter
== 2 ? 1 : 0;
662 case IntID::PrimaryPointerCapabilities
: {
663 aResult
= static_cast<int32_t>(
664 widget::WinUtils::GetPrimaryPointerCapabilities());
667 case IntID::AllPointerCapabilities
: {
669 static_cast<int32_t>(widget::WinUtils::GetAllPointerCapabilities());
672 case IntID::TouchDeviceSupportPresent
:
673 aResult
= WinUtils::IsTouchDeviceSupportPresent() ? 1 : 0;
675 case IntID::PanelAnimations
:
680 res
= NS_ERROR_FAILURE
;
685 nsresult
nsLookAndFeel::NativeGetFloat(FloatID aID
, float& aResult
) {
686 nsresult res
= NS_OK
;
689 case FloatID::IMEUnderlineRelativeSize
:
692 case FloatID::SpellCheckerUnderlineRelativeSize
:
695 case FloatID::TextScaleFactor
:
696 aResult
= WindowsUIUtils::ComputeTextScaleFactor();
700 res
= NS_ERROR_FAILURE
;
705 LookAndFeelFont
nsLookAndFeel::GetLookAndFeelFontInternal(
706 const LOGFONTW
& aLogFont
, bool aUseShellDlg
) {
707 LookAndFeelFont result
{};
709 result
.haveFont() = false;
711 // Get scaling factor from physical to logical pixels
713 1.0 / WinUtils::SystemScaleFactor() / LookAndFeel::GetTextScaleFactor();
715 // The lfHeight is in pixels, and it needs to be adjusted for the
716 // device it will be displayed on.
717 // Screens and Printers will differ in DPI
719 // So this accounts for the difference in the DeviceContexts
720 // The pixelScale will typically be 1.0 for the screen
721 // (though larger for hi-dpi screens where the Windows resolution
722 // scale factor is 125% or 150% or even more), and could be
723 // any value when going to a printer, for example pixelScale is
724 // 6.25 when going to a 600dpi printer.
725 float pixelHeight
= -aLogFont
.lfHeight
;
726 if (pixelHeight
< 0) {
727 nsAutoFont
hFont(::CreateFontIndirectW(&aLogFont
));
732 nsAutoHDC
dc(::GetDC(nullptr));
733 HGDIOBJ hObject
= ::SelectObject(dc
, hFont
);
735 ::GetTextMetrics(dc
, &tm
);
736 ::SelectObject(dc
, hObject
);
738 pixelHeight
= tm
.tmAscent
;
741 pixelHeight
*= pixelScale
;
743 // we have problem on Simplified Chinese system because the system
744 // report the default font size is 8 points. but if we use 8, the text
745 // display very ugly. force it to be at 9 points (12 pixels) on that
746 // system (cp936), but leave other sizes alone.
747 if (pixelHeight
< 12 && ::GetACP() == 936) {
751 result
.haveFont() = true;
754 result
.name() = u
"MS Shell Dlg 2"_ns
;
756 result
.name() = aLogFont
.lfFaceName
;
759 result
.size() = pixelHeight
;
760 result
.italic() = !!aLogFont
.lfItalic
;
761 // FIXME: Other weights?
763 ((aLogFont
.lfWeight
== FW_BOLD
) ? FontWeight::BOLD
: FontWeight::NORMAL
)
769 LookAndFeelFont
nsLookAndFeel::GetLookAndFeelFont(LookAndFeel::FontID anID
) {
770 LookAndFeelFont result
{};
772 result
.haveFont() = false;
774 // FontID::Icon is handled differently than the others
775 if (anID
== LookAndFeel::FontID::Icon
) {
777 if (::SystemParametersInfoW(SPI_GETICONTITLELOGFONT
, sizeof(logFont
),
778 (PVOID
)&logFont
, 0)) {
779 result
= GetLookAndFeelFontInternal(logFont
, false);
784 NONCLIENTMETRICSW ncm
;
785 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
786 if (!::SystemParametersInfoW(SPI_GETNONCLIENTMETRICS
, sizeof(ncm
),
792 case LookAndFeel::FontID::Menu
:
793 case LookAndFeel::FontID::MozPullDownMenu
:
794 result
= GetLookAndFeelFontInternal(ncm
.lfMenuFont
, false);
796 case LookAndFeel::FontID::Caption
:
797 result
= GetLookAndFeelFontInternal(ncm
.lfCaptionFont
, false);
799 case LookAndFeel::FontID::SmallCaption
:
800 result
= GetLookAndFeelFontInternal(ncm
.lfSmCaptionFont
, false);
802 case LookAndFeel::FontID::StatusBar
:
803 result
= GetLookAndFeelFontInternal(ncm
.lfStatusFont
, false);
805 case LookAndFeel::FontID::MozButton
:
806 case LookAndFeel::FontID::MozField
:
807 case LookAndFeel::FontID::MozList
:
808 // XXX It's not clear to me whether this is exactly the right
809 // set of LookAndFeel values to map to the dialog font; we may
810 // want to add or remove cases here after reviewing the visual
811 // results under various Windows versions.
812 result
= GetLookAndFeelFontInternal(ncm
.lfMessageFont
, true);
815 result
= GetLookAndFeelFontInternal(ncm
.lfMessageFont
, false);
822 bool nsLookAndFeel::NativeGetFont(LookAndFeel::FontID anID
, nsString
& aFontName
,
823 gfxFontStyle
& aFontStyle
) {
824 LookAndFeelFont font
= GetLookAndFeelFont(anID
);
825 return LookAndFeelFontToStyle(font
, aFontName
, aFontStyle
);
829 char16_t
nsLookAndFeel::GetPasswordCharacterImpl() {
830 #define UNICODE_BLACK_CIRCLE_CHAR 0x25cf
831 return UNICODE_BLACK_CIRCLE_CHAR
;
834 static Maybe
<nscolor
> GetAccentColorText(const Maybe
<nscolor
>& aAccentColor
) {
838 // We want the color that we return for text that will be drawn over
839 // a background that has the accent color to have good contrast with
840 // the accent color. Windows itself uses either white or black text
841 // depending on how light or dark the accent color is. We do the same
842 // here based on the luminance of the accent color with a threshhold
843 // value. This algorithm should match what Windows does. It comes from:
845 // https://docs.microsoft.com/en-us/windows/uwp/style/color
846 float luminance
= (NS_GET_R(*aAccentColor
) * 2 + NS_GET_G(*aAccentColor
) * 5 +
847 NS_GET_B(*aAccentColor
)) /
850 return Some(luminance
<= 128 ? NS_RGB(255, 255, 255) : NS_RGB(0, 0, 0));
853 nscolor
nsLookAndFeel::GetColorForSysColorIndex(int index
) {
854 MOZ_ASSERT(index
>= SYS_COLOR_MIN
&& index
<= SYS_COLOR_MAX
);
855 return mSysColorTable
[index
- SYS_COLOR_MIN
];
858 void nsLookAndFeel::EnsureInit() {
864 mColorAccent
= WindowsUIUtils::GetAccentColor();
865 mColorAccentText
= GetAccentColorText(mColorAccent
);
867 if (nsUXThemeData::IsAppThemed()) {
868 mColorMenuHoverText
=
869 ::GetColorFromTheme(eUXMenu
, MENU_POPUPITEM
, MPI_HOT
, TMT_TEXTCOLOR
);
870 mColorMediaText
= ::GetColorFromTheme(eUXMediaToolbar
, TP_BUTTON
, TS_NORMAL
,
872 mColorCommunicationsText
= ::GetColorFromTheme(
873 eUXCommunicationsToolbar
, TP_BUTTON
, TS_NORMAL
, TMT_TEXTCOLOR
);
876 // Fill out the sys color table.
877 for (int i
= SYS_COLOR_MIN
; i
<= SYS_COLOR_MAX
; ++i
) {
878 mSysColorTable
[i
- SYS_COLOR_MIN
] = [&] {
879 if (auto c
= WindowsUIUtils::GetSystemColor(ColorScheme::Light
, i
)) {
882 DWORD color
= ::GetSysColor(i
);
883 return COLOREF_2_NSRGB(color
);
888 WindowsUIUtils::GetSystemColor(ColorScheme::Dark
, COLOR_HIGHLIGHT
);
890 WindowsUIUtils::GetSystemColor(ColorScheme::Dark
, COLOR_HIGHLIGHTTEXT
);