You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-22 15:06:45 +00:00
Add support for system dark mode and accent color detection (macOS and Windows). Add support for dark mode title bar on Windows.
This commit is contained in:
@@ -37,6 +37,11 @@
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
#include <avrt.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
|
||||
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
||||
#endif
|
||||
|
||||
#if defined(GLES3_ENABLED)
|
||||
#include "drivers/gles3/rasterizer_gles3.h"
|
||||
@@ -2391,6 +2396,20 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
case WM_PAINT: {
|
||||
Main::force_redraw();
|
||||
} break;
|
||||
case WM_SETTINGCHANGE: {
|
||||
if (lParam && CompareStringOrdinal(reinterpret_cast<LPCWCH>(lParam), -1, L"ImmersiveColorSet", -1, true) == CSTR_EQUAL) {
|
||||
if (is_dark_mode_supported()) {
|
||||
BOOL value = is_dark_mode();
|
||||
::DwmSetWindowAttribute(windows[window_id].hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case WM_THEMECHANGED: {
|
||||
if (is_dark_mode_supported()) {
|
||||
BOOL value = is_dark_mode();
|
||||
::DwmSetWindowAttribute(windows[window_id].hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
|
||||
}
|
||||
} break;
|
||||
case WM_SYSCOMMAND: // Intercept system commands.
|
||||
{
|
||||
switch (wParam) // Check system calls.
|
||||
@@ -3501,6 +3520,11 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
|
||||
wd.pre_fs_valid = true;
|
||||
}
|
||||
|
||||
if (is_dark_mode_supported()) {
|
||||
BOOL value = is_dark_mode();
|
||||
::DwmSetWindowAttribute(wd.hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
|
||||
}
|
||||
|
||||
#ifdef VULKAN_ENABLED
|
||||
if (context_vulkan) {
|
||||
if (context_vulkan->window_create(id, p_vsync_mode, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) == -1) {
|
||||
@@ -3587,6 +3611,14 @@ WTInfoPtr DisplayServerWindows::wintab_WTInfo = nullptr;
|
||||
WTPacketPtr DisplayServerWindows::wintab_WTPacket = nullptr;
|
||||
WTEnablePtr DisplayServerWindows::wintab_WTEnable = nullptr;
|
||||
|
||||
// UXTheme API.
|
||||
bool DisplayServerWindows::ux_theme_available = false;
|
||||
IsDarkModeAllowedForAppPtr DisplayServerWindows::IsDarkModeAllowedForApp = nullptr;
|
||||
ShouldAppsUseDarkModePtr DisplayServerWindows::ShouldAppsUseDarkMode = nullptr;
|
||||
GetImmersiveColorFromColorSetExPtr DisplayServerWindows::GetImmersiveColorFromColorSetEx = nullptr;
|
||||
GetImmersiveColorTypeFromNamePtr DisplayServerWindows::GetImmersiveColorTypeFromName = nullptr;
|
||||
GetImmersiveUserColorSetPreferencePtr DisplayServerWindows::GetImmersiveUserColorSetPreference = nullptr;
|
||||
|
||||
// Windows Ink API.
|
||||
bool DisplayServerWindows::winink_available = false;
|
||||
GetPointerTypePtr DisplayServerWindows::win8p_GetPointerType = nullptr;
|
||||
@@ -3598,6 +3630,23 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS {
|
||||
SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||||
} SHC_PROCESS_DPI_AWARENESS;
|
||||
|
||||
bool DisplayServerWindows::is_dark_mode_supported() const {
|
||||
return ux_theme_available && IsDarkModeAllowedForApp();
|
||||
}
|
||||
|
||||
bool DisplayServerWindows::is_dark_mode() const {
|
||||
return ux_theme_available && ShouldAppsUseDarkMode();
|
||||
}
|
||||
|
||||
Color DisplayServerWindows::get_accent_color() const {
|
||||
if (!ux_theme_available) {
|
||||
return Color(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
int argb = GetImmersiveColorFromColorSetEx((UINT)GetImmersiveUserColorSetPreference(false, false), GetImmersiveColorTypeFromName(L"ImmersiveSystemAccent"), false, 0);
|
||||
return Color((argb & 0xFF) / 255.f, ((argb & 0xFF00) >> 8) / 255.f, ((argb & 0xFF0000) >> 16) / 255.f, ((argb & 0xFF000000) >> 24) / 255.f);
|
||||
}
|
||||
|
||||
int DisplayServerWindows::tablet_get_driver_count() const {
|
||||
return tablet_drivers.size();
|
||||
}
|
||||
@@ -3655,6 +3704,18 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
|
||||
// Enforce default keep screen on value.
|
||||
screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
|
||||
|
||||
// Load UXTheme
|
||||
HMODULE ux_theme_lib = LoadLibraryW(L"uxtheme.dll");
|
||||
if (ux_theme_lib) {
|
||||
IsDarkModeAllowedForApp = (IsDarkModeAllowedForAppPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(136));
|
||||
ShouldAppsUseDarkMode = (ShouldAppsUseDarkModePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(132));
|
||||
GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(95));
|
||||
GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(96));
|
||||
GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(98));
|
||||
|
||||
ux_theme_available = IsDarkModeAllowedForApp && ShouldAppsUseDarkMode && GetImmersiveColorFromColorSetEx && GetImmersiveColorTypeFromName && GetImmersiveUserColorSetPreference;
|
||||
}
|
||||
|
||||
// Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink.
|
||||
HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll");
|
||||
if (wintab_lib) {
|
||||
|
||||
Reference in New Issue
Block a user