From f843f02860d8acd709fe89bfa891892d907de81a Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 19 Jul 2017 13:24:55 +0200 Subject: Add -moz-win-accentcolor(text) #31 points 1 and 2 --- widget/LookAndFeel.h | 4 ++ widget/nsXPLookAndFeel.cpp | 5 +++ widget/windows/nsLookAndFeel.cpp | 82 ++++++++++++++++++++++++++++++++++++++++ widget/windows/nsLookAndFeel.h | 19 ++++++++++ widget/windows/nsWindow.cpp | 17 ++++++--- 5 files changed, 122 insertions(+), 5 deletions(-) (limited to 'widget') diff --git a/widget/LookAndFeel.h b/widget/LookAndFeel.h index b7a05748e..8d510f69f 100644 --- a/widget/LookAndFeel.h +++ b/widget/LookAndFeel.h @@ -158,6 +158,10 @@ public: // vista rebars + // accent color for title bar + eColorID__moz_win_accentcolor, + // color from drawing text over the accent color + eColorID__moz_win_accentcolortext, // media rebar text eColorID__moz_win_mediatext, // communications rebar text diff --git a/widget/nsXPLookAndFeel.cpp b/widget/nsXPLookAndFeel.cpp index 54c619829..28e1c2c5a 100644 --- a/widget/nsXPLookAndFeel.cpp +++ b/widget/nsXPLookAndFeel.cpp @@ -647,6 +647,11 @@ nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID) result = NS_RGB(0x3F, 0x3F, 0x3F); break; case eColorID__moz_mac_secondaryhighlight: result = NS_RGB(0xD4, 0xD4, 0xD4); break; + case eColorID__moz_win_accentcolor: + // Seems to be the default color (hardcoded because of bug 1065998) + result = NS_RGB(0x9E, 0x9E, 0x9E); break; + case eColorID__moz_win_accentcolortext: + result = NS_RGB(0x00, 0x00, 0x00); break; case eColorID__moz_win_mediatext: result = NS_RGB(0xFF, 0xFF, 0xFF); break; case eColorID__moz_win_communicationstext: diff --git a/widget/windows/nsLookAndFeel.cpp b/widget/windows/nsLookAndFeel.cpp index 60e351323..63af65306 100644 --- a/widget/windows/nsLookAndFeel.cpp +++ b/widget/windows/nsLookAndFeel.cpp @@ -267,6 +267,23 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor) case eColorID__moz_cellhighlight: idx = COLOR_3DFACE; break; + case eColorID__moz_win_accentcolor: + res = GetAccentColor(aColor); + if (NS_SUCCEEDED(res)) { + return res; + } + NS_WARNING("Using fallback for accent color - UI code failed to use the " + "-moz-windows-accent-color-applies media query properly"); + // Seems to be the default color (hardcoded because of bug 1065998) + aColor = NS_RGB(158, 158, 158); + return NS_OK; + case eColorID__moz_win_accentcolortext: + res = GetAccentColorText(aColor); + if (NS_SUCCEEDED(res)) { + return res; + } + aColor = NS_RGB(0, 0, 0); + return NS_OK; case eColorID__moz_win_mediatext: if (IsVistaOrLater() && IsAppThemed()) { res = ::GetColorFromTheme(eUXMediaToolbar, @@ -705,3 +722,68 @@ nsLookAndFeel::SetIntCacheImpl(const nsTArray& aLookAndFeelIntCa } } +/* static */ nsresult +nsLookAndFeel::GetAccentColor(nscolor& aColor) +{ + nsresult rv; + + if (!mDwmKey) { + mDwmKey = do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + } + + rv = mDwmKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, + NS_LITERAL_STRING("SOFTWARE\\Microsoft\\Windows\\DWM"), + nsIWindowsRegKey::ACCESS_QUERY_VALUE); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + // The ColorPrevalence value is set to 1 when the "Show color on title bar" + // setting in the Color section of Window's Personalization settings is + // turned on. + uint32_t accentColor, colorPrevalence; + if (NS_SUCCEEDED(mDwmKey->ReadIntValue(NS_LITERAL_STRING("AccentColor"), &accentColor)) && + NS_SUCCEEDED(mDwmKey->ReadIntValue(NS_LITERAL_STRING("ColorPrevalence"), &colorPrevalence)) && + colorPrevalence == 1) { + // The order of the color components in the DWORD stored in the registry + // happens to be the same order as we store the components in nscolor + // so we can just assign directly here. + aColor = accentColor; + rv = NS_OK; + } else { + rv = NS_ERROR_NOT_AVAILABLE; + } + + mDwmKey->Close(); + + return rv; +} + +/* static */ nsresult +nsLookAndFeel::GetAccentColorText(nscolor& aColor) +{ + nscolor accentColor; + nsresult rv = GetAccentColor(accentColor); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + // We want the color that we return for text that will be drawn over + // a background that has the accent color to have good contrast with + // the accent color. Windows itself uses either white or black text + // depending on how light or dark the accent color is. We do the same + // here based on the luminance of the accent color with a threshhold + // value and formula that are specified in the UWP guidelines. + // See: https://docs.microsoft.com/en-us/windows/uwp/style/color + + float luminance = (NS_GET_R(accentColor) * 2 + + NS_GET_G(accentColor) * 5 + + NS_GET_B(accentColor)) / 8; + + aColor = (luminance <= 128) ? NS_RGB(255, 255, 255) : NS_RGB(0, 0, 0); + + return NS_OK; +} diff --git a/widget/windows/nsLookAndFeel.h b/widget/windows/nsLookAndFeel.h index bc2d158b6..29b6f4b78 100644 --- a/widget/windows/nsLookAndFeel.h +++ b/widget/windows/nsLookAndFeel.h @@ -6,6 +6,7 @@ #ifndef __nsLookAndFeel #define __nsLookAndFeel #include "nsXPLookAndFeel.h" +#include "nsIWindowsRegKey.h" /* * Gesture System Metrics @@ -59,7 +60,25 @@ public: virtual void SetIntCacheImpl(const nsTArray& aLookAndFeelIntCache); private: + /** + * Fetches the Windows accent color from the Windows settings if + * the accent color is set to apply to the title bar, otherwise + * returns an error code. + */ + nsresult GetAccentColor(nscolor& aColor); + + /** + * If the Windows accent color from the Windows settings is set + * to apply to the title bar, this computes the color that should + * be used for text that is to be written over a background that has + * the accent color. Otherwise, (if the accent color should not + * apply to the title bar) this returns an error code. + */ + nsresult GetAccentColorText(nscolor& aColor); + int32_t mUseAccessibilityTheme; + + nsCOMPtr mDwmKey; }; #endif diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 2172f2aa0..dd4f359f7 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -5084,12 +5084,19 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, case WM_SETTINGCHANGE: { - if (IsWin10OrLater() && mWindowType == eWindowType_invisible && lParam) { + if (lParam) { auto lParamString = reinterpret_cast(lParam); - if (!wcscmp(lParamString, L"UserInteractionMode")) { - nsCOMPtr uiUtils(do_GetService("@mozilla.org/windows-ui-utils;1")); - if (uiUtils) { - uiUtils->UpdateTabletModeState(); + if (!wcscmp(lParamString, L"ImmersiveColorSet")) { + // WM_SYSCOLORCHANGE is not dispatched for accent color changes + OnSysColorChanged(); + break; + } + if (IsWin10OrLater() && mWindowType == eWindowType_invisible) { + if (!wcscmp(lParamString, L"UserInteractionMode")) { + nsCOMPtr uiUtils(do_GetService("@mozilla.org/windows-ui-utils;1")); + if (uiUtils) { + uiUtils->UpdateTabletModeState(); + } } } } -- cgit v1.2.3