diff --git a/docs/window.dox b/docs/window.dox index 3cec6358..cbb02734 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -240,7 +240,7 @@ focus when @ref glfwShowWindow is called. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. @anchor GLFW_SCALE_TO_MONITOR -__GLFW_SCALE_TO_MONITOR__ specified whether the window content area should be +__GLFW_SCALE_TO_MONITOR__ specifies whether the window content area should be resized based on the [monitor content scale](@ref monitor_scale) of any monitor it is placed on. This includes the initial placement when the window is created. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. @@ -249,6 +249,11 @@ This hint only has an effect on platforms where screen coordinates and pixels always map 1:1 such as Windows and X11. On platforms like macOS the resolution of the framebuffer is changed independently of the window size. +@anchor GLFW_DARK_THEME +__GLFW_DARK_THEME__ specifies whether the window should use dark theme or not. +Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This hint only has effect +on windows operating system. + @anchor GLFW_MOUSE_PASSTHROUGH_hint __GLFW_MOUSE_PASSTHROUGH__ specifies whether the window is transparent to mouse input, letting any mouse events pass through to whatever window is behind it. diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 58b395cd..1d76eef4 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1099,6 +1099,11 @@ extern "C" { /*! @brief macOS specific * [window hint](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint). */ +#define GLFW_DARK_THEME 0x0002200D +/*! @brief windows specific + * + * Allows specifying whether dark theme should be used. + */ #define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 /*! @brief macOS specific * [window hint](@ref GLFW_COCOA_FRAME_NAME_hint). diff --git a/src/internal.h b/src/internal.h index fe0369aa..3cd8ca03 100644 --- a/src/internal.h +++ b/src/internal.h @@ -408,6 +408,7 @@ struct _GLFWwndconfig GLFWbool focusOnShow; GLFWbool mousePassthrough; GLFWbool scaleToMonitor; + GLFWbool darkTheme; struct { GLFWbool retina; char frameName[256]; diff --git a/src/win32_init.c b/src/win32_init.c index ef2615f1..402a56ef 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -151,6 +151,8 @@ static GLFWbool loadLibraries(void) _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow"); _glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor) _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor"); + _glfw.win32.dwmapi.DwmSetWindowAttribute = (PFN_DwmSetWindowAttribute) + _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmSetWindowAttribute"); } _glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll"); @@ -570,6 +572,14 @@ void _glfwUpdateKeyNamesWin32(void) } } +void _glfwSetWindowTheme(BOOL dark, HWND hwnd) +{ +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + _glfw.win32.dwmapi.DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &dark, sizeof(dark)); +} + // Replacement for IsWindowsVersionOrGreater, as we cannot rely on the // application having a correct embedded manifest // diff --git a/src/win32_platform.h b/src/win32_platform.h index 82b34bb9..edafebc5 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -299,8 +299,9 @@ typedef int (WINAPI * PFN_GetSystemMetricsForDpi)(int,UINT); // dwmapi.dll function pointer typedefs typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*); typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID); -typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*); +typedef HRESULT (WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*); typedef HRESULT (WINAPI * PFN_DwmGetColorizationColor)(DWORD*,BOOL*); +typedef HRESULT (WINAPI * PFN_DwmSetWindowAttribute)(HWND, DWORD, LPCVOID, DWORD); #define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled #define DwmFlush _glfw.win32.dwmapi.Flush #define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow @@ -487,6 +488,7 @@ typedef struct _GLFWlibraryWin32 PFN_DwmFlush Flush; PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow; PFN_DwmGetColorizationColor GetColorizationColor; + PFN_DwmSetWindowAttribute DwmSetWindowAttribute; } dwmapi; struct { @@ -533,6 +535,7 @@ BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp); BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build); void _glfwInputErrorWin32(int error, const char* description); void _glfwUpdateKeyNamesWin32(void); +void _glfwSetWindowTheme(BOOL dark, HWND hwnd); void _glfwPollMonitorsWin32(void); void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired); diff --git a/src/win32_window.c b/src/win32_window.c index 676640bf..d093d269 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1344,6 +1344,7 @@ static int createNativeWindow(_GLFWwindow* window, _glfw.win32.instance, (LPVOID) wndconfig); + _glfwSetWindowTheme(wndconfig->darkTheme, window->win32.handle); _glfw_free(wideTitle); if (!window->win32.handle) diff --git a/src/window.c b/src/window.c index 1c8519ff..edb05803 100644 --- a/src/window.c +++ b/src/window.c @@ -388,6 +388,9 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_SCALE_TO_MONITOR: _glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE; return; + case GLFW_DARK_THEME: + _glfw.hints.window.darkTheme = value ? GLFW_TRUE : GLFW_FALSE; + return; case GLFW_CENTER_CURSOR: _glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE; return;