Bug 1368808 - Honor the system light/dark mode setting on Windows 10. r?jimm draft
authorMatt Howell <mhowell@mozilla.com>
Sun, 08 Jul 2018 17:32:52 -0700
changeset 815522 982f2e5aae5d57b3fc095d48fabe5370686f27e0
parent 815500 b0111088608390a0ab4baa3727e5e6fb06cd9f31
push id115525
push userbmo:mhowell@mozilla.com
push dateMon, 09 Jul 2018 03:13:20 +0000
reviewersjimm
bugs1368808
milestone63.0a1
Bug 1368808 - Honor the system light/dark mode setting on Windows 10. r?jimm MozReview-Commit-ID: 3bzhX9bfR4s
widget/windows/nsLookAndFeel.cpp
widget/windows/nsWindow.cpp
--- 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) {