Skip to content

Commit

Permalink
[win] Add support for dark mode on Windows 11
Browse files Browse the repository at this point in the history
  • Loading branch information
dacap committed Aug 16, 2023
1 parent c182b50 commit 7847847
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 3 deletions.
9 changes: 9 additions & 0 deletions base/win/registry.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// LAF Base Library
// Copyright (c) 2023 Igara Studio S.A.
// Copyright (c) 2017 David Capello
//
// This file is released under the terms of the MIT license.
Expand Down Expand Up @@ -101,6 +102,14 @@ void hkey::close()
}
}

bool hkey::exists(const std::string& name)
{
std::wstring wname = from_utf8(name);
LONG result = RegQueryValueExW(m_hkey, wname.c_str(),
nullptr, nullptr, nullptr, nullptr);
return (result == ERROR_SUCCESS);
}

std::string hkey::string(const std::string& name)
{
if (!m_hkey)
Expand Down
4 changes: 3 additions & 1 deletion base/win/registry.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// LAF Base Library
// Copyright (c) 2021 Igara Studio S.A.
// Copyright (c) 2021-2023 Igara Studio S.A.
// Copyright (c) 2017 David Capello
//
// This file is released under the terms of the MIT license.
Expand Down Expand Up @@ -44,6 +44,8 @@ class hkey {
hkey create(const std::string& subkey);
void close();

bool exists(const std::string& name);

std::string string(const std::string& name);
void string(const std::string& name, const std::string& value);

Expand Down
42 changes: 41 additions & 1 deletion os/win/window.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// LAF OS Library
// Copyright (C) 2018-2022 Igara Studio S.A.
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2012-2018 David Capello
//
// This file is released under the terms of the MIT license.
Expand Down Expand Up @@ -28,6 +28,8 @@
#include "base/string.h"
#include "base/thread.h"
#include "base/win/comptr.h"
#include "base/win/registry.h"
#include "base/win/win32_exception.h"
#include "gfx/border.h"
#include "gfx/region.h"
#include "gfx/size.h"
Expand Down Expand Up @@ -131,6 +133,10 @@ static BOOL CALLBACK log_monitor_info(HMONITOR monitor,
return TRUE;
}

// Keys used to detect if the Windows 11 dark mode is selected.
static constexpr const char* kPersonalizeKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
static constexpr const char* kAppsUseLightThemeValue = "AppsUseLightTheme";

PointerType WindowWin::m_pointerType = PointerType::Unknown;
float WindowWin::m_pressure = 0.0f;
std::vector<PACKET> WindowWin::m_packets;
Expand Down Expand Up @@ -874,6 +880,7 @@ LRESULT WindowWin::wndProc(UINT msg, WPARAM wparam, LPARAM lparam)
}
}

checkDarkModeChange();
notifyFullScreenStateToShell();
break;
}
Expand Down Expand Up @@ -1133,6 +1140,10 @@ LRESULT WindowWin::wndProc(UINT msg, WPARAM wparam, LPARAM lparam)
onEndResizing();
break;

case WM_SETTINGCHANGE:
checkDarkModeChange();
break;

// Mouse and Trackpad Messages

case WM_MOUSEMOVE: {
Expand Down Expand Up @@ -2343,6 +2354,35 @@ void WindowWin::checkColorSpaceChange()
onChangeColorSpace();
}

// We only support the Windows 11 dark mode, detecting it and using
// the correct (dark/light) title bar.
//
// A lot of information and discussion about this can be found here:
// https://github.com/microsoft/WindowsAppSDK/issues/41
void WindowWin::checkDarkModeChange()
{
try {
auto key = base::hkey::current_user().open(kPersonalizeKey,
base::hkey::read);

// We can check if "AppsUseLightTheme" option is 0 which means
// that we have to use the dark theme. Not sure why this is not
// automatic or the default behavior on Windows 11, or configured
// through the manifest for Win32 apps.
if (key.exists(kAppsUseLightThemeValue)) {
BOOL value = (key.dword(kAppsUseLightThemeValue) == 0);
DwmSetWindowAttribute(
m_hwnd, 20, // DWMWA_USE_IMMERSIVE_DARK_MODE,
&value, sizeof(BOOL));
}
}
catch (const base::Win32Exception&) {
// Probably the "Personalize" key doesn't exist because we are on
// Windows 10, so we do nothing, which means: use the light
// theme/current theme/title bar as it is.
}
}

void WindowWin::openWintabCtx()
{
const TabletAPI tabletAPI = system()->tabletAPI();
Expand Down
3 changes: 2 additions & 1 deletion os/win/window.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// LAF OS Library
// Copyright (C) 2018-2021 Igara Studio S.A.
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2012-2018 David Capello
//
// This file is released under the terms of the MIT license.
Expand Down Expand Up @@ -91,6 +91,7 @@ namespace os {
void clearDelayedTouchEvents();
void killTouchTimer();
void checkColorSpaceChange();
void checkDarkModeChange();

void openWintabCtx();
void closeWintabCtx();
Expand Down

0 comments on commit 7847847

Please sign in to comment.