mirror of
https://github.com/glfw/glfw.git
synced 2024-11-26 22:34:35 +00:00
Merge pull request #2 from floppyhammer/add-win32-theming
Add win32 theming base
This commit is contained in:
commit
85a6eb0625
@ -151,6 +151,8 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
||||||
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
|
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
|
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
|
||||||
|
_glfw.win32.dwmapi.SetWindowAttribute = (PFN_DwmSetWindowAttribute)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmSetWindowAttribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll");
|
_glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll");
|
||||||
@ -169,6 +171,18 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
_glfwPlatformGetModuleSymbol(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfw.win32.uxtheme.instance = _glfwPlatformLoadModule("uxtheme.dll");
|
||||||
|
if (_glfw.win32.uxtheme.instance)
|
||||||
|
{
|
||||||
|
_glfw.win32.uxtheme.ShouldAppsUseDarkMode = (ShouldAppsUseDarkModePtr)_glfwPlatformGetModuleSymbol(_glfw.win32.uxtheme.instance, MAKEINTRESOURCEA(132));
|
||||||
|
_glfw.win32.uxtheme.GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)_glfwPlatformGetModuleSymbol(_glfw.win32.uxtheme.instance, MAKEINTRESOURCEA(95));
|
||||||
|
_glfw.win32.uxtheme.GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)_glfwPlatformGetModuleSymbol(_glfw.win32.uxtheme.instance, MAKEINTRESOURCEA(96));
|
||||||
|
_glfw.win32.uxtheme.GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)_glfwPlatformGetModuleSymbol(_glfw.win32.uxtheme.instance, MAKEINTRESOURCEA(98));
|
||||||
|
|
||||||
|
_glfw.win32.uxtheme.uxThemeAvailable = _glfw.win32.uxtheme.ShouldAppsUseDarkMode && _glfw.win32.uxtheme.GetImmersiveColorFromColorSetEx && _glfw.win32.uxtheme.GetImmersiveColorTypeFromName && _glfw.win32.uxtheme.GetImmersiveUserColorSetPreference;
|
||||||
|
_glfw.win32.uxtheme.darkTitleAvailable = _glfwIsWindows10BuildOrGreaterWin32(22000);
|
||||||
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,6 +207,9 @@ static void freeLibraries(void)
|
|||||||
|
|
||||||
if (_glfw.win32.ntdll.instance)
|
if (_glfw.win32.ntdll.instance)
|
||||||
_glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
|
_glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
|
||||||
|
|
||||||
|
if (_glfw.win32.uxtheme.instance)
|
||||||
|
_glfwPlatformFreeModule(_glfw.win32.uxtheme.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create key code translation tables
|
// Create key code translation tables
|
||||||
@ -739,9 +756,18 @@ void _glfwTerminateWin32(void)
|
|||||||
|
|
||||||
_GLFWtheme* _glfwGetSystemDefaultThemeWin32(void)
|
_GLFWtheme* _glfwGetSystemDefaultThemeWin32(void)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
|
_GLFWtheme* theme = &_glfw.theme;
|
||||||
return NULL; // TODO: implement
|
|
||||||
|
theme->variation = GLFW_THEME_LIGHT;
|
||||||
|
theme->flags = 0;
|
||||||
|
|
||||||
|
if (_glfw.win32.uxtheme.uxThemeAvailable && _glfw.win32.uxtheme.darkTitleAvailable) {
|
||||||
|
if (_glfw.win32.uxtheme.ShouldAppsUseDarkMode() & 0x1) {
|
||||||
|
theme->variation = GLFW_THEME_DARK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _GLFW_WIN32
|
#endif // _GLFW_WIN32
|
||||||
|
|
||||||
|
@ -299,12 +299,15 @@ typedef int (WINAPI * PFN_GetSystemMetricsForDpi)(int,UINT);
|
|||||||
// dwmapi.dll function pointer typedefs
|
// dwmapi.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||||
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
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_DwmGetColorizationColor)(DWORD*,BOOL*);
|
||||||
|
typedef HRESULT (WINAPI * PFN_DwmSetWindowAttribute)(HWND,DWORD,LPCVOID,DWORD);
|
||||||
|
|
||||||
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
||||||
#define DwmFlush _glfw.win32.dwmapi.Flush
|
#define DwmFlush _glfw.win32.dwmapi.Flush
|
||||||
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
||||||
#define DwmGetColorizationColor _glfw.win32.dwmapi.GetColorizationColor
|
#define DwmGetColorizationColor _glfw.win32.dwmapi.GetColorizationColor
|
||||||
|
#define DwmSetWindowAttribute _glfw.win32.dwmapi.SetWindowAttribute
|
||||||
|
|
||||||
// shcore.dll function pointer typedefs
|
// shcore.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||||
@ -366,6 +369,11 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
|
|||||||
#define GLFW_WGL_CONTEXT_STATE _GLFWcontextWGL wgl;
|
#define GLFW_WGL_CONTEXT_STATE _GLFWcontextWGL wgl;
|
||||||
#define GLFW_WGL_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl;
|
#define GLFW_WGL_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl;
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI * ShouldAppsUseDarkModePtr)();
|
||||||
|
typedef DWORD (WINAPI * GetImmersiveColorFromColorSetExPtr)(UINT,UINT,BOOL,UINT);
|
||||||
|
typedef int (WINAPI * GetImmersiveColorTypeFromNamePtr)(const WCHAR*);
|
||||||
|
typedef int (WINAPI * GetImmersiveUserColorSetPreferencePtr)(BOOL,BOOL);
|
||||||
|
|
||||||
|
|
||||||
// WGL-specific per-context data
|
// WGL-specific per-context data
|
||||||
//
|
//
|
||||||
@ -487,6 +495,7 @@ typedef struct _GLFWlibraryWin32
|
|||||||
PFN_DwmFlush Flush;
|
PFN_DwmFlush Flush;
|
||||||
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
||||||
PFN_DwmGetColorizationColor GetColorizationColor;
|
PFN_DwmGetColorizationColor GetColorizationColor;
|
||||||
|
PFN_DwmSetWindowAttribute SetWindowAttribute;
|
||||||
} dwmapi;
|
} dwmapi;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -499,6 +508,16 @@ typedef struct _GLFWlibraryWin32
|
|||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
|
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
|
||||||
} ntdll;
|
} ntdll;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
HINSTANCE instance;
|
||||||
|
GLFWbool uxThemeAvailable;
|
||||||
|
GLFWbool darkTitleAvailable;
|
||||||
|
ShouldAppsUseDarkModePtr ShouldAppsUseDarkMode;
|
||||||
|
GetImmersiveColorFromColorSetExPtr GetImmersiveColorFromColorSetEx;
|
||||||
|
GetImmersiveColorTypeFromNamePtr GetImmersiveColorTypeFromName;
|
||||||
|
GetImmersiveUserColorSetPreferencePtr GetImmersiveUserColorSetPreference;
|
||||||
|
} uxtheme;
|
||||||
} _GLFWlibraryWin32;
|
} _GLFWlibraryWin32;
|
||||||
|
|
||||||
// Win32-specific per-monitor data
|
// Win32-specific per-monitor data
|
||||||
|
@ -37,6 +37,46 @@
|
|||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
|
||||||
|
// Ref: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
|
||||||
|
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
|
||||||
|
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Apply the system default theme
|
||||||
|
//
|
||||||
|
static void applySystemTheme(HWND handle)
|
||||||
|
{
|
||||||
|
if (_glfw.win32.uxtheme.uxThemeAvailable && _glfw.win32.uxtheme.darkTitleAvailable)
|
||||||
|
{
|
||||||
|
GLFWbool value = _glfw.win32.uxtheme.ShouldAppsUseDarkMode() & 0x1;
|
||||||
|
DwmSetWindowAttribute(handle,
|
||||||
|
DWMWA_USE_IMMERSIVE_DARK_MODE,
|
||||||
|
&value,
|
||||||
|
sizeof(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getAccentColor(float color[4])
|
||||||
|
{
|
||||||
|
if (!_glfw.win32.uxtheme.uxThemeAvailable)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT dwImmersiveColorType = _glfw.win32.uxtheme.GetImmersiveColorTypeFromName(L"ImmersiveSystemAccent");
|
||||||
|
UINT dwImmersiveColorSet = _glfw.win32.uxtheme.GetImmersiveUserColorSetPreference(FALSE, FALSE);
|
||||||
|
|
||||||
|
UINT rgba = _glfw.win32.uxtheme.GetImmersiveColorFromColorSetEx(dwImmersiveColorSet,
|
||||||
|
dwImmersiveColorType,
|
||||||
|
FALSE,
|
||||||
|
0);
|
||||||
|
|
||||||
|
color[0] = (0xFF & rgba);
|
||||||
|
color[1] = ((0xFF00 & rgba) >> 8) ;
|
||||||
|
color[2] = ((0xFF0000 & rgba) >> 16);
|
||||||
|
color[3] = ((0xFF000000 & rgba) >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the window style for the specified window
|
// Returns the window style for the specified window
|
||||||
//
|
//
|
||||||
static DWORD getWindowStyle(const _GLFWwindow* window)
|
static DWORD getWindowStyle(const _GLFWwindow* window)
|
||||||
@ -1146,6 +1186,13 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_THEMECHANGED:
|
||||||
|
case WM_SETTINGCHANGE: {
|
||||||
|
if (window->theme.variation == GLFW_THEME_DEFAULT) {
|
||||||
|
applySystemTheme(window->win32.handle);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
case WM_GETDPISCALEDSIZE:
|
case WM_GETDPISCALEDSIZE:
|
||||||
{
|
{
|
||||||
if (window->win32.scaleToMonitor)
|
if (window->win32.scaleToMonitor)
|
||||||
@ -1436,6 +1483,9 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
_glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height);
|
_glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height);
|
||||||
|
|
||||||
|
// Use the system default when creating a window
|
||||||
|
applySystemTheme(window->win32.handle);
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2375,13 +2425,36 @@ const char* _glfwGetClipboardStringWin32(void)
|
|||||||
|
|
||||||
void _glfwSetThemeWin32(_GLFWwindow* window, _GLFWtheme* theme)
|
void _glfwSetThemeWin32(_GLFWwindow* window, _GLFWtheme* theme)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
|
if (!theme || theme->variation == GLFW_THEME_DEFAULT)
|
||||||
|
{
|
||||||
|
applySystemTheme(window->win32.handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool darkMode = theme->variation == GLFW_THEME_DARK;
|
||||||
|
|
||||||
|
DwmSetWindowAttribute(window->win32.handle,
|
||||||
|
DWMWA_USE_IMMERSIVE_DARK_MODE,
|
||||||
|
&darkMode,
|
||||||
|
sizeof(darkMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
_GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window)
|
_GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
|
_GLFWtheme* theme = &window->theme;
|
||||||
return NULL; // TODO: implement
|
|
||||||
|
theme->variation = GLFW_THEME_LIGHT;
|
||||||
|
theme->flags = 0;
|
||||||
|
|
||||||
|
if (_glfw.win32.uxtheme.uxThemeAvailable && _glfw.win32.uxtheme.darkTitleAvailable)
|
||||||
|
{
|
||||||
|
theme->variation = GLFW_THEME_DARK;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(theme->color, 0, sizeof(float) * 4);
|
||||||
|
getAccentColor(theme->color);
|
||||||
|
|
||||||
|
return theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs)
|
EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs)
|
||||||
@ -2512,4 +2585,3 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif // _GLFW_WIN32
|
#endif // _GLFW_WIN32
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user