Bug 1368808 - Honor the system light/dark mode setting on Windows 10. r?jimm
MozReview-Commit-ID: 3bzhX9bfR4s
--- a/widget/windows/nsLookAndFeel.cpp
+++ b/widget/windows/nsLookAndFeel.cpp
@@ -57,16 +57,48 @@ static nsresult GetColorFromTheme(nsUXTh
}
static int32_t GetSystemParam(long flag, int32_t def)
{
DWORD value;
return ::SystemParametersInfo(flag, 0, &value, 0) ? value : def;
}
+static nsresult
+SystemWantsDarkTheme(int32_t& darkThemeEnabled)
+{
+ if (!IsWin10OrLater()) {
+ darkThemeEnabled = 0;
+ return NS_OK;
+ }
+
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIWindowsRegKey> personalizeKey =
+ do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ rv = personalizeKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
+ NS_LITERAL_STRING("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"),
+ nsIWindowsRegKey::ACCESS_QUERY_VALUE);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ uint32_t lightThemeEnabled;
+ rv = personalizeKey->ReadIntValue(NS_LITERAL_STRING("AppsUseLightTheme"),
+ &lightThemeEnabled);
+ if (NS_SUCCEEDED(rv)) {
+ darkThemeEnabled = !lightThemeEnabled;
+ }
+
+ return rv;
+}
+
nsLookAndFeel::nsLookAndFeel()
: nsXPLookAndFeel()
, mUseAccessibilityTheme(0)
, mUseDefaultTheme(0)
, mNativeThemeId(eWindowsTheme_Generic)
, mCaretBlinkTime(-1)
, mHasColorMenuHoverText(false)
, mHasColorAccent(false)
@@ -568,16 +600,19 @@ nsLookAndFeel::GetIntImpl(IntID aID, int
break;
case eIntID_ScrollbarFadeDuration:
aResult = 350;
break;
case eIntID_ContextMenuOffsetVertical:
case eIntID_ContextMenuOffsetHorizontal:
aResult = 2;
break;
+ case eIntID_SystemUsesDarkTheme:
+ res = SystemWantsDarkTheme(aResult);
+ break;
default:
aResult = 0;
res = NS_ERROR_FAILURE;
}
return res;
}
nsresult
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -5316,16 +5316,25 @@ nsWindow::ProcessMessage(UINT msg, WPARA
if (wParam == SPI_SETKEYBOARDDELAY) {
// CaretBlinkTime is cached in nsLookAndFeel
NotifyThemeChanged();
break;
}
if (lParam) {
auto lParamString = reinterpret_cast<const wchar_t*>(lParam);
if (!wcscmp(lParamString, L"ImmersiveColorSet")) {
+ // This might be the Win10 dark mode setting; only way to tell
+ // is to actually force a theme change, since we don't get
+ // WM_THEMECHANGED or WM_SYSCOLORCHANGE when that happens.
+ if (IsWin10OrLater() && mWindowType == eWindowType_toplevel) {
+ nsIPresShell* presShell = mWidgetListener->GetPresShell();
+ if (presShell) {
+ presShell->ThemeChanged();
+ }
+ }
// WM_SYSCOLORCHANGE is not dispatched for accent color changes
OnSysColorChanged();
break;
}
if (IsWin10OrLater() && mWindowType == eWindowType_invisible) {
if (!wcscmp(lParamString, L"UserInteractionMode")) {
nsCOMPtr<nsIWindowsUIUtils> uiUtils(do_GetService("@mozilla.org/windows-ui-utils;1"));
if (uiUtils) {