diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 8129d2fa..ca8e1e87 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -5845,16 +5845,31 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); */ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); -typedef struct GLFWtheme -{ - int baseTheme; // light/dark - int flags; - unsigned char color[4]; -} GLFWtheme; +typedef struct GLFWtheme GLFWtheme; -#define GLFW_BASE_THEME_DEFAULT 0 -#define GLFW_BASE_THEME_LIGHT 1 -#define GLFW_BASE_THEME_DARK 2 +typedef struct _GLFWtheme +{ + int variation; // light/dark + int flags; + unsigned char color[4]; // TODO: change to 128 bit (4 floats) to support wider gamuts. +} _GLFWtheme; + +GLFWAPI GLFWtheme* glfwCreateTheme(void); +GLFWAPI void glfwDestroyTheme(GLFWtheme* theme); +GLFWAPI void glfwCopyTheme(const GLFWtheme* source, GLFWtheme* target); + +GLFWAPI int glfwThemeGetVariation(const GLFWtheme* theme); +GLFWAPI void glfwThemeSetVariation(GLFWtheme* theme, int value); + +GLFWAPI int glfwThemeGetFlags(const GLFWtheme* theme); +GLFWAPI void glfwThemeSetFlags(GLFWtheme* theme, int value); + +GLFWAPI void glfwThemeGetColor(const GLFWtheme* theme, float* red, float* green, float* blue, float* alpha); +GLFWAPI void glfwThemeSetColor(GLFWtheme* theme, float red, float green, float blue, float alpha); + +#define GLFW_THEME_DARK -1 +#define GLFW_THEME_DEFAULT 0 +#define GLFW_THEME_LIGHT 1 #define GLFW_THEME_FLAG_HAS_COLOR 1 #define GLFW_THEME_FLAG_HIGH_CONTRAST 2 @@ -5872,7 +5887,7 @@ GLFWAPI GLFWthemefun glfwSetSystemThemeCallback(GLFWthemefun callback); * @param[in] window The window to set the theme for. * @param[in] theme The theme to set. Pass `NULL` to set it to the system default. */ -GLFWAPI void glfwSetTheme(GLFWwindow* handle, GLFWtheme* theme); +GLFWAPI void glfwSetTheme(GLFWwindow* handle, const GLFWtheme* theme); GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* handle); GLFWAPI GLFWtheme* glfwGetSystemDefaultTheme(); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 01f191c9..09427835 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,7 @@ add_library(glfw ${GLFW_LIBRARY_TYPE} "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h" internal.h platform.h mappings.h - context.c init.c input.c monitor.c platform.c vulkan.c window.c + context.c init.c input.c monitor.c platform.c theme.c vulkan.c window.c egl_context.c osmesa_context.c null_platform.h null_joystick.h null_init.c null_monitor.c null_window.c null_joystick.c) @@ -248,7 +248,7 @@ endif() # Make GCC warn about declarations that VS 2010 and 2012 won't accept for all # source files that VS will build (Clang ignores this because we set -std=c99) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - set_source_files_properties(context.c init.c input.c monitor.c platform.c vulkan.c + set_source_files_properties(context.c init.c input.c monitor.c platform.c theme.c vulkan.c window.c null_init.c null_joystick.c null_monitor.c null_window.c win32_init.c win32_joystick.c win32_module.c win32_monitor.c win32_time.c win32_thread.c win32_window.c diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 9570d4c2..5c8b0e82 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -175,7 +175,7 @@ static void createMenuBar(void) [NSApp performSelector:setAppleMenuSelector withObject:appMenu]; } -void nsAppearanceToGLFWTheme(NSAppearance* appearance, GLFWtheme* theme) +void nsAppearanceToGLFWTheme(NSAppearance* appearance, _GLFWtheme* theme) { NSAppearanceName name; @@ -197,20 +197,20 @@ void nsAppearanceToGLFWTheme(NSAppearance* appearance, GLFWtheme* theme) if ([name isEqualToString:NSAppearanceNameAqua]) { - theme->baseTheme = GLFW_BASE_THEME_LIGHT; + theme->variation = GLFW_THEME_LIGHT; return; } if (@available(macOS 10.10, *)) { if ([name isEqualToString:NSAppearanceNameVibrantLight]) { - theme->baseTheme = GLFW_BASE_THEME_LIGHT; + theme->variation = GLFW_THEME_LIGHT; theme->flags |= GLFW_THEME_FLAG_VIBRANT; return; } if ([name isEqualToString:NSAppearanceNameVibrantDark]) { - theme->baseTheme = GLFW_BASE_THEME_DARK; + theme->variation = GLFW_THEME_DARK; theme->flags |= GLFW_THEME_FLAG_VIBRANT; return; } @@ -220,36 +220,36 @@ void nsAppearanceToGLFWTheme(NSAppearance* appearance, GLFWtheme* theme) { if ([name isEqualToString:NSAppearanceNameDarkAqua]) { - theme->baseTheme = GLFW_BASE_THEME_DARK; + theme->variation = GLFW_THEME_DARK; return; } if ([name isEqualToString:NSAppearanceNameAccessibilityHighContrastAqua]) { - theme->baseTheme = GLFW_BASE_THEME_LIGHT; + theme->variation = GLFW_THEME_LIGHT; theme->flags |= GLFW_THEME_FLAG_HIGH_CONTRAST; return; } if ([name isEqualToString:NSAppearanceNameAccessibilityHighContrastDarkAqua]) { - theme->baseTheme = GLFW_BASE_THEME_DARK; + theme->variation = GLFW_THEME_DARK; theme->flags |= GLFW_THEME_FLAG_HIGH_CONTRAST; return; } if ([name isEqualToString:NSAppearanceNameAccessibilityHighContrastVibrantLight]) { - theme->baseTheme = GLFW_BASE_THEME_LIGHT; + theme->variation = GLFW_THEME_LIGHT; theme->flags |= GLFW_THEME_FLAG_VIBRANT | GLFW_THEME_FLAG_HIGH_CONTRAST; return; } if ([name isEqualToString:NSAppearanceNameAccessibilityHighContrastVibrantDark]) { - theme->baseTheme = GLFW_BASE_THEME_DARK; + theme->variation = GLFW_THEME_DARK; theme->flags |= GLFW_THEME_FLAG_VIBRANT | GLFW_THEME_FLAG_HIGH_CONTRAST; return; } } - theme->baseTheme = GLFW_BASE_THEME_LIGHT; + theme->variation = GLFW_THEME_LIGHT; } // Create key code translation tables @@ -491,9 +491,12 @@ static GLFWbool initializeTIS(void) // TODO: FIXME: this method is invoked twice when the high contrast setting is edited in the preferences. - GLFWtheme theme = { GLFW_BASE_THEME_LIGHT, 0 }; + _GLFWtheme theme = { GLFW_THEME_LIGHT, 0 }; if (@available(macOS 10.14, *)) { + // effectiveAppearance is actually not the system appearance, but the application appearance. + // As long as NSApplication.appearance is never set, using the effective appearance is fine + // to get and observe the system appearance. nsAppearanceToGLFWTheme(NSApp.effectiveAppearance, &theme); NSColor* color = [[NSColor controlAccentColor] colorUsingColorSpace:NSColorSpace.genericRGBColorSpace]; @@ -842,7 +845,7 @@ void _glfwTerminateCocoa(void) } // autoreleasepool } -GLFWtheme* _glfwGetSystemDefaultThemeCocoa(void) +_GLFWtheme* _glfwGetSystemDefaultThemeCocoa(void) { _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL); return NULL; // TODO: implement diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 84a0ace0..6e6f9054 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -297,7 +297,7 @@ void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor); float _glfwTransformYCocoa(float y); -void nsAppearanceToGLFWTheme(NSAppearance* appearance, GLFWtheme* theme); +void nsAppearanceToGLFWTheme(NSAppearance* appearance, _GLFWtheme* theme); void* _glfwLoadLocalVulkanLoaderCocoa(void); @@ -309,6 +309,6 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, void _glfwDestroyContextNSGL(_GLFWwindow* window); -GLFWtheme* _glfwGetSystemDefaultThemeCocoa(void); -void _glfwSetThemeCocoa(_GLFWwindow* window, GLFWtheme* theme); -GLFWtheme* _glfwGetThemeCocoa(_GLFWwindow* window); +_GLFWtheme* _glfwGetSystemDefaultThemeCocoa(void); +void _glfwSetThemeCocoa(_GLFWwindow* window, _GLFWtheme* theme); +_GLFWtheme* _glfwGetThemeCocoa(_GLFWwindow* window); diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 6ba54501..b99a9e85 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1876,9 +1876,9 @@ const char* _glfwGetClipboardStringCocoa(void) } // autoreleasepool } -void _glfwSetThemeCocoa(_GLFWwindow* window, GLFWtheme* theme) +void _glfwSetThemeCocoa(_GLFWwindow* window, _GLFWtheme* theme) { - if (!theme || theme->baseTheme == GLFW_BASE_THEME_DEFAULT) + if (!theme || theme->variation == GLFW_THEME_DEFAULT) { [(NSWindow*)window->ns.object setAppearance:nil]; return; @@ -1896,7 +1896,7 @@ void _glfwSetThemeCocoa(_GLFWwindow* window, GLFWtheme* theme) // appearanceNamed: will result in nil, so these can not be used. NSAppearanceName name; - if (theme->baseTheme == GLFW_BASE_THEME_LIGHT) + if (theme->variation == GLFW_THEME_LIGHT) { if (theme->flags & GLFW_THEME_FLAG_VIBRANT) { @@ -1926,11 +1926,11 @@ void _glfwSetThemeCocoa(_GLFWwindow* window, GLFWtheme* theme) [(NSWindow*)window->ns.object setAppearance:appearance]; } -GLFWtheme* _glfwGetThemeCocoa(_GLFWwindow* window) +_GLFWtheme* _glfwGetThemeCocoa(_GLFWwindow* window) { - GLFWtheme* theme = &window->theme; + _GLFWtheme* theme = &window->theme; - theme->baseTheme = GLFW_BASE_THEME_LIGHT; + theme->variation = GLFW_THEME_LIGHT; theme->flags = 0; if (@available(macOS 10.09, *)) diff --git a/src/init.c b/src/init.c index 41107ee8..69d391c1 100644 --- a/src/init.c +++ b/src/init.c @@ -546,7 +546,11 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun) GLFWAPI GLFWtheme* glfwGetSystemDefaultTheme() { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return _glfw.platform.getSystemDefaultTheme(); + + _GLFWtheme* theme = _glfw.platform.getSystemDefaultTheme(); + assert(theme->variation != GLFW_THEME_DEFAULT); + + return (GLFWtheme*) theme; } GLFWAPI GLFWthemefun glfwSetSystemThemeCallback(GLFWthemefun callback) diff --git a/src/input.c b/src/input.c index dc2ab137..03fc41cb 100644 --- a/src/input.c +++ b/src/input.c @@ -477,12 +477,12 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value) js->hats[hat] = value; } -void _glfwInputSystemTheme(GLFWtheme* theme) +void _glfwInputSystemTheme(_GLFWtheme* theme) { assert(theme != NULL); if (_glfw.callbacks.theme) - _glfw.callbacks.theme(theme); + _glfw.callbacks.theme((GLFWtheme*) theme); } ////////////////////////////////////////////////////////////////////////// diff --git a/src/internal.h b/src/internal.h index 5d3ec9a6..9795fc6b 100644 --- a/src/internal.h +++ b/src/internal.h @@ -571,7 +571,7 @@ struct _GLFWwindow GLFWdropfun drop; } callbacks; - GLFWtheme theme; + _GLFWtheme theme; // TODO: This data is mutable by clients, so remove it. // This is defined in platform.h GLFW_PLATFORM_WINDOW_STATE @@ -675,7 +675,7 @@ struct _GLFWplatform // Init GLFWbool (*init)(void); void (*terminate)(void); - GLFWtheme* (*getSystemDefaultTheme)(void); + _GLFWtheme* (*getSystemDefaultTheme)(void); // Input void (*getCursorPos)(_GLFWwindow*,double*,double*); void (*setCursorPos)(_GLFWwindow*,double,double); @@ -738,8 +738,8 @@ struct _GLFWplatform void (*setWindowFloating)(_GLFWwindow*,GLFWbool); void (*setWindowOpacity)(_GLFWwindow*,float); void (*setWindowMousePassthrough)(_GLFWwindow*,GLFWbool); - GLFWtheme* (*getTheme)(_GLFWwindow*); - void (*setTheme)(_GLFWwindow*,GLFWtheme*); + _GLFWtheme* (*getTheme)(_GLFWwindow*); + void (*setTheme)(_GLFWwindow*,_GLFWtheme*); // Events void (*pollEvents)(void); void (*waitEvents)(void); @@ -936,7 +936,7 @@ void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value); void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value); void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value); -void _glfwInputSystemTheme(GLFWtheme* theme); +void _glfwInputSystemTheme(_GLFWtheme* theme); void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement); void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window); diff --git a/src/null_init.c b/src/null_init.c index f42f70b4..15738873 100644 --- a/src/null_init.c +++ b/src/null_init.c @@ -140,7 +140,7 @@ void _glfwTerminateNull(void) _glfwTerminateEGL(); } -GLFWtheme* _glfwGetSystemDefaultThemeNull(void) +_GLFWtheme* _glfwGetSystemDefaultThemeNull(void) { - return NULL; // TODO: should probably return a colorless GLFWtheme with baseTheme set to GLFW_BASE_THEME_LIGHT + return NULL; // TODO: should probably return a colorless GLFWtheme with baseTheme set to GLFW_THEME_LIGHT } diff --git a/src/null_platform.h b/src/null_platform.h index 44a61cad..b5abe2b0 100644 --- a/src/null_platform.h +++ b/src/null_platform.h @@ -147,6 +147,6 @@ VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window, void _glfwPollMonitorsNull(void); -GLFWtheme* _glfwGetSystemDefaultThemeNull(void); -void _glfwSetThemeNull(_GLFWwindow* window, GLFWtheme* theme); -GLFWtheme* _glfwGetThemeNull(_GLFWwindow* window); +_GLFWtheme* _glfwGetSystemDefaultThemeNull(void); +void _glfwSetThemeNull(_GLFWwindow* window, _GLFWtheme* theme); +_GLFWtheme* _glfwGetThemeNull(_GLFWwindow* window); diff --git a/src/null_window.c b/src/null_window.c index 2804fa59..c0d3264a 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -551,11 +551,11 @@ const char* _glfwGetClipboardStringNull(void) return _glfw.null.clipboardString; } -void _glfwSetThemeNull(_GLFWwindow* window, GLFWtheme* theme) +void _glfwSetThemeNull(_GLFWwindow* window, _GLFWtheme* theme) { } -GLFWtheme* _glfwGetThemeNull(_GLFWwindow* window) +_GLFWtheme* _glfwGetThemeNull(_GLFWwindow* window) { return NULL; // TODO: see to-do in _glfwGetSystemDefaultThemeNull } diff --git a/src/theme.c b/src/theme.c new file mode 100644 index 00000000..bcb119a0 --- /dev/null +++ b/src/theme.c @@ -0,0 +1,88 @@ +// +// theme.c +// glfw +// +// Created by Andreas Ormevik Jansen on 28/01/2023. +// + +#include "internal.h" + +#include +#include +#include +#include +#include + + +GLFWAPI GLFWtheme* glfwCreateTheme(void) +{ + _GLFWtheme* theme = _glfw_calloc(1, sizeof(_GLFWtheme)); + + theme->variation = GLFW_THEME_DEFAULT; + theme->flags = 0; + + return (GLFWtheme*) theme; +} + +GLFWAPI void glfwDestroyTheme(GLFWtheme* theme) +{ + _glfw_free((_GLFWtheme*) theme); +} + +GLFWAPI void glfwCopyTheme(const GLFWtheme* source, GLFWtheme* target) +{ + memcpy(target, source, sizeof(_GLFWtheme)); +} + +GLFWAPI int glfwThemeGetVariation(const GLFWtheme* theme) +{ + assert(theme != NULL); + return ((_GLFWtheme*) theme)->variation; +} + +GLFWAPI void glfwThemeSetVariation(GLFWtheme* theme, int value) +{ + assert(theme != NULL); + assert(value == GLFW_THEME_DARK || value == GLFW_THEME_DEFAULT || value == GLFW_THEME_LIGHT); + + ((_GLFWtheme*) theme)->variation = value; +} + +GLFWAPI int glfwThemeGetFlags(const GLFWtheme* theme) +{ + assert(theme != NULL); + return ((_GLFWtheme*) theme)->flags; +} + +GLFWAPI void glfwThemeSetFlags(GLFWtheme* theme, int value) +{ + assert(theme != NULL); + assert((value & ~(GLFW_THEME_FLAG_HAS_COLOR | GLFW_THEME_FLAG_HIGH_CONTRAST | GLFW_THEME_FLAG_VIBRANT)) == 0); + + ((_GLFWtheme*) theme)->flags = value; +} + +GLFWAPI void glfwThemeGetColor(const GLFWtheme* theme, float* red, float* green, float* blue, float* alpha) +{ + assert(theme != NULL); + assert(red != NULL && green != NULL && blue != NULL && alpha != NULL); + + const _GLFWtheme* iTheme = ((_GLFWtheme*) theme); + + *red = iTheme->color[0] / 255.0f; + *green = iTheme->color[1] / 255.0f; + *blue = iTheme->color[2] / 255.0f; + *alpha = iTheme->color[3] / 255.0f; +} + +GLFWAPI void glfwThemeSetColor(GLFWtheme* theme, float red, float green, float blue, float alpha) +{ + assert(theme != NULL); + + _GLFWtheme* iTheme = ((_GLFWtheme*) theme); + + iTheme->color[0] = red * 255.0f; + iTheme->color[1] = green * 255.0f; + iTheme->color[2] = blue * 255.0f; + iTheme->color[3] = alpha * 255.0f; +} diff --git a/src/win32_init.c b/src/win32_init.c index 2ee73b23..3bba1f65 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -737,7 +737,7 @@ void _glfwTerminateWin32(void) freeLibraries(); } -GLFWtheme* _glfwGetSystemDefaultThemeWin32(void) +_GLFWtheme* _glfwGetSystemDefaultThemeWin32(void) { _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL); return NULL; // TODO: implement diff --git a/src/win32_platform.h b/src/win32_platform.h index ca46cb16..fd7624f0 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -622,6 +622,6 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); -GLFWtheme* _glfwGetSystemDefaultThemeWin32(void); -void _glfwSetThemeWin32(_GLFWwindow* window, GLFWtheme* theme); -GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window); +_GLFWtheme* _glfwGetSystemDefaultThemeWin32(void); +void _glfwSetThemeWin32(_GLFWwindow* window, _GLFWtheme* theme); +_GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window); diff --git a/src/win32_window.c b/src/win32_window.c index 53a11a14..0a73f36b 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -2373,12 +2373,12 @@ const char* _glfwGetClipboardStringWin32(void) return _glfw.win32.clipboardString; } -void _glfwSetThemeWin32(_GLFWwindow* window, GLFWtheme* theme) +void _glfwSetThemeWin32(_GLFWwindow* window, _GLFWtheme* theme) { _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL); } -GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window) +_GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window) { _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL); return NULL; // TODO: implement diff --git a/src/window.c b/src/window.c index e380d3fb..12bd4a30 100644 --- a/src/window.c +++ b/src/window.c @@ -1160,7 +1160,7 @@ GLFWAPI void glfwSetTheme(GLFWwindow* handle, GLFWtheme* theme) assert(window != NULL); _GLFW_REQUIRE_INIT(); - _glfw.platform.setTheme(window, theme); + _glfw.platform.setTheme(window, (_GLFWtheme*) theme); } GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* handle) @@ -1169,5 +1169,5 @@ GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* handle) assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - return _glfw.platform.getTheme(window); + return (GLFWtheme*) _glfw.platform.getTheme(window); } diff --git a/src/wl_init.c b/src/wl_init.c index b28e0e15..0efa0007 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -803,7 +803,7 @@ void _glfwTerminateWayland(void) _glfw_free(_glfw.wl.clipboardString); } -GLFWtheme* _glfwGetSystemDefaultThemeWayland(void) +_GLFWtheme* _glfwGetSystemDefaultThemeWayland(void) { _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL); return NULL; // TODO: implement diff --git a/src/wl_platform.h b/src/wl_platform.h index af357cac..bf19f16a 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -519,6 +519,6 @@ void _glfwUpdateContentScaleWayland(_GLFWwindow* window); void _glfwAddSeatListenerWayland(struct wl_seat* seat); void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device); -GLFWtheme* _glfwGetSystemDefaultThemeWayland(void); -void _glfwSetThemeWayland(_GLFWwindow* window, GLFWtheme* theme); -GLFWtheme* _glfwGetThemeWayland(_GLFWwindow* window); +_GLFWtheme* _glfwGetSystemDefaultThemeWayland(void); +void _glfwSetThemeWayland(_GLFWwindow* window, _GLFWtheme* theme); +_GLFWtheme* _glfwGetThemeWayland(_GLFWwindow* window); diff --git a/src/wl_window.c b/src/wl_window.c index 48a60b52..ed490155 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2775,12 +2775,12 @@ const char* _glfwGetClipboardStringWayland(void) return _glfw.wl.clipboardString; } -void _glfwSetThemeWayland(_GLFWwindow* window, GLFWtheme* theme) +void _glfwSetThemeWayland(_GLFWwindow* window, _GLFWtheme* theme) { _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL); } -GLFWtheme* _glfwGetThemeWayland(_GLFWwindow* window) +_GLFWtheme* _glfwGetThemeWayland(_GLFWwindow* window) { _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL); return NULL; // TODO: implement diff --git a/src/x11_init.c b/src/x11_init.c index 21645b94..582624b9 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -1664,7 +1664,7 @@ void _glfwTerminateX11(void) } } -GLFWtheme* _glfwGetSystemDefaultThemeX11(void) +_GLFWtheme* _glfwGetSystemDefaultThemeX11(void) { _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL); return NULL; // TODO: implement diff --git a/src/x11_platform.h b/src/x11_platform.h index e0214699..5cff4c7a 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -1002,6 +1002,6 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth); -GLFWtheme* _glfwGetSystemDefaultThemeX11(void); -void _glfwSetThemeX11(_GLFWwindow* window, GLFWtheme* theme); -GLFWtheme* _glfwGetThemeX11(_GLFWwindow* window); +_GLFWtheme* _glfwGetSystemDefaultThemeX11(void); +void _glfwSetThemeX11(_GLFWwindow* window, _GLFWtheme* theme); +_GLFWtheme* _glfwGetThemeX11(_GLFWwindow* window); diff --git a/src/x11_window.c b/src/x11_window.c index f3adc490..675f5014 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -3082,12 +3082,12 @@ const char* _glfwGetClipboardStringX11(void) return getSelectionString(_glfw.x11.CLIPBOARD); } -void _glfwSetThemeX11(_GLFWwindow* window, GLFWtheme* theme) +void _glfwSetThemeX11(_GLFWwindow* window, _GLFWtheme* theme) { _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL); } -GLFWtheme* _glfwGetThemeX11(_GLFWwindow* window) +_GLFWtheme* _glfwGetThemeX11(_GLFWwindow* window) { _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL); return NULL; // TODO: implement diff --git a/tests/theming.c b/tests/theming.c index c74425c8..21bab47b 100644 --- a/tests/theming.c +++ b/tests/theming.c @@ -36,75 +36,84 @@ #include #include -const unsigned char theme_colors[6][4] = +const float theme_colors[6][4] = { - { 0, 0, 0, 255 }, // black - { 255, 0, 0, 255 }, // red - { 0, 255, 0, 255 }, // green - { 0, 0, 255, 255 }, // blue - { 255, 255, 255, 255 }, // white - { 128, 128, 128, 255 } // gray (no theme color) + { 0, 0, 0, 1.0 }, // black + { 1.0, 0, 0, 1.0 }, // red + { 0, 1.0, 0, 1.0 }, // green + { 0, 0, 1.0, 1.0 }, // blue + { 1.0, 1.0, 1.0, 1.0 }, // white + { 0.5, 0.5, 0.5, 1.0 } // gray (no theme color) }; static int cur_theme_color = 0; -static GLFWtheme theme; +static GLFWtheme* theme; static void print_theme(GLFWtheme* theme, const char* title) { + const int flags = glfwThemeGetFlags(theme); int n = 0; printf("%s: {\n", title); - printf(" Base: %s\n", theme->baseTheme == GLFW_BASE_THEME_LIGHT ? "light" : "dark"); + printf(" Base: %s\n", glfwThemeGetVariation(theme) == GLFW_THEME_LIGHT ? "light" : "dark"); printf(" Flags: ["); - if (theme->flags & GLFW_THEME_FLAG_HAS_COLOR) + if (flags & GLFW_THEME_FLAG_HAS_COLOR) { printf(n++ > 0 ? ", %s" : "%s", "HAS_COLOR"); } - if (theme->flags & GLFW_THEME_FLAG_VIBRANT) + if (flags & GLFW_THEME_FLAG_VIBRANT) { printf(n++ > 0 ? ", %s" : "%s", "VIBRANT"); } - if (theme->flags & GLFW_THEME_FLAG_HIGH_CONTRAST) + if (flags & GLFW_THEME_FLAG_HIGH_CONTRAST) { printf(n++ > 0 ? ", %s" : "%s", "HIGH_CONTRAST"); } printf("]\n"); - if (theme->flags & GLFW_THEME_FLAG_HAS_COLOR) + if (flags & GLFW_THEME_FLAG_HAS_COLOR) { - printf(" Color: [%i, %i, %i, %i]\n", theme->color[0], theme->color[1], theme->color[2], theme->color[3]); + float r, g, b, a; + glfwThemeGetColor(theme, &r, &g, &b, &a); + printf(" Color: [%f, %f, %f, %f]\n", r, g, b, a); } printf("}\n"); } static void set_theme(GLFWwindow* window, int theme_color) { - memcpy(theme.color, theme_colors[theme_color], 4); + glfwThemeSetColor( + theme, + theme_colors[theme_color][0], + theme_colors[theme_color][1], + theme_colors[theme_color][2], + theme_colors[theme_color][3] + ); if (theme_color == 6) { - theme.flags &= ~GLFW_THEME_FLAG_HAS_COLOR; + glfwThemeSetFlags(theme, glfwThemeGetFlags(theme) & ~GLFW_THEME_FLAG_HAS_COLOR); } else { - theme.flags |= GLFW_THEME_FLAG_HAS_COLOR; + glfwThemeSetFlags(theme, glfwThemeGetFlags(theme) | GLFW_THEME_FLAG_HAS_COLOR); } const char* title; - switch (theme.baseTheme) { - case GLFW_BASE_THEME_DEFAULT: + switch (glfwThemeGetVariation(theme)) { + case GLFW_THEME_DEFAULT: title = "Default theme"; break; - case GLFW_BASE_THEME_LIGHT: + case GLFW_THEME_LIGHT: title = "Light theme"; break; - case GLFW_BASE_THEME_DARK: + case GLFW_THEME_DARK: title = "Dark theme"; break; } glfwSetWindowTitle(window, title); - glfwSetTheme(window, &theme); + glfwSetTheme(window, theme); } static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) @@ -119,15 +128,15 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, glfwSetTheme(window, NULL); break; case GLFW_KEY_1: - theme.baseTheme = GLFW_BASE_THEME_DEFAULT; + glfwThemeSetVariation(theme, GLFW_THEME_DEFAULT); set_theme(window, cur_theme_color); break; case GLFW_KEY_2: - theme.baseTheme = GLFW_BASE_THEME_LIGHT; + glfwThemeSetVariation(theme, GLFW_THEME_LIGHT); set_theme(window, cur_theme_color); break; case GLFW_KEY_3: - theme.baseTheme = GLFW_BASE_THEME_DARK; + glfwThemeSetVariation(theme, GLFW_THEME_DARK); set_theme(window, cur_theme_color); break; case GLFW_KEY_ESCAPE: @@ -172,12 +181,11 @@ int main(int argc, char** argv) glfwSetKeyCallback(window, key_callback); - theme.baseTheme = GLFW_BASE_THEME_DEFAULT; - theme.flags = 0; - theme.color[0] = 0; - theme.color[1] = 0; - theme.color[2] = 0; - theme.color[3] = 0; + theme = glfwCreateTheme(); + + glfwThemeSetVariation(theme, GLFW_THEME_DEFAULT); + glfwThemeSetFlags(theme, 0); + glfwThemeSetColor(theme, 0, 0, 0, 0); set_theme(window, cur_theme_color); glfwSetSystemThemeCallback(theme_callback); @@ -195,6 +203,7 @@ int main(int argc, char** argv) glfwWaitEvents(); } + glfwDestroyTheme(theme); glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_SUCCESS);