graphics: respect Windows dark mode (#765)

Only affects the caption bar.

Should work for:

- [x] standalone configurator
- [x] dx9 games, including multi-window games like gitadora
- [x] Unity games
This commit is contained in:
bicarus
2026-06-17 11:51:31 -07:00
committed by GitHub
parent 301e15c44d
commit 50fc80a1c3
5 changed files with 61 additions and 0 deletions
+43
View File
@@ -4,6 +4,15 @@
#include "utils.h"
#if !SPICE_XP
#include <dwmapi.h>
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#endif
// older numbering used by Win10 1809..1909
#define DWMWA_USE_IMMERSIVE_DARK_MODE_OLD 19
#endif
const char *inet_ntop(short af, const void *src, char *dst, DWORD size) {
// prepare storage
@@ -124,3 +133,37 @@ void generate_ea_card(char card[17]) {
// terminate and flush
card[16] = 0;
}
void set_window_dark_titlebar(HWND hWnd, bool force_dark) {
#if !SPICE_XP
if (hWnd == nullptr) {
return;
}
// AppsUseLightTheme == 0 means the dark app theme is selected
DWORD light = 1;
if (!force_dark) {
DWORD size = sizeof(light);
HKEY key;
if (RegOpenKeyExW(HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
RegQueryValueExW(key, L"AppsUseLightTheme", nullptr, nullptr,
reinterpret_cast<LPBYTE>(&light), &size);
RegCloseKey(key);
}
}
BOOL dark = (force_dark || light == 0) ? TRUE : FALSE;
// fall back to the older attribute numbering on Win10 1809..1909
if (FAILED(DwmSetWindowAttribute(hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE,
&dark, sizeof(dark)))) {
DwmSetWindowAttribute(hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE_OLD,
&dark, sizeof(dark));
}
#else
(void) hWnd;
(void) force_dark;
#endif
}
+4
View File
@@ -28,6 +28,10 @@ static const char HEX_LOOKUP_UPPERCASE[16] = {
const char *inet_ntop(short af, const void *src, char *dst, DWORD size);
// make a window's native title bar follow the Windows dark/light app theme.
// pass force_dark=true to always use the dark caption regardless of the system theme.
void set_window_dark_titlebar(HWND hWnd, bool force_dark = false);
static inline bool string_begins_with(const std::string &s, const std::string &prefix) {
return s.compare(0, prefix.size(), prefix) == 0;
}