Commit 63e92830 authored by Robert Liao's avatar Robert Liao Committed by Commit Bot

Wire Up Windows Dark Mode to NativeThemeWin

The Dark/Light mode toggle in System Settings appears to be intended
for UWP apps, so this change needs to be slightly more creative about
checking this state.

This change checks and monitors AppsUseLightTheme in HKCU's theme area,
which is not an API guarantee. Future versions of Windows could change
the way this is persisted and subsequently break this change.

BUG=838670

Change-Id: Ic84341ae69e2bb9cd988f9bea027052033c66360
Reviewed-on: https://chromium-review.googlesource.com/c/1429963Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Commit-Queue: Robert Liao <robliao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#625331}
parent 08832e65
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
#include <vsstyle.h> #include <vsstyle.h>
#include <vssym32.h> #include <vssym32.h>
#include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/feature_list.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/win/scoped_gdi_object.h" #include "base/win/scoped_gdi_object.h"
...@@ -28,6 +30,7 @@ ...@@ -28,6 +30,7 @@
#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkShader.h" #include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches.h"
#include "ui/display/win/screen_win.h" #include "ui/display/win/screen_win.h"
#include "ui/gfx/color_palette.h" #include "ui/gfx/color_palette.h"
...@@ -253,6 +256,19 @@ NativeThemeWin::NativeThemeWin() ...@@ -253,6 +256,19 @@ NativeThemeWin::NativeThemeWin()
close_theme_ = reinterpret_cast<CloseThemeDataPtr>( close_theme_ = reinterpret_cast<CloseThemeDataPtr>(
GetProcAddress(theme_dll_, "CloseThemeData")); GetProcAddress(theme_dll_, "CloseThemeData"));
} }
if (base::FeatureList::IsEnabled(features::kDarkMode)) {
// Dark Mode currently targets UWP apps, which means Win32 apps need to use
// alternate, less reliable means of detecting the state. The following
// can break in future Windows versions.
bool key_open_succeeded =
hkcu_themes_regkey_.Open(
HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\"
L"Themes\\Personalize",
KEY_READ | KEY_NOTIFY) == ERROR_SUCCESS;
if (key_open_succeeded)
RegisterThemeRegkeyObserver();
}
memset(theme_handles_, 0, sizeof(theme_handles_)); memset(theme_handles_, 0, sizeof(theme_handles_));
// Initialize the cached system colors. // Initialize the cached system colors.
...@@ -562,6 +578,17 @@ bool NativeThemeWin::UsesHighContrastColors() const { ...@@ -562,6 +578,17 @@ bool NativeThemeWin::UsesHighContrastColors() const {
return force_enabled || IsUsingHighContrastThemeInternal(); return force_enabled || IsUsingHighContrastThemeInternal();
} }
bool NativeThemeWin::SystemDarkModeEnabled() const {
bool fDarkModeEnabled = false;
if (hkcu_themes_regkey_.Valid()) {
DWORD apps_use_light_theme = 1;
hkcu_themes_regkey_.ReadValueDW(L"AppsUseLightTheme",
&apps_use_light_theme);
fDarkModeEnabled = (apps_use_light_theme == 0);
}
return fDarkModeEnabled || NativeTheme::SystemDarkModeEnabled();
}
void NativeThemeWin::PaintIndirect(cc::PaintCanvas* destination_canvas, void NativeThemeWin::PaintIndirect(cc::PaintCanvas* destination_canvas,
Part part, Part part,
State state, State state,
...@@ -1890,4 +1917,16 @@ HANDLE NativeThemeWin::GetThemeHandle(ThemeName theme_name) const { ...@@ -1890,4 +1917,16 @@ HANDLE NativeThemeWin::GetThemeHandle(ThemeName theme_name) const {
return handle; return handle;
} }
void NativeThemeWin::RegisterThemeRegkeyObserver() {
DCHECK(hkcu_themes_regkey_.Valid());
hkcu_themes_regkey_.StartWatching(base::BindRepeating(
[](NativeThemeWin* native_theme) {
native_theme->NotifyObservers();
// RegKey::StartWatching only provides one notification. Reregistration
// is required to get future notifications.
native_theme->RegisterThemeRegkeyObserver();
},
base::Unretained(this)));
}
} // namespace ui } // namespace ui
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/win/registry.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#include "ui/gfx/sys_color_change_listener.h" #include "ui/gfx/sys_color_change_listener.h"
...@@ -80,6 +81,7 @@ class NATIVE_THEME_EXPORT NativeThemeWin : public NativeTheme, ...@@ -80,6 +81,7 @@ class NATIVE_THEME_EXPORT NativeThemeWin : public NativeTheme,
gfx::Size GetNinePatchCanvasSize(Part part) const override; gfx::Size GetNinePatchCanvasSize(Part part) const override;
gfx::Rect GetNinePatchAperture(Part part) const override; gfx::Rect GetNinePatchAperture(Part part) const override;
bool UsesHighContrastColors() const override; bool UsesHighContrastColors() const override;
bool SystemDarkModeEnabled() const override;
protected: protected:
friend class NativeTheme; friend class NativeTheme;
...@@ -260,6 +262,8 @@ class NATIVE_THEME_EXPORT NativeThemeWin : public NativeTheme, ...@@ -260,6 +262,8 @@ class NATIVE_THEME_EXPORT NativeThemeWin : public NativeTheme,
// Returns a handle to the theme data. // Returns a handle to the theme data.
HANDLE GetThemeHandle(ThemeName theme_name) const; HANDLE GetThemeHandle(ThemeName theme_name) const;
void RegisterThemeRegkeyObserver();
typedef HRESULT (WINAPI* DrawThemeBackgroundPtr)(HANDLE theme, typedef HRESULT (WINAPI* DrawThemeBackgroundPtr)(HANDLE theme,
HDC hdc, HDC hdc,
int part_id, int part_id,
...@@ -314,6 +318,9 @@ class NATIVE_THEME_EXPORT NativeThemeWin : public NativeTheme, ...@@ -314,6 +318,9 @@ class NATIVE_THEME_EXPORT NativeThemeWin : public NativeTheme,
// Handle to uxtheme.dll. // Handle to uxtheme.dll.
HMODULE theme_dll_; HMODULE theme_dll_;
// Dark Mode registry key.
base::win::RegKey hkcu_themes_regkey_;
// A cache of open theme handles. // A cache of open theme handles.
mutable HANDLE theme_handles_[LAST]; mutable HANDLE theme_handles_[LAST];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment