mirror of
				https://github.com/glfw/glfw.git
				synced 2025-11-03 22:04:15 +00:00 
			
		
		
		
	Update theming API
This commit is contained in:
		
							parent
							
								
									8ba39bca81
								
							
						
					
					
						commit
						decb018a31
					
				@ -5879,9 +5879,12 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
 | 
					GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: consider requiring GLFW to be initialized for these GLFWTheme functions to work. That way, implementations can add extra data to the themes, and process them in a platform-specific way.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLFWAPI GLFWtheme* glfwCreateTheme(void);
 | 
					GLFWAPI GLFWtheme* glfwCreateTheme(void);
 | 
				
			||||||
GLFWAPI void glfwDestroyTheme(GLFWtheme* theme);
 | 
					GLFWAPI void glfwDestroyTheme(GLFWtheme* theme);
 | 
				
			||||||
GLFWAPI void glfwCopyTheme(const GLFWtheme* source, GLFWtheme* target);
 | 
					GLFWAPI void glfwCopyTheme(const GLFWtheme* source, GLFWtheme* target);
 | 
				
			||||||
 | 
					GLFWAPI int glfwThemeEqual(const GLFWtheme* first, const GLFWtheme* second);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLFWAPI int glfwThemeGetVariation(const GLFWtheme* theme);
 | 
					GLFWAPI int glfwThemeGetVariation(const GLFWtheme* theme);
 | 
				
			||||||
GLFWAPI void glfwThemeSetVariation(GLFWtheme* theme, int value);
 | 
					GLFWAPI void glfwThemeSetVariation(GLFWtheme* theme, int value);
 | 
				
			||||||
@ -5889,10 +5892,12 @@ GLFWAPI void glfwThemeSetVariation(GLFWtheme* theme, int value);
 | 
				
			|||||||
GLFWAPI int glfwThemeGetAttribute(const GLFWtheme* theme, int attribute);
 | 
					GLFWAPI int glfwThemeGetAttribute(const GLFWtheme* theme, int attribute);
 | 
				
			||||||
