From de257c27ae5455d042c7519c50062475615406ea Mon Sep 17 00:00:00 2001 From: Santiago Date: Sun, 6 Aug 2023 13:35:05 +0200 Subject: [PATCH 1/5] Add dark theme flag --- docs/window.dox | 7 ++++++- include/GLFW/glfw3.h | 5 +++++ src/internal.h | 1 + src/win32_init.c | 10 ++++++++++ src/win32_platform.h | 5 ++++- src/win32_window.c | 1 + src/window.c | 3 +++ 7 files changed, 30 insertions(+), 2 deletions(-) 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; From a8d1a4d44db81be0bc0f432e16c9528e93cfeacc Mon Sep 17 00:00:00 2001 From: Santiago Date: Sun, 6 Aug 2023 14:22:01 +0200 Subject: [PATCH 2/5] Add premake file --- premake5.lua | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 premake5.lua diff --git a/premake5.lua b/premake5.lua new file mode 100644 index 00000000..2b9c80c2 --- /dev/null +++ b/premake5.lua @@ -0,0 +1,106 @@ +project "GLFW" + kind "StaticLib" + language "C" + + targetdir ("bin/" .. outputdir .. "/%{prj.name}") + objdir ("bin-int/" .. outputdir .. "/%{prj.name}") + + files + { + "include/GLFW/glfw3.h", + "include/GLFW/glfw3native.h", + "src/glfw_config.h", + "src/context.c", + "src/init.c", + "src/input.c", + "src/monitor.c", + + "src/null_init.c", + "src/null_joystick.c", + "src/null_monitor.c", + "src/null_window.c", + + "src/platform.c", + "src/vulkan.c", + "src/window.c" + } + filter "system:linux" + pic "On" + + systemversion "latest" + staticruntime "On" + + files + { + "src/x11_init.c", + "src/x11_monitor.c", + "src/x11_window.c", + "src/xkb_unicode.c", + "src/posix_module.c", + "src/posix_time.c", + "src/posix_thread.c", + "src/posix_module.c", + "src/glx_context.c", + "src/egl_context.c", + "src/osmesa_context.c", + "src/linux_joystick.c" + } + + defines + { + "_GLFW_X11" + } + + filter "system:macosx" + pic "On" + + files + { + "src/cocoa_init.m", + "src/cocoa_monitor.m", + "src/cocoa_window.m", + "src/cocoa_joystick.m", + "src/cocoa_time.c", + "src/nsgl_context.m", + "src/posix_thread.c", + "src/posix_module.c", + "src/osmesa_context.c", + "src/egl_context.c" + } + + defines + { + "_GLFW_COCOA" + } + + filter "system:windows" + systemversion "latest" + staticruntime "On" + + files + { + "src/win32_init.c", + "src/win32_joystick.c", + "src/win32_module.c", + "src/win32_monitor.c", + "src/win32_time.c", + "src/win32_thread.c", + "src/win32_window.c", + "src/wgl_context.c", + "src/egl_context.c", + "src/osmesa_context.c" + } + + defines + { + "_GLFW_WIN32", + "_CRT_SECURE_NO_WARNINGS" + } + + filter "configurations:Debug" + runtime "Debug" + symbols "on" + + filter "configurations:Release" + runtime "Release" + optimize "on" From 6ee3153f9c876776c72512ce27cbe59134c64cab Mon Sep 17 00:00:00 2001 From: Santiago Date: Sun, 6 Aug 2023 20:57:29 +0200 Subject: [PATCH 3/5] Change dark theme flag to light theme flag, so default is dark --- docs/window.dox | 4 ++-- include/GLFW/glfw3.h | 4 ++-- src/internal.h | 2 +- src/win32_window.c | 2 +- src/window.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/window.dox b/docs/window.dox index cbb02734..ff1cd225 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -249,8 +249,8 @@ 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. +@anchor GLFW_LIGHT_THEME +__GLFW_LIGHT_THEME__ specifies whether the window should use light theme or not. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This hint only has effect on windows operating system. diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 1d76eef4..39bc17f4 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1099,10 +1099,10 @@ extern "C" { /*! @brief macOS specific * [window hint](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint). */ -#define GLFW_DARK_THEME 0x0002200D +#define GLFW_LIGHT_THEME 0x0002200D /*! @brief windows specific * - * Allows specifying whether dark theme should be used. + * Allows specifying whether light theme should be used. */ #define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 /*! @brief macOS specific diff --git a/src/internal.h b/src/internal.h index 3cd8ca03..98c889a3 100644 --- a/src/internal.h +++ b/src/internal.h @@ -408,7 +408,7 @@ struct _GLFWwndconfig GLFWbool focusOnShow; GLFWbool mousePassthrough; GLFWbool scaleToMonitor; - GLFWbool darkTheme; + GLFWbool lightTheme; struct { GLFWbool retina; char frameName[256]; diff --git a/src/win32_window.c b/src/win32_window.c index d093d269..f6a8b0b7 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1344,7 +1344,7 @@ static int createNativeWindow(_GLFWwindow* window, _glfw.win32.instance, (LPVOID) wndconfig); - _glfwSetWindowTheme(wndconfig->darkTheme, window->win32.handle); + _glfwSetWindowTheme(!(wndconfig->lightTheme), window->win32.handle); _glfw_free(wideTitle); if (!window->win32.handle) diff --git a/src/window.c b/src/window.c index edb05803..c601bee0 100644 --- a/src/window.c +++ b/src/window.c @@ -388,8 +388,8 @@ 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; + case GLFW_LIGHT_THEME: + _glfw.hints.window.lightTheme = value ? GLFW_TRUE : GLFW_FALSE; return; case GLFW_CENTER_CURSOR: _glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE; From d63766c99f670db43a788d4b95cf1fde2fd3477d Mon Sep 17 00:00:00 2001 From: Santiago Date: Mon, 7 Aug 2023 19:55:48 +0200 Subject: [PATCH 4/5] Better window theme handling using windows registry --- docs/window.dox | 6 +++--- include/GLFW/glfw3.h | 8 ++++++-- src/internal.h | 2 +- src/win32_window.c | 30 +++++++++++++++++++++++++++++- src/window.c | 4 ++-- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/docs/window.dox b/docs/window.dox index ff1cd225..405cca5a 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -249,9 +249,9 @@ 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_LIGHT_THEME -__GLFW_LIGHT_THEME__ specifies whether the window should use light theme or not. -Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This hint only has effect +@anchor GLFW_THEME +__GLFW_THEME__ specifies whether the window should use light theme or not. +Possible values are `GLFW_THEME_AUTO`, `GLFW_THEME_DARK`, and `GLFW_THEME_LIGHT`. This hint only has effect on windows operating system. @anchor GLFW_MOUSE_PASSTHROUGH_hint diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 39bc17f4..b1e5cf2b 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1099,10 +1099,10 @@ extern "C" { /*! @brief macOS specific * [window hint](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint). */ -#define GLFW_LIGHT_THEME 0x0002200D +#define GLFW_THEME 0x0002200D /*! @brief windows specific * - * Allows specifying whether light theme should be used. + * Allows specifying whether light or dark theme should be used. */ #define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 /*! @brief macOS specific @@ -1174,6 +1174,10 @@ extern "C" { #define GLFW_ANY_POSITION 0x80000000 +#define GLFW_THEME_AUTO 0x00000000 +#define GLFW_THEME_DARK 0x00000001 +#define GLFW_THEME_LIGHT 0x00000002 + /*! @defgroup shapes Standard cursor shapes * @brief Standard system cursor shapes. * diff --git a/src/internal.h b/src/internal.h index 98c889a3..9dace49c 100644 --- a/src/internal.h +++ b/src/internal.h @@ -408,7 +408,7 @@ struct _GLFWwndconfig GLFWbool focusOnShow; GLFWbool mousePassthrough; GLFWbool scaleToMonitor; - GLFWbool lightTheme; + int theme; struct { GLFWbool retina; char frameName[256]; diff --git a/src/win32_window.c b/src/win32_window.c index f6a8b0b7..e029fc7a 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1344,7 +1344,35 @@ static int createNativeWindow(_GLFWwindow* window, _glfw.win32.instance, (LPVOID) wndconfig); - _glfwSetWindowTheme(!(wndconfig->lightTheme), window->win32.handle); + BOOL should_use_light_mode; + if (wndconfig->theme == GLFW_THEME_AUTO) + { + BOOL success = FALSE; + HKEY hRootKey = HKEY_CURRENT_USER; + const wchar_t* lpSubKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; + const wchar_t* lpValueName = L"AppsUseLightTheme"; + DWORD result; + { + HKEY hKey = 0; + if (RegOpenKeyExW(hRootKey, lpSubKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + DWORD dwBufferSize = sizeof(DWORD); + DWORD dwData = 0; + if (RegQueryValueExW(hKey, lpValueName, 0, NULL, (LPBYTE)(&dwData), &dwBufferSize) == ERROR_SUCCESS) + { + result = dwData; + success = TRUE; + } + RegCloseKey(hKey); + } + } + should_use_light_mode = success && result != 0; + } + else + should_use_light_mode = wndconfig->theme == GLFW_THEME_LIGHT; + + _glfwSetWindowTheme(!should_use_light_mode, window->win32.handle); + _glfw_free(wideTitle); if (!window->win32.handle) diff --git a/src/window.c b/src/window.c index c601bee0..5f212a98 100644 --- a/src/window.c +++ b/src/window.c @@ -388,8 +388,8 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_SCALE_TO_MONITOR: _glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE; return; - case GLFW_LIGHT_THEME: - _glfw.hints.window.lightTheme = value ? GLFW_TRUE : GLFW_FALSE; + case GLFW_THEME: + _glfw.hints.window.theme = value; return; case GLFW_CENTER_CURSOR: _glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE; From 8b991ae051939b568404a5890545b99274c2b466 Mon Sep 17 00:00:00 2001 From: Santiago Date: Sat, 19 Aug 2023 15:22:26 +0200 Subject: [PATCH 5/5] Add glfwIsWindowLightTheme function --- include/GLFW/glfw3.h | 2 ++ src/internal.h | 1 + src/win32_window.c | 1 + src/window.c | 9 +++++++++ 4 files changed, 13 insertions(+) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index b1e5cf2b..c029787a 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3388,6 +3388,8 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); */ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); +GLFWAPI int glfwIsWindowLightTheme(GLFWwindow* window); + /*! @brief Retrieves the size of the content area of the specified window. * * This function retrieves the size, in screen coordinates, of the content area diff --git a/src/internal.h b/src/internal.h index 9dace49c..b3a2962a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -533,6 +533,7 @@ struct _GLFWwindow GLFWbool focusOnShow; GLFWbool mousePassthrough; GLFWbool shouldClose; + GLFWbool isLightTheme; void* userPointer; GLFWbool doublebuffer; GLFWvidmode videoMode; diff --git a/src/win32_window.c b/src/win32_window.c index e029fc7a..379bb64c 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1372,6 +1372,7 @@ static int createNativeWindow(_GLFWwindow* window, should_use_light_mode = wndconfig->theme == GLFW_THEME_LIGHT; _glfwSetWindowTheme(!should_use_light_mode, window->win32.handle); + window->isLightTheme = should_use_light_mode ? GLFW_TRUE : GLFW_FALSE; _glfw_free(wideTitle); diff --git a/src/window.c b/src/window.c index 5f212a98..9d399bfe 100644 --- a/src/window.c +++ b/src/window.c @@ -588,6 +588,15 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) _glfw.platform.setWindowPos(window, xpos, ypos); } +GLFWAPI int glfwIsWindowLightTheme(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*)handle; + assert(window != NULL); + + _GLFW_REQUIRE_INIT_OR_RETURN(0); + return window->isLightTheme; +} + GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) { _GLFWwindow* window = (_GLFWwindow*) handle;