GLFWAPI void glfwThemeSetAttribute(GLFWtheme* theme, int attribute, int value);
 | 
					GLFWAPI void glfwThemeSetAttribute(GLFWtheme* theme, int attribute, int value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// If the return value of glfwGetAttribute(specifier) is GLFW_FALSE, the return values of this function are undefined.
 | 
				
			||||||
GLFWAPI void glfwThemeGetColor(const GLFWtheme* theme,
 | 
					GLFWAPI void glfwThemeGetColor(const GLFWtheme* theme,
 | 
				
			||||||
                               int specifier,
 | 
					                               int specifier,
 | 
				
			||||||
                               float* red, float* green, float* blue, float* alpha);
 | 
					                               float* red, float* green, float* blue, float* alpha);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Must execute glfwThemeSetAttribute(specifier, GLFW_TRUE) for this to have an effect.
 | 
				
			||||||
GLFWAPI void glfwThemeSetColor(GLFWtheme* theme,
 | 
					GLFWAPI void glfwThemeSetColor(GLFWtheme* theme,
 | 
				
			||||||
                               int specifier,
 | 
					                               int specifier,
 | 
				
			||||||
                               float red, float green, float blue, float alpha);
 | 
					                               float red, float green, float blue, float alpha);
 | 
				
			||||||
@ -5934,11 +5939,19 @@ GLFWAPI void glfwThemeSetColor(GLFWtheme* theme,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/*! @brief Theme attribute.
 | 
					/*! @brief Theme attribute.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  Specifies that a theme is vibrant.
 | 
					 *  Specifies that a theme requests reduced transparency.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @ingroup theme
 | 
					 *  @ingroup theme
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define GLFW_THEME_ATTRIBUTE_VIBRANT 2
 | 
					#define GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! @brief Theme attribute.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Specifies that a theme requests reduced motion.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @ingroup theme
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define GLFW_THEME_ATTRIBUTE_REDUCE_MOTION 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! @brief Theme color attribute.
 | 
					/*! @brief Theme color attribute.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -5949,7 +5962,7 @@ GLFWAPI void glfwThemeSetColor(GLFWtheme* theme,
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @ingroup theme
 | 
					 *  @ingroup theme
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define GLFW_THEME_COLOR_MAIN 4
 | 
					#define GLFW_THEME_COLOR_MAIN 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! @brief Sets the system theme callback.
 | 
					/*! @brief Sets the system theme callback.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -6005,8 +6018,24 @@ GLFWAPI GLFWthemefun glfwSetSystemThemeCallback(GLFWthemefun callback);
 | 
				
			|||||||
GLFWAPI void glfwSetTheme(GLFWwindow* handle, const GLFWtheme* theme);
 | 
					GLFWAPI void glfwSetTheme(GLFWwindow* handle, const GLFWtheme* theme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! @brief Returns the currently active system theme.
 | 
					/*! @brief Returns the currently active system theme.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Executing this yields no changes to a window's theme settings:
 | 
				
			||||||
 | 
					 *  @code
 | 
				
			||||||
 | 
					 *  glfwSetTheme(window, glfwGetTheme(window, GLFW_FALSE))
 | 
				
			||||||
 | 
					 *  @endcode
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Executing this sets a window's theme to the current system theme, and disables
 | 
				
			||||||
 | 
					 *  automatic changes to the window's theme for when the system changes its theme.
 | 
				
			||||||
 | 
					 *  @code
 | 
				
			||||||
 | 
					 *  glfwSetTheme(window, glfwGetTheme(window, GLFW_TRUE))
 | 
				
			||||||
 | 
					 *  @endcode
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @param[in] window The [window](@ref window) to retrieve the current theme for.
 | 
					 *  @param[in] window The [window](@ref window) to retrieve the current theme for.
 | 
				
			||||||
 | 
					 *  @param[in] inlineDefaults Specifies whether or not GLFW should replace unspecified
 | 
				
			||||||
 | 
					 *  theme attributes with the currently active system ones.  If `GLFW_TRUE`, the returned
 | 
				
			||||||
 | 
					 *  theme describes the active style of the window.  If `GLFW_FALSE`, the returned theme
 | 
				
			||||||
 | 
					 *  describes the window's theme settings.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @return A mutable [theme](@ref theme) object, or `NULL` if an
 | 
					 *  @return A mutable [theme](@ref theme) object, or `NULL` if an
 | 
				
			||||||
 *  [error](@ref error_handling) occurred.
 | 
					 *  [error](@ref error_handling) occurred.
 | 
				
			||||||
@ -6027,7 +6056,7 @@ GLFWAPI void glfwSetTheme(GLFWwindow* handle, const GLFWtheme* theme);
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @ingroup theme
 | 
					 *  @ingroup theme
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* handle);
 | 
					GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* handle, int inlineDefaults);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! @brief Returns the currently active system theme.
 | 
					/*! @brief Returns the currently active system theme.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -6051,7 +6080,7 @@ GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* handle);
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @ingroup theme
 | 
					 *  @ingroup theme
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
GLFWAPI GLFWtheme* glfwGetSystemDefaultTheme();
 | 
					GLFWAPI const GLFWtheme* glfwGetSystemDefaultTheme();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! @brief Returns the GLFW time.
 | 
					/*! @brief Returns the GLFW time.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
				
			|||||||
@ -175,7 +175,7 @@ static void createMenuBar(void)
 | 
				
			|||||||
    [NSApp performSelector:setAppleMenuSelector withObject:appMenu];
 | 
					    [NSApp performSelector:setAppleMenuSelector withObject:appMenu];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void nsAppearanceToGLFWTheme(NSAppearance* appearance, _GLFWtheme* theme)
 | 
					void _glfwNSAppearanceToTheme(NSAppearance* appearance, _GLFWtheme* theme)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    NSAppearanceName name;
 | 
					    NSAppearanceName name;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@ -188,10 +188,9 @@ void nsAppearanceToGLFWTheme(NSAppearance* appearance, _GLFWtheme* theme)
 | 
				
			|||||||
            NSAppearanceNameVibrantDark,
 | 
					            NSAppearanceNameVibrantDark,
 | 
				
			||||||
            NSAppearanceNameAccessibilityHighContrastAqua,
 | 
					            NSAppearanceNameAccessibilityHighContrastAqua,
 | 
				
			||||||
            NSAppearanceNameAccessibilityHighContrastDarkAqua,
 | 
					            NSAppearanceNameAccessibilityHighContrastDarkAqua,
 | 
				
			||||||
            NSAppearanceNameAccessibilityHighContrastVibrantLight,
 | 
					 | 
				
			||||||
            NSAppearanceNameAccessibilityHighContrastVibrantDark
 | 
					 | 
				
			||||||
        ]];
 | 
					        ]];
 | 
				
			||||||
    } else {
 | 
					    } else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        name = appearance.name;
 | 
					        name = appearance.name;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@ -205,13 +204,11 @@ void nsAppearanceToGLFWTheme(NSAppearance* appearance, _GLFWtheme* theme)
 | 
				
			|||||||
        if ([name isEqualToString:NSAppearanceNameVibrantLight])
 | 
					        if ([name isEqualToString:NSAppearanceNameVibrantLight])
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            theme->variation = GLFW_THEME_LIGHT;
 | 
					            theme->variation = GLFW_THEME_LIGHT;
 | 
				
			||||||
            theme->flags |= GLFW_THEME_ATTRIBUTE_VIBRANT;
 | 
					 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ([name isEqualToString:NSAppearanceNameVibrantDark])
 | 
					        if ([name isEqualToString:NSAppearanceNameVibrantDark])
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            theme->variation = GLFW_THEME_DARK;
 | 
					            theme->variation = GLFW_THEME_DARK;
 | 
				
			||||||
            theme->flags |= GLFW_THEME_ATTRIBUTE_VIBRANT;
 | 
					 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -235,24 +232,12 @@ void nsAppearanceToGLFWTheme(NSAppearance* appearance, _GLFWtheme* theme)
 | 
				
			|||||||
            theme->flags |= GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST;
 | 
					            theme->flags |= GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST;
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ([name isEqualToString:NSAppearanceNameAccessibilityHighContrastVibrantLight])
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            theme->variation = GLFW_THEME_LIGHT;
 | 
					 | 
				
			||||||
            theme->flags |= GLFW_THEME_ATTRIBUTE_VIBRANT | GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST;
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ([name isEqualToString:NSAppearanceNameAccessibilityHighContrastVibrantDark])
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            theme->variation = GLFW_THEME_DARK;
 | 
					 | 
				
			||||||
            theme->flags |= GLFW_THEME_ATTRIBUTE_VIBRANT | GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST;
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    theme->variation = GLFW_THEME_LIGHT;
 | 
					    theme->variation = GLFW_THEME_LIGHT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void getSystemTheme(_GLFWtheme* theme)
 | 
					void _glfwGetSystemThemeCocoa(_GLFWtheme* theme)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    theme->variation = GLFW_THEME_LIGHT;
 | 
					    theme->variation = GLFW_THEME_LIGHT;
 | 
				
			||||||
    theme->flags = 0;
 | 
					    theme->flags = 0;
 | 
				
			||||||
@ -262,7 +247,7 @@ static void getSystemTheme(_GLFWtheme* theme)
 | 
				
			|||||||
        // effectiveAppearance is actually not the system appearance, but the application appearance.
 | 
					        // 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
 | 
					        // As long as NSApplication.appearance is never set, using the effective appearance is fine
 | 
				
			||||||
        // to get and observe the system appearance.
 | 
					        // to get and observe the system appearance.
 | 
				
			||||||
        nsAppearanceToGLFWTheme(NSApp.effectiveAppearance, theme);
 | 
					        _glfwNSAppearanceToTheme(NSApp.effectiveAppearance, theme);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        NSColor* color = [[NSColor controlAccentColor] colorUsingColorSpace:NSColorSpace.genericRGBColorSpace];
 | 
					        NSColor* color = [[NSColor controlAccentColor] colorUsingColorSpace:NSColorSpace.genericRGBColorSpace];
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@ -272,6 +257,35 @@ static void getSystemTheme(_GLFWtheme* theme)
 | 
				
			|||||||
        theme->color[2] = color.blueComponent;
 | 
					        theme->color[2] = color.blueComponent;
 | 
				
			||||||
        theme->color[3] = color.alphaComponent;
 | 
					        theme->color[3] = color.alphaComponent;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // TODO: return the standard blue accent color if running in 10.13 or earlier.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // TODO: optimize by reading multiple values at once.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    const CFStringRef applicationID = CFSTR("com.apple.universalaccess");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Boolean keyIsValid = false;
 | 
				
			||||||
 | 
					    Boolean highContrast = CFPreferencesGetAppBooleanValue(CFSTR("increaseContrast"),
 | 
				
			||||||
 | 
					                                                           applicationID,
 | 
				
			||||||
 | 
					                                                           &keyIsValid);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (keyIsValid && highContrast)
 | 
				
			||||||
 | 
					        theme->flags |= GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    keyIsValid = false;
 | 
				
			||||||
 | 
					    Boolean reduceTransparency = CFPreferencesGetAppBooleanValue(CFSTR("reduceTransparency"),
 | 
				
			||||||
 | 
					                                                                 applicationID,
 | 
				
			||||||
 | 
					                                                                 &keyIsValid);
 | 
				
			||||||
 | 
					    if (keyIsValid && reduceTransparency)
 | 
				
			||||||
 | 
					        theme->flags |= GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    keyIsValid = false;
 | 
				
			||||||
 | 
					    Boolean reduceMotion = CFPreferencesGetAppBooleanValue(CFSTR("reduceMotion"),
 | 
				
			||||||
 | 
					                                                           applicationID,
 | 
				
			||||||
 | 
					                                                           &keyIsValid);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (keyIsValid && reduceMotion)
 | 
				
			||||||
 | 
					        theme->flags |= GLFW_THEME_ATTRIBUTE_REDUCE_MOTION;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create key code translation tables
 | 
					// Create key code translation tables
 | 
				
			||||||
@ -511,11 +525,16 @@ static GLFWbool initializeTIS(void)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    // This class is never subclassed, so it's safe to ignore the context parameter
 | 
					    // This class is never subclassed, so it's safe to ignore the context parameter
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // TODO: FIXME: this method is invoked twice when the high contrast setting is edited in the preferences.
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    _GLFWtheme theme;
 | 
					    _GLFWtheme theme;
 | 
				
			||||||
    getSystemTheme(&theme);
 | 
					    _glfwGetSystemThemeCocoa(&theme);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    // The observer for the effective appearance is invoked more often than the appearance name itself changes.
 | 
				
			||||||
 | 
					    // For instance, it's invoked when various accesibility settings are changed in the system preferences.
 | 
				
			||||||
 | 
					    // Not all of these properties are included in the GLFW themes, so those updates must be filtered out.
 | 
				
			||||||
 | 
					    if (glfwThemeEqual((GLFWtheme*) &theme, (GLFWtheme*) &_glfw.theme))
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    memcpy(&_glfw.theme, &theme, sizeof(_GLFWtheme));
 | 
				
			||||||
    _glfwInputSystemTheme(&theme);
 | 
					    _glfwInputSystemTheme(&theme);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /*if ([keyPath isEqualToString:@"controlAccentColor"]) {
 | 
					    /*if ([keyPath isEqualToString:@"controlAccentColor"]) {
 | 
				
			||||||
@ -786,6 +805,9 @@ int _glfwInitCocoa(void)
 | 
				
			|||||||
                 context:nil];
 | 
					                 context:nil];
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					    _glfwInitDefaultTheme(&_glfw.theme);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // TODO: add observer for properties other than effectiveAppearance, for observing prior to 10.14. I assume the accesibility options were available then.
 | 
				
			||||||
    if (@available(macOS 10.14, *))
 | 
					    if (@available(macOS 10.14, *))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        [NSApp addObserver:_glfw.ns.helper
 | 
					        [NSApp addObserver:_glfw.ns.helper
 | 
				
			||||||
@ -857,7 +879,7 @@ void _glfwTerminateCocoa(void)
 | 
				
			|||||||
_GLFWtheme* _glfwGetSystemDefaultThemeCocoa(void)
 | 
					_GLFWtheme* _glfwGetSystemDefaultThemeCocoa(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _GLFWtheme* theme = &_glfw.theme;
 | 
					    _GLFWtheme* theme = &_glfw.theme;
 | 
				
			||||||
    getSystemTheme(theme);
 | 
					    _glfwGetSystemThemeCocoa(theme);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return theme;
 | 
					    return theme;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -297,7 +297,8 @@ void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
float _glfwTransformYCocoa(float y);
 | 
					float _glfwTransformYCocoa(float y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void nsAppearanceToGLFWTheme(NSAppearance* appearance, _GLFWtheme* theme);
 | 
					void _glfwNSAppearanceToTheme(NSAppearance* appearance, _GLFWtheme* theme);
 | 
				
			||||||
 | 
					void _glfwGetSystemThemeCocoa(_GLFWtheme* theme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* _glfwLoadLocalVulkanLoaderCocoa(void);
 | 
					void* _glfwLoadLocalVulkanLoaderCocoa(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -308,7 +309,6 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
 | 
				
			|||||||
                                const _GLFWfbconfig* fbconfig);
 | 
					                                const _GLFWfbconfig* fbconfig);
 | 
				
			||||||
void _glfwDestroyContextNSGL(_GLFWwindow* window);
 | 
					void _glfwDestroyContextNSGL(_GLFWwindow* window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
_GLFWtheme* _glfwGetSystemDefaultThemeCocoa(void);
 | 
					_GLFWtheme* _glfwGetSystemDefaultThemeCocoa(void);
 | 
				
			||||||
void _glfwSetThemeCocoa(_GLFWwindow* window, _GLFWtheme* theme);
 | 
					void _glfwSetThemeCocoa(_GLFWwindow* window, const _GLFWtheme* theme);
 | 
				
			||||||
_GLFWtheme* _glfwGetThemeCocoa(_GLFWwindow* window);
 | 
					_GLFWtheme* _glfwGetThemeCocoa(_GLFWwindow* window, int inlineDefaults);
 | 
				
			||||||
 | 
				
			|||||||
@ -1876,19 +1876,22 @@ const char* _glfwGetClipboardStringCocoa(void)
 | 
				
			|||||||
    } // autoreleasepool
 | 
					    } // autoreleasepool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void _glfwSetThemeCocoa(_GLFWwindow* window, _GLFWtheme* theme)
 | 
					// TODO: move
 | 
				
			||||||
 | 
					static void replaceTheme(_GLFWwindow* window, _GLFWtheme* currentTheme, const _GLFWtheme* newTheme)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!theme || theme->variation == GLFW_THEME_DEFAULT)
 | 
					    const int dissimilarFlags = currentTheme->flags ^ newTheme->flags;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (currentTheme->variation != newTheme->variation
 | 
				
			||||||
 | 
					        || (dissimilarFlags & GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (newTheme->variation == GLFW_THEME_DEFAULT)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            [(NSWindow*)window->ns.object setAppearance:nil];
 | 
					            [(NSWindow*)window->ns.object setAppearance:nil];
 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    
 | 
					        else
 | 
				
			||||||
    if (@available(macOS 10.10, *)) {} else
 | 
					        {
 | 
				
			||||||
 | 
					            if (@available(macOS 10.10, *))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
                // TODO: support color
 | 
					                // TODO: support color
 | 
				
			||||||
                // TODO: fix vibrancy
 | 
					                // TODO: fix vibrancy
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
@ -1896,27 +1899,24 @@ void _glfwSetThemeCocoa(_GLFWwindow* window, _GLFWtheme* theme)
 | 
				
			|||||||
                // appearanceNamed: will result in nil, so these can not be used.
 | 
					                // appearanceNamed: will result in nil, so these can not be used.
 | 
				
			||||||
                NSAppearanceName name;
 | 
					                NSAppearanceName name;
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
    if (theme->variation == GLFW_THEME_LIGHT)
 | 
					                if (newTheme->variation == GLFW_THEME_LIGHT)
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (theme->flags & GLFW_THEME_ATTRIBUTE_VIBRANT)
 | 
					 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
 | 
					                    if (newTheme->flags & GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY)
 | 
				
			||||||
                        name = NSAppearanceNameVibrantLight;
 | 
					                        name = NSAppearanceNameVibrantLight;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
                        name = NSAppearanceNameAqua;
 | 
					                        name = NSAppearanceNameAqua;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
        if (theme->flags & GLFW_THEME_ATTRIBUTE_VIBRANT)
 | 
					                    if (newTheme->flags & GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        name = NSAppearanceNameVibrantDark;
 | 
					                        name = NSAppearanceNameVibrantDark;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else if (@available(macOS 10.14, *))
 | 
					                    else if (@available(macOS 10.14, *))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        name = NSAppearanceNameDarkAqua;
 | 
					                        name = NSAppearanceNameDarkAqua;
 | 
				
			||||||
        } else
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        name = NSAppearanceNameAqua;
 | 
					                        name = NSAppearanceNameAqua;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@ -1925,10 +1925,41 @@ void _glfwSetThemeCocoa(_GLFWwindow* window, _GLFWtheme* theme)
 | 
				
			|||||||
                NSAppearance* appearance = [NSAppearance appearanceNamed:name];
 | 
					                NSAppearance* appearance = [NSAppearance appearanceNamed:name];
 | 
				
			||||||
                [(NSWindow*)window->ns.object setAppearance:appearance];
 | 
					                [(NSWindow*)window->ns.object setAppearance:appearance];
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_GLFWtheme* _glfwGetThemeCocoa(_GLFWwindow* window)
 | 
					void _glfwSetThemeCocoa(_GLFWwindow* window, const _GLFWtheme* theme)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _GLFWtheme* theme = &window->theme;
 | 
					    _GLFWtheme* currentTheme = &window->theme.internal;
 | 
				
			||||||
 | 
					    _GLFWtheme newTheme;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!theme)
 | 
				
			||||||
 | 
					        _glfwInitDefaultTheme(&newTheme);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        memcpy(&newTheme, theme, sizeof(_GLFWtheme));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    replaceTheme(window, currentTheme, &newTheme);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    memcpy(currentTheme, &newTheme, sizeof(_GLFWtheme));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Not available for setting in Cocoa.
 | 
				
			||||||
 | 
					    currentTheme->flags &= ~(GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST |
 | 
				
			||||||
 | 
					                             GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY |
 | 
				
			||||||
 | 
					                             GLFW_THEME_ATTRIBUTE_REDUCE_MOTION|
 | 
				
			||||||
 | 
					                             GLFW_THEME_COLOR_MAIN);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // TODO: NSColor controlAccentColor is not settable. Is there any reason in overriding a similar value? Does it apply to menu item highlights? If yes, then it must be overridden.
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_GLFWtheme* _glfwGetThemeCocoa(_GLFWwindow* window, int inlineDefaults)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _GLFWtheme* theme = &window->theme.external;
 | 
				
			||||||
 | 
					    memcpy(theme, &window->theme.internal, sizeof(_GLFWtheme));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // FIXME: fix not overriding specified properties.
 | 
				
			||||||
 | 
					    if (!inlineDefaults)
 | 
				
			||||||
 | 
					        return theme;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    theme->variation = GLFW_THEME_LIGHT;
 | 
					    theme->variation = GLFW_THEME_LIGHT;
 | 
				
			||||||
    theme->flags = 0;
 | 
					    theme->flags = 0;
 | 
				
			||||||
@ -1940,21 +1971,21 @@ _GLFWtheme* _glfwGetThemeCocoa(_GLFWwindow* window)
 | 
				
			|||||||
        if (appearance == NULL)
 | 
					        if (appearance == NULL)
 | 
				
			||||||
            appearance = [NSApp effectiveAppearance];
 | 
					            appearance = [NSApp effectiveAppearance];
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        nsAppearanceToGLFWTheme(appearance, theme);
 | 
					        _glfwNSAppearanceToTheme(appearance, theme);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (@available(macOS 10.14, *)) {
 | 
					    _GLFWtheme systemTheme;
 | 
				
			||||||
        // TODO: this is not settable. Is there any reason in overriding a similar value? Does it apply to menu item highlights? If yes, then it must be overridden.
 | 
					 | 
				
			||||||
        NSColor* color = [[NSColor controlAccentColor] colorUsingColorSpace:NSColorSpace.genericRGBColorSpace];
 | 
					 | 
				
			||||||
        // TODO: Cannot use the accent color directly, for window themes, because the accent color is never overridden.
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        theme->flags |= GLFW_THEME_COLOR_MAIN;
 | 
					    _glfwGetSystemThemeCocoa(&systemTheme);
 | 
				
			||||||
        theme->color[0] = color.redComponent;
 | 
					    
 | 
				
			||||||
        theme->color[1] = color.greenComponent;
 | 
					    if ((theme->flags & GLFW_THEME_COLOR_MAIN) == 0)
 | 
				
			||||||
        theme->color[2] = color.blueComponent;
 | 
					    {
 | 
				
			||||||
        theme->color[3] = color.alphaComponent;
 | 
					        assert(systemTheme.flags & GLFW_THEME_COLOR_MAIN);
 | 
				
			||||||
 | 
					        memcpy(&theme->color, &systemTheme.color, sizeof(float) * 4);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    theme->flags |= systemTheme.flags;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    return theme;
 | 
					    return theme;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -543,7 +543,7 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
 | 
				
			|||||||
    return cbfun;
 | 
					    return cbfun;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLFWAPI GLFWtheme* glfwGetSystemDefaultTheme()
 | 
					GLFWAPI const GLFWtheme* glfwGetSystemDefaultTheme()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _GLFWtheme* theme;
 | 
					    _GLFWtheme* theme;
 | 
				
			||||||
    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
 | 
					    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
 | 
				
			||||||
@ -551,7 +551,7 @@ GLFWAPI GLFWtheme* glfwGetSystemDefaultTheme()
 | 
				
			|||||||
    theme = _glfw.platform.getSystemDefaultTheme();
 | 
					    theme = _glfw.platform.getSystemDefaultTheme();
 | 
				
			||||||
    assert(theme->variation != GLFW_THEME_DEFAULT);
 | 
					    assert(theme->variation != GLFW_THEME_DEFAULT);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return (GLFWtheme*) theme;
 | 
					    return (const GLFWtheme*) theme;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLFWAPI GLFWthemefun glfwSetSystemThemeCallback(GLFWthemefun callback)
 | 
					GLFWAPI GLFWthemefun glfwSetSystemThemeCallback(GLFWthemefun callback)
 | 
				
			||||||
 | 
				
			|||||||
@ -586,8 +586,13 @@ struct _GLFWwindow
 | 
				
			|||||||
        GLFWdropfun               drop;
 | 
					        GLFWdropfun               drop;
 | 
				
			||||||
    } callbacks;
 | 
					    } callbacks;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    struct {
 | 
				
			||||||
        // Clients can mutate this theme data at any time
 | 
					        // Clients can mutate this theme data at any time
 | 
				
			||||||
    _GLFWtheme theme;
 | 
					        _GLFWtheme external;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // The window's user-specified theme settings.
 | 
				
			||||||
 | 
					        _GLFWtheme internal; // TODO: init to defaults on window creation. TODO: set in glfwSetTheme
 | 
				
			||||||
 | 
					    } theme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // This is defined in platform.h
 | 
					    // This is defined in platform.h
 | 
				
			||||||
    GLFW_PLATFORM_WINDOW_STATE
 | 
					    GLFW_PLATFORM_WINDOW_STATE
 | 
				
			||||||
@ -754,8 +759,8 @@ struct _GLFWplatform
 | 
				
			|||||||
    void (*setWindowFloating)(_GLFWwindow*,GLFWbool);
 | 
					    void (*setWindowFloating)(_GLFWwindow*,GLFWbool);
 | 
				
			||||||
    void (*setWindowOpacity)(_GLFWwindow*,float);
 | 
					    void (*setWindowOpacity)(_GLFWwindow*,float);
 | 
				
			||||||
    void (*setWindowMousePassthrough)(_GLFWwindow*,GLFWbool);
 | 
					    void (*setWindowMousePassthrough)(_GLFWwindow*,GLFWbool);
 | 
				
			||||||
    _GLFWtheme* (*getTheme)(_GLFWwindow*);
 | 
					    _GLFWtheme* (*getTheme)(_GLFWwindow*,int);
 | 
				
			||||||
    void (*setTheme)(_GLFWwindow*,_GLFWtheme*);
 | 
					    void (*setTheme)(_GLFWwindow*,const _GLFWtheme*);
 | 
				
			||||||
    // Events
 | 
					    // Events
 | 
				
			||||||
    void (*pollEvents)(void);
 | 
					    void (*pollEvents)(void);
 | 
				
			||||||
    void (*waitEvents)(void);
 | 
					    void (*waitEvents)(void);
 | 
				
			||||||
@ -888,7 +893,6 @@ struct _GLFWlibrary
 | 
				
			|||||||
        GLFWthemefun    theme;
 | 
					        GLFWthemefun    theme;
 | 
				
			||||||
    } callbacks;
 | 
					    } callbacks;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Clients can mutate this theme data at any time
 | 
					 | 
				
			||||||
    _GLFWtheme theme;
 | 
					    _GLFWtheme theme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // These are defined in platform.h
 | 
					    // These are defined in platform.h
 | 
				
			||||||
@ -1035,3 +1039,4 @@ void* _glfw_calloc(size_t count, size_t size);
 | 
				
			|||||||
void* _glfw_realloc(void* pointer, size_t size);
 | 
					void* _glfw_realloc(void* pointer, size_t size);
 | 
				
			||||||
void _glfw_free(void* pointer);
 | 
					void _glfw_free(void* pointer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void _glfwInitDefaultTheme(_GLFWtheme* theme);
 | 
				
			||||||
 | 
				
			|||||||
@ -142,5 +142,10 @@ void _glfwTerminateNull(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
_GLFWtheme* _glfwGetSystemDefaultThemeNull(void)
 | 
					_GLFWtheme* _glfwGetSystemDefaultThemeNull(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return NULL; // TODO: should probably return a colorless GLFWtheme with baseTheme set to GLFW_THEME_LIGHT
 | 
					    _glfwInitDefaultTheme(&_glfw.theme);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // DEFAULT is not a valid return value.
 | 
				
			||||||
 | 
					    _glfw.theme.variation = GLFW_THEME_LIGHT;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return &_glfw.theme;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -148,5 +148,5 @@ VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window,
 | 
				
			|||||||
void _glfwPollMonitorsNull(void);
 | 
					void _glfwPollMonitorsNull(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_GLFWtheme* _glfwGetSystemDefaultThemeNull(void);
 | 
					_GLFWtheme* _glfwGetSystemDefaultThemeNull(void);
 | 
				
			||||||
void _glfwSetThemeNull(_GLFWwindow* window, _GLFWtheme* theme);
 | 
					void _glfwSetThemeNull(_GLFWwindow* window, const _GLFWtheme* theme);
 | 
				
			||||||
_GLFWtheme* _glfwGetThemeNull(_GLFWwindow* window);
 | 
					_GLFWtheme* _glfwGetThemeNull(_GLFWwindow* window, int inlineDefaults);
 | 
				
			||||||
 | 
				
			|||||||
@ -551,13 +551,16 @@ const char* _glfwGetClipboardStringNull(void)
 | 
				
			|||||||
    return _glfw.null.clipboardString;
 | 
					    return _glfw.null.clipboardString;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void _glfwSetThemeNull(_GLFWwindow* window, _GLFWtheme* theme)
 | 
					void _glfwSetThemeNull(_GLFWwindow* window, const _GLFWtheme* theme)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(&window->theme.internal, theme, sizeof(_GLFWtheme));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_GLFWtheme* _glfwGetThemeNull(_GLFWwindow* window)
 | 
					_GLFWtheme* _glfwGetThemeNull(_GLFWwindow* window, int inlineDefaults)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return NULL; // TODO: see to-do in _glfwGetSystemDefaultThemeNull
 | 
					    memcpy(&window->theme.external, &window->theme.internal, sizeof(_GLFWtheme));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return &window->theme.external;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
 | 
					EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										56
									
								
								src/theme.c
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								src/theme.c
									
									
									
									
									
								
							@ -31,12 +31,25 @@
 | 
				
			|||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GLFWbool attributesAreValid(int attributes)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (attributes & ~(GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST |
 | 
				
			||||||
 | 
					                           GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY |
 | 
				
			||||||
 | 
					                           GLFW_THEME_ATTRIBUTE_REDUCE_MOTION |
 | 
				
			||||||
 | 
					                           GLFW_THEME_COLOR_MAIN)) == 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void _glfwInitDefaultTheme(_GLFWtheme* theme)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    theme->variation = GLFW_THEME_DEFAULT;
 | 
				
			||||||
 | 
					    theme->flags = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLFWAPI GLFWtheme* glfwCreateTheme(void)
 | 
					GLFWAPI GLFWtheme* glfwCreateTheme(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _GLFWtheme* theme = _glfw_calloc(1, sizeof(_GLFWtheme));
 | 
					    _GLFWtheme* theme = _glfw_calloc(1, sizeof(_GLFWtheme));
 | 
				
			||||||
    
 | 
					    _glfwInitDefaultTheme(theme);
 | 
				
			||||||
    theme->variation = GLFW_THEME_DEFAULT;
 | 
					 | 
				
			||||||
    theme->flags = 0;
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return (GLFWtheme*) theme;
 | 
					    return (GLFWtheme*) theme;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -51,6 +64,23 @@ GLFWAPI void glfwCopyTheme(const GLFWtheme* source, GLFWtheme* target)
 | 
				
			|||||||
    memcpy(target, source, sizeof(_GLFWtheme));
 | 
					    memcpy(target, source, sizeof(_GLFWtheme));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GLFWAPI int glfwThemeEqual(const GLFWtheme* first, const GLFWtheme* second)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _GLFWtheme* _first = (_GLFWtheme*) first;
 | 
				
			||||||
 | 
					    _GLFWtheme* _second = (_GLFWtheme*) second;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (_first->variation != _second->variation)
 | 
				
			||||||
 | 
					        return GLFW_FALSE;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (_first->flags != _second->flags)
 | 
				
			||||||
 | 
					        return GLFW_FALSE;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (_first->flags & GLFW_THEME_COLOR_MAIN)
 | 
				
			||||||
 | 
					        return memcmp(&_first->color, &_second->color, sizeof(float) * 4);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    return GLFW_TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLFWAPI int glfwThemeGetVariation(const GLFWtheme* theme)
 | 
					GLFWAPI int glfwThemeGetVariation(const GLFWtheme* theme)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(theme != NULL);
 | 
					    assert(theme != NULL);
 | 
				
			||||||
@ -68,22 +98,18 @@ GLFWAPI void glfwThemeSetVariation(GLFWtheme* theme, int value)
 | 
				
			|||||||
GLFWAPI int glfwThemeGetAttribute(const GLFWtheme* theme, int attribute)
 | 
					GLFWAPI int glfwThemeGetAttribute(const GLFWtheme* theme, int attribute)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(theme != NULL);
 | 
					    assert(theme != NULL);
 | 
				
			||||||
    assert((attribute & ~(GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST |
 | 
					    assert(attributesAreValid(attribute));
 | 
				
			||||||
                          GLFW_THEME_ATTRIBUTE_VIBRANT |
 | 
					 | 
				
			||||||
                          GLFW_THEME_COLOR_MAIN)) == 0);
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return ((_GLFWtheme*) theme)->flags & attribute ? GLFW_TRUE : GLFW_FALSE;
 | 
					    return ((_GLFWtheme*) theme)->flags & attribute ? GLFW_TRUE : GLFW_FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLFWAPI void glfwThemeSetAttribute(GLFWtheme* theme, int attribute, int value)
 | 
					GLFWAPI void glfwThemeSetAttribute(GLFWtheme* theme, int attribute, int value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    _GLFWtheme* _theme = (_GLFWtheme*) theme;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    assert(theme != NULL);
 | 
					    assert(theme != NULL);
 | 
				
			||||||
    assert(value == GLFW_TRUE || value == GLFW_FALSE);
 | 
					    assert(value == GLFW_TRUE || value == GLFW_FALSE);
 | 
				
			||||||
    assert((attribute & ~(GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST |
 | 
					    assert(attributesAreValid(attribute));
 | 
				
			||||||
                          GLFW_THEME_ATTRIBUTE_VIBRANT |
 | 
					 | 
				
			||||||
                          GLFW_THEME_COLOR_MAIN)) == 0);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    _GLFWtheme* _theme = (_GLFWtheme*) theme;
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (value == GLFW_TRUE)
 | 
					    if (value == GLFW_TRUE)
 | 
				
			||||||
        _theme->flags |= attribute;
 | 
					        _theme->flags |= attribute;
 | 
				
			||||||
@ -93,12 +119,12 @@ GLFWAPI void glfwThemeSetAttribute(GLFWtheme* theme, int attribute, int value)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
GLFWAPI void glfwThemeGetColor(const GLFWtheme* theme, int specifier, float* red, float* green, float* blue, float* alpha)
 | 
					GLFWAPI void glfwThemeGetColor(const GLFWtheme* theme, int specifier, float* red, float* green, float* blue, float* alpha)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    const float* color = ((_GLFWtheme*) theme)->color;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    assert(theme != NULL);
 | 
					    assert(theme != NULL);
 | 
				
			||||||
    assert(specifier == GLFW_THEME_COLOR_MAIN);
 | 
					    assert(specifier == GLFW_THEME_COLOR_MAIN);
 | 
				
			||||||
    assert(red != NULL && green != NULL && blue != NULL && alpha != NULL);
 | 
					    assert(red != NULL && green != NULL && blue != NULL && alpha != NULL);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    const float* color = ((_GLFWtheme*) theme)->color;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    *red   = color[0];
 | 
					    *red   = color[0];
 | 
				
			||||||
    *green = color[1];
 | 
					    *green = color[1];
 | 
				
			||||||
    *blue  = color[2];
 | 
					    *blue  = color[2];
 | 
				
			||||||
@ -107,11 +133,11 @@ GLFWAPI void glfwThemeGetColor(const GLFWtheme* theme, int specifier, float* red
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
GLFWAPI void glfwThemeSetColor(GLFWtheme* theme, int specifier, float red, float green, float blue, float alpha)
 | 
					GLFWAPI void glfwThemeSetColor(GLFWtheme* theme, int specifier, float red, float green, float blue, float alpha)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    float* color = ((_GLFWtheme*) theme)->color;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    assert(theme != NULL);
 | 
					    assert(theme != NULL);
 | 
				
			||||||
    assert(specifier == GLFW_THEME_COLOR_MAIN);
 | 
					    assert(specifier == GLFW_THEME_COLOR_MAIN);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    float* color = ((_GLFWtheme*) theme)->color;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    color[0] = red;
 | 
					    color[0] = red;
 | 
				
			||||||
    color[1] = green;
 | 
					    color[1] = green;
 | 
				
			||||||
    color[2] = blue;
 | 
					    color[2] = blue;
 | 
				
			||||||
 | 
				
			|||||||
@ -642,5 +642,5 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
 | 
				
			|||||||
                               const _GLFWfbconfig* fbconfig);
 | 
					                               const _GLFWfbconfig* fbconfig);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_GLFWtheme* _glfwGetSystemDefaultThemeWin32(void);
 | 
					_GLFWtheme* _glfwGetSystemDefaultThemeWin32(void);
 | 
				
			||||||
void _glfwSetThemeWin32(_GLFWwindow* window, _GLFWtheme* theme);
 | 
					void _glfwSetThemeWin32(_GLFWwindow* window, const _GLFWtheme* theme);
 | 
				
			||||||
_GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window);
 | 
					_GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window, int inlineDefaults);
 | 
				
			||||||
 | 
				
			|||||||
@ -56,12 +56,11 @@ static void applySystemTheme(HWND handle)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void getAccentColor(float color[4])
 | 
					
 | 
				
			||||||
 | 
					static int getAccentColor(float color[4])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!_glfw.win32.uxtheme.uxThemeAvailable)
 | 
					    if (!_glfw.win32.uxtheme.uxThemeAvailable)
 | 
				
			||||||
    {
 | 
					        return GLFW_FALSE;
 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    UINT dwImmersiveColorType = _glfw.win32.uxtheme.GetImmersiveColorTypeFromName(L"ImmersiveSystemAccent");
 | 
					    UINT dwImmersiveColorType = _glfw.win32.uxtheme.GetImmersiveColorTypeFromName(L"ImmersiveSystemAccent");
 | 
				
			||||||
    UINT dwImmersiveColorSet = _glfw.win32.uxtheme.GetImmersiveUserColorSetPreference(FALSE, FALSE);
 | 
					    UINT dwImmersiveColorSet = _glfw.win32.uxtheme.GetImmersiveUserColorSetPreference(FALSE, FALSE);
 | 
				
			||||||
@ -71,10 +70,12 @@ static void getAccentColor(float color[4])
 | 
				
			|||||||
                                                                    FALSE,
 | 
					                                                                    FALSE,
 | 
				
			||||||
                                                                    0);
 | 
					                                                                    0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    color[0] = (0xFF & rgba);
 | 
					    color[0] = (double) (0xFF & rgba);
 | 
				
			||||||
    color[1] = ((0xFF00 & rgba) >> 8) ;
 | 
					    color[1] = (double) ((0xFF00 & rgba) >> 8);
 | 
				
			||||||
    color[2] = ((0xFF0000 & rgba) >> 16);
 | 
					    color[2] = (double) ((0xFF0000 & rgba) >> 16);
 | 
				
			||||||
    color[3] = ((0xFF000000 & rgba) >> 24);
 | 
					    color[3] = (double) ((0xFF000000 & rgba) >> 24);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return GLFW_TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns the window style for the specified window
 | 
					// Returns the window style for the specified window
 | 
				
			||||||
@ -2423,7 +2424,7 @@ const char* _glfwGetClipboardStringWin32(void)
 | 
				
			|||||||
    return _glfw.win32.clipboardString;
 | 
					    return _glfw.win32.clipboardString;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void _glfwSetThemeWin32(_GLFWwindow* window, _GLFWtheme* theme)
 | 
					void _glfwSetThemeWin32(_GLFWwindow* window, const _GLFWtheme* theme)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!theme || theme->variation == GLFW_THEME_DEFAULT)
 | 
					    if (!theme || theme->variation == GLFW_THEME_DEFAULT)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -2437,22 +2438,34 @@ void _glfwSetThemeWin32(_GLFWwindow* window, _GLFWtheme* theme)
 | 
				
			|||||||
                          DWMWA_USE_IMMERSIVE_DARK_MODE,
 | 
					                          DWMWA_USE_IMMERSIVE_DARK_MODE,
 | 
				
			||||||
                          &darkMode,
 | 
					                          &darkMode,
 | 
				
			||||||
                          sizeof(darkMode));
 | 
					                          sizeof(darkMode));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // TODO: set accent color
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window)
 | 
					_GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window, int inlineDefaults)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _GLFWtheme* theme = &window->theme;
 | 
					    _GLFWtheme* theme = &window->theme.external;
 | 
				
			||||||
 | 
					    memcpy(theme, &window->theme.internal, sizeof(_GLFWtheme));
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    // FIXME: fix not overriding specified properties.
 | 
				
			||||||
 | 
					    if (!inlineDefaults)
 | 
				
			||||||
 | 
					        return theme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (theme->variation == GLFW_THEME_DEFAULT)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        theme->variation = GLFW_THEME_LIGHT;
 | 
					        theme->variation = GLFW_THEME_LIGHT;
 | 
				
			||||||
    theme->flags = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (_glfw.win32.uxtheme.uxThemeAvailable && _glfw.win32.uxtheme.darkTitleAvailable)
 | 
					        if (_glfw.win32.uxtheme.uxThemeAvailable && _glfw.win32.uxtheme.darkTitleAvailable)
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
            theme->variation = GLFW_THEME_DARK;
 | 
					            theme->variation = GLFW_THEME_DARK;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    memset(theme->color, 0, sizeof(float) * 4);
 | 
					    if ((theme->flags & GLFW_THEME_COLOR_MAIN) == 0)
 | 
				
			||||||
    getAccentColor(theme->color);
 | 
					    {
 | 
				
			||||||
 | 
					        if (getAccentColor(&theme->color))
 | 
				
			||||||
 | 
					            theme->flags |= GLFW_THEME_COLOR_MAIN;
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            memset(&theme->color, 0, sizeof(float) * 4);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return theme;
 | 
					    return theme;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -245,6 +245,8 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
 | 
				
			|||||||
    window->numer       = GLFW_DONT_CARE;
 | 
					    window->numer       = GLFW_DONT_CARE;
 | 
				
			||||||
    window->denom       = GLFW_DONT_CARE;
 | 
					    window->denom       = GLFW_DONT_CARE;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    _glfwInitDefaultTheme(&window->theme.internal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!_glfw.platform.createWindow(window, &wndconfig, &ctxconfig, &fbconfig))
 | 
					    if (!_glfw.platform.createWindow(window, &wndconfig, &ctxconfig, &fbconfig))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        glfwDestroyWindow((GLFWwindow*) window);
 | 
					        glfwDestroyWindow((GLFWwindow*) window);
 | 
				
			||||||
@ -1163,11 +1165,11 @@ GLFWAPI void glfwSetTheme(GLFWwindow* handle, const GLFWtheme* theme)
 | 
				
			|||||||
    _glfw.platform.setTheme(window, (_GLFWtheme*) theme);
 | 
					    _glfw.platform.setTheme(window, (_GLFWtheme*) theme);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* handle)
 | 
					GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* handle, int inlineDefaults)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _GLFWwindow* window = (_GLFWwindow*) handle;
 | 
					    _GLFWwindow* window = (_GLFWwindow*) handle;
 | 
				
			||||||
    assert(window != NULL);
 | 
					    assert(window != NULL);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
 | 
					    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
 | 
				
			||||||
    return (GLFWtheme*) _glfw.platform.getTheme(window);
 | 
					    return (GLFWtheme*) _glfw.platform.getTheme(window, inlineDefaults);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -520,5 +520,5 @@ void _glfwAddSeatListenerWayland(struct wl_seat* seat);
 | 
				
			|||||||
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
 | 
					void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_GLFWtheme* _glfwGetSystemDefaultThemeWayland(void);
 | 
					_GLFWtheme* _glfwGetSystemDefaultThemeWayland(void);
 | 
				
			||||||
void _glfwSetThemeWayland(_GLFWwindow* window, _GLFWtheme* theme);
 | 
					void _glfwSetThemeWayland(_GLFWwindow* window, const _GLFWtheme* theme);
 | 
				
			||||||
_GLFWtheme* _glfwGetThemeWayland(_GLFWwindow* window);
 | 
					_GLFWtheme* _glfwGetThemeWayland(_GLFWwindow* window, int inlineDefaults);
 | 
				
			||||||
 | 
				
			|||||||
@ -2780,7 +2780,7 @@ void _glfwSetThemeWayland(_GLFWwindow* window, _GLFWtheme* theme)
 | 
				
			|||||||
    _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
 | 
					    _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_GLFWtheme* _glfwGetThemeWayland(_GLFWwindow* window)
 | 
					_GLFWtheme* _glfwGetThemeWayland(_GLFWwindow* window, int inlineDefaults)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
 | 
					    _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
 | 
				
			||||||
    return NULL; // TODO: implement
 | 
					    return NULL; // TODO: implement
 | 
				
			||||||
 | 
				
			|||||||
@ -1003,5 +1003,5 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
 | 
				
			|||||||
                              Visual** visual, int* depth);
 | 
					                              Visual** visual, int* depth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_GLFWtheme* _glfwGetSystemDefaultThemeX11(void);
 | 
					_GLFWtheme* _glfwGetSystemDefaultThemeX11(void);
 | 
				
			||||||
void _glfwSetThemeX11(_GLFWwindow* window, _GLFWtheme* theme);
 | 
					void _glfwSetThemeX11(_GLFWwindow* window, const _GLFWtheme* theme);
 | 
				
			||||||
_GLFWtheme* _glfwGetThemeX11(_GLFWwindow* window);
 | 
					_GLFWtheme* _glfwGetThemeX11(_GLFWwindow* window, int inlineDefaults);
 | 
				
			||||||
 | 
				
			|||||||
@ -3082,12 +3082,12 @@ const char* _glfwGetClipboardStringX11(void)
 | 
				
			|||||||
    return getSelectionString(_glfw.x11.CLIPBOARD);
 | 
					    return getSelectionString(_glfw.x11.CLIPBOARD);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void _glfwSetThemeX11(_GLFWwindow* window, _GLFWtheme* theme)
 | 
					void _glfwSetThemeX11(_GLFWwindow* window, const _GLFWtheme* theme)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
 | 
					    _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_GLFWtheme* _glfwGetThemeX11(_GLFWwindow* window)
 | 
					_GLFWtheme* _glfwGetThemeX11(_GLFWwindow* window, int inlineDefaults)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
 | 
					    _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
 | 
				
			||||||
    return NULL; // TODO: implement
 | 
					    return NULL; // TODO: implement
 | 
				
			||||||
 | 
				
			|||||||
@ -50,26 +50,29 @@ static int cur_theme_color = 0;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static GLFWtheme* theme;
 | 
					static GLFWtheme* theme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void print_theme(GLFWtheme* theme, const char* title)
 | 
					static void print_theme(const GLFWtheme* theme, const char* title)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int n = 0;
 | 
					    int n = 0;
 | 
				
			||||||
 | 
					    int variation = glfwThemeGetVariation(theme);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    printf("%s: {\n", title);
 | 
					    printf("%s: {\n", title);
 | 
				
			||||||
    printf("    Variation: %s\n", glfwThemeGetVariation(theme) == GLFW_THEME_LIGHT ? "light" : "dark");
 | 
					    printf("    Variation: %s\n", variation == GLFW_THEME_DEFAULT ? "default" : variation == GLFW_THEME_LIGHT ? "light" : "dark");
 | 
				
			||||||
    printf("    Attributes: [");
 | 
					    printf("    Attributes: [");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    if (glfwThemeGetAttribute(theme, GLFW_THEME_COLOR_MAIN))
 | 
					    if (glfwThemeGetAttribute(theme, GLFW_THEME_COLOR_MAIN))
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        printf(n++ > 0 ? ", %s" : "%s", "COLOR_MAIN");
 | 
					        printf(n++ > 0 ? ", %s" : "%s", "COLOR_MAIN");
 | 
				
			||||||
    }
 | 
					    
 | 
				
			||||||
    if (glfwThemeGetAttribute(theme, GLFW_THEME_ATTRIBUTE_VIBRANT))
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        printf(n++ > 0 ? ", %s" : "%s", "VIBRANT");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (glfwThemeGetAttribute(theme, GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST))
 | 
					    if (glfwThemeGetAttribute(theme, GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST))
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        printf(n++ > 0 ? ", %s" : "%s", "HIGH_CONTRAST");
 | 
					        printf(n++ > 0 ? ", %s" : "%s", "HIGH_CONTRAST");
 | 
				
			||||||
    }
 | 
					    
 | 
				
			||||||
 | 
					    if (glfwThemeGetAttribute(theme, GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY))
 | 
				
			||||||
 | 
					        printf(n++ > 0 ? ", %s" : "%s", "REDUCE_TRANSPARENCY");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (glfwThemeGetAttribute(theme, GLFW_THEME_ATTRIBUTE_REDUCE_MOTION))
 | 
				
			||||||
 | 
					        printf(n++ > 0 ? ", %s" : "%s", "REDUCE_MOTION");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    printf("]\n");
 | 
					    printf("]\n");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    if (glfwThemeGetAttribute(theme, GLFW_THEME_COLOR_MAIN))
 | 
					    if (glfwThemeGetAttribute(theme, GLFW_THEME_COLOR_MAIN))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        float r, g, b, a;
 | 
					        float r, g, b, a;
 | 
				
			||||||
@ -90,7 +93,7 @@ static void set_theme(GLFWwindow* window, int theme_color)
 | 
				
			|||||||
            theme_colors[theme_color][3]
 | 
					            theme_colors[theme_color][3]
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (theme_color == 6)
 | 
					    if (theme_color == 5)
 | 
				
			||||||
        glfwThemeSetAttribute(theme, GLFW_THEME_COLOR_MAIN, GLFW_FALSE);
 | 
					        glfwThemeSetAttribute(theme, GLFW_THEME_COLOR_MAIN, GLFW_FALSE);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        glfwThemeSetAttribute(theme, GLFW_THEME_COLOR_MAIN, GLFW_TRUE);
 | 
					        glfwThemeSetAttribute(theme, GLFW_THEME_COLOR_MAIN, GLFW_TRUE);
 | 
				
			||||||
@ -113,6 +116,11 @@ static void set_theme(GLFWwindow* window, int theme_color)
 | 
				
			|||||||
    glfwSetTheme(window, theme);
 | 
					    glfwSetTheme(window, theme);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void flip_attribute(int attribute)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    glfwThemeSetAttribute(theme, attribute, !glfwThemeGetAttribute(theme, attribute));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
 | 
					static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (action != GLFW_PRESS)
 | 
					    if (action != GLFW_PRESS)
 | 
				
			||||||
@ -120,31 +128,59 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    switch (key)
 | 
					    switch (key)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        // No theme specified
 | 
				
			||||||
        case GLFW_KEY_0:
 | 
					        case GLFW_KEY_0:
 | 
				
			||||||
            glfwSetWindowTitle(window, "Default theme (NULL)");
 | 
					            glfwSetWindowTitle(window, "Default theme (NULL)");
 | 
				
			||||||
            glfwSetTheme(window, NULL);
 | 
					            glfwSetTheme(window, NULL);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        // Theme with default variation
 | 
				
			||||||
        case GLFW_KEY_1:
 | 
					        case GLFW_KEY_1:
 | 
				
			||||||
            glfwThemeSetVariation(theme, GLFW_THEME_DEFAULT);
 | 
					            glfwThemeSetVariation(theme, GLFW_THEME_DEFAULT);
 | 
				
			||||||
            set_theme(window, cur_theme_color);
 | 
					            set_theme(window, cur_theme_color);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        // Theme with light variation
 | 
				
			||||||
        case GLFW_KEY_2:
 | 
					        case GLFW_KEY_2:
 | 
				
			||||||
            glfwThemeSetVariation(theme, GLFW_THEME_LIGHT);
 | 
					            glfwThemeSetVariation(theme, GLFW_THEME_LIGHT);
 | 
				
			||||||
            set_theme(window, cur_theme_color);
 | 
					            set_theme(window, cur_theme_color);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        // Theme with dark variation
 | 
				
			||||||
        case GLFW_KEY_3:
 | 
					        case GLFW_KEY_3:
 | 
				
			||||||
            glfwThemeSetVariation(theme, GLFW_THEME_DARK);
 | 
					            glfwThemeSetVariation(theme, GLFW_THEME_DARK);
 | 
				
			||||||
            set_theme(window, cur_theme_color);
 | 
					            set_theme(window, cur_theme_color);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case GLFW_KEY_ESCAPE:
 | 
					        // Traverse colors
 | 
				
			||||||
            glfwSetWindowShouldClose(window, GLFW_TRUE);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case GLFW_KEY_SPACE:
 | 
					        case GLFW_KEY_SPACE:
 | 
				
			||||||
            cur_theme_color = (cur_theme_color + 1) % 6;
 | 
					            cur_theme_color = (cur_theme_color + 1) % 6;
 | 
				
			||||||
            set_theme(window, cur_theme_color);
 | 
					            set_theme(window, cur_theme_color);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        // Inspect
 | 
				
			||||||
 | 
					        case GLFW_KEY_I:
 | 
				
			||||||
 | 
					            print_theme(theme, "Constructed theme");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        // Print
 | 
				
			||||||
        case GLFW_KEY_P:
 | 
					        case GLFW_KEY_P:
 | 
				
			||||||
            print_theme(glfwGetTheme(window), "Window theme");
 | 
					            print_theme(glfwGetTheme(window, GLFW_FALSE), "Specified window theme");
 | 
				
			||||||
 | 
					            print_theme(glfwGetTheme(window, GLFW_TRUE), "Active window theme");
 | 
				
			||||||
 | 
					            printf("\n");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        // High contrast
 | 
				
			||||||
 | 
					        case GLFW_KEY_H:
 | 
				
			||||||
 | 
					            flip_attribute(GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST);
 | 
				
			||||||
 | 
					            set_theme(window, cur_theme_color);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        // Transparency
 | 
				
			||||||
 | 
					        case GLFW_KEY_T:
 | 
				
			||||||
 | 
					            flip_attribute(GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY);
 | 
				
			||||||
 | 
					            set_theme(window, cur_theme_color);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        // Motion
 | 
				
			||||||
 | 
					        case GLFW_KEY_M:
 | 
				
			||||||
 | 
					            flip_attribute(GLFW_THEME_ATTRIBUTE_REDUCE_MOTION);
 | 
				
			||||||
 | 
					            set_theme(window, cur_theme_color);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        // Exit
 | 
				
			||||||
 | 
					        case GLFW_KEY_ESCAPE:
 | 
				
			||||||
 | 
					            glfwSetWindowShouldClose(window, GLFW_TRUE);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -175,6 +211,10 @@ int main(int argc, char** argv)
 | 
				
			|||||||
        exit(EXIT_FAILURE);
 | 
					        exit(EXIT_FAILURE);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    print_theme(glfwGetTheme(window, GLFW_FALSE), "Initial specified window theme");
 | 
				
			||||||
 | 
					    print_theme(glfwGetTheme(window, GLFW_TRUE), "Initial active window theme");
 | 
				
			||||||
 | 
					    printf("\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    glfwMakeContextCurrent(window);
 | 
					    glfwMakeContextCurrent(window);
 | 
				
			||||||
    gladLoadGL(glfwGetProcAddress);
 | 
					    gladLoadGL(glfwGetProcAddress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user