mirror of
https://github.com/glfw/glfw.git
synced 2025-06-07 16:24:57 +00:00
Merge 14eea06345
into b4c3ef9d0f
This commit is contained in:
commit
3688ac6839
@ -33,6 +33,7 @@ video tutorials.
|
|||||||
- David Carlier
|
- David Carlier
|
||||||
- Arturo Castro
|
- Arturo Castro
|
||||||
- Chi-kwan Chan
|
- Chi-kwan Chan
|
||||||
|
- Haoyun Chen
|
||||||
- TheChocolateOre
|
- TheChocolateOre
|
||||||
- Ali Chraghi
|
- Ali Chraghi
|
||||||
- Joseph Chua
|
- Joseph Chua
|
||||||
@ -103,6 +104,7 @@ video tutorials.
|
|||||||
- IntellectualKitty
|
- IntellectualKitty
|
||||||
- Aaron Jacobs
|
- Aaron Jacobs
|
||||||
- JannikGM
|
- JannikGM
|
||||||
|
- Andreas O. Jansen
|
||||||
- Erik S. V. Jansson
|
- Erik S. V. Jansson
|
||||||
- jjYBdx4IL
|
- jjYBdx4IL
|
||||||
- Peter Johnson
|
- Peter Johnson
|
||||||
|
@ -1404,6 +1404,18 @@ typedef struct GLFWwindow GLFWwindow;
|
|||||||
*/
|
*/
|
||||||
typedef struct GLFWcursor GLFWcursor;
|
typedef struct GLFWcursor GLFWcursor;
|
||||||
|
|
||||||
|
/*! @brief Opaque theme object.
|
||||||
|
*
|
||||||
|
* Opaque theme object.
|
||||||
|
*
|
||||||
|
* @see @ref theme_object
|
||||||
|
*
|
||||||
|
* @since Added in version 3.4.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
typedef struct GLFWtheme GLFWtheme;
|
||||||
|
|
||||||
/*! @brief The function pointer type for memory allocation callbacks.
|
/*! @brief The function pointer type for memory allocation callbacks.
|
||||||
*
|
*
|
||||||
* This is the function pointer type for memory allocation callbacks. A memory
|
* This is the function pointer type for memory allocation callbacks. A memory
|
||||||
@ -1974,6 +1986,28 @@ typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event);
|
|||||||
*/
|
*/
|
||||||
typedef void (* GLFWjoystickfun)(int jid, int event);
|
typedef void (* GLFWjoystickfun)(int jid, int event);
|
||||||
|
|
||||||
|
/*! @brief The function pointer type for system theme callbacks.
|
||||||
|
*
|
||||||
|
* This is the function pointer type for system theme callbacks. A system
|
||||||
|
* theme callback function has the following signature:
|
||||||
|
* @code
|
||||||
|
* void function_name(GLFWtheme* theme)
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @param[in] theme The new system theme.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The theme is valid until the callback
|
||||||
|
* function returns.
|
||||||
|
*
|
||||||
|
* @sa @ref theme
|
||||||
|
* @sa @ref glfwSetSystemThemeCallback
|
||||||
|
*
|
||||||
|
* @since Added in version 3.4.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
typedef void (* GLFWthemefun)(GLFWtheme* theme);
|
||||||
|
|
||||||
/*! @brief Video mode type.
|
/*! @brief Video mode type.
|
||||||
*
|
*
|
||||||
* This describes a single video mode.
|
* This describes a single video mode.
|
||||||
@ -5858,6 +5892,209 @@ 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 void glfwDestroyTheme(GLFWtheme* theme);
|
||||||
|
GLFWAPI void glfwCopyTheme(const GLFWtheme* source, GLFWtheme* target);
|
||||||
|
GLFWAPI int glfwThemeEqual(const GLFWtheme* first, const GLFWtheme* second);
|
||||||
|
|
||||||
|
GLFWAPI int glfwThemeGetVariation(const GLFWtheme* theme);
|
||||||
|
GLFWAPI void glfwThemeSetVariation(GLFWtheme* theme, int value);
|
||||||
|
|
||||||
|
GLFWAPI int glfwThemeGetAttribute(const GLFWtheme* theme, int attribute);
|
||||||
|
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,
|
||||||
|
int specifier,
|
||||||
|
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,
|
||||||
|
int specifier,
|
||||||
|
float red, float green, float blue, float alpha);
|
||||||
|
|
||||||
|
/*! @brief Theme variation type.
|
||||||
|
*
|
||||||
|
* Specifies that a theme is of a dark variation.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
#define GLFW_THEME_DARK -1
|
||||||
|
|
||||||
|
/*! @brief Theme variation type.
|
||||||
|
*
|
||||||
|
* Specifies that a theme has no specific variation.
|
||||||
|
* This is an invalid value for themes returned by GLFW, but this
|
||||||
|
* variation can be set to make GLFW use the default system theme when
|
||||||
|
* applying a user-specified theme.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
#define GLFW_THEME_DEFAULT 0
|
||||||
|
|
||||||
|
/*! @brief Theme variation type.
|
||||||
|
*
|
||||||
|
* Specifies that a theme is of a light variation.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
#define GLFW_THEME_LIGHT 1
|
||||||
|
|
||||||
|
/*! @brief Theme attribute.
|
||||||
|
*
|
||||||
|
* Specifies that a theme uses a high contrast mode.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
#define GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST 1
|
||||||
|
|
||||||
|
/*! @brief Theme attribute.
|
||||||
|
*
|
||||||
|
* Specifies that a theme requests reduced transparency.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
#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.
|
||||||
|
*
|
||||||
|
* This is both an attribute and color specifier. As an attribute, it specifies
|
||||||
|
* if this color is present in the theme or not. If this attribute is set on a theme
|
||||||
|
* returned by GLFW, that theme contains this color. If this attribute is set on a
|
||||||
|
* theme supplied to GLFW, GLFW applies this color if the platform supports it.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
#define GLFW_THEME_COLOR_MAIN 8
|
||||||
|
|
||||||
|
/*! @brief Sets the system theme callback.
|
||||||
|
*
|
||||||
|
* This function sets the system theme callback, or removes the
|
||||||
|
* currently set callback. This is called when the system theme changes,
|
||||||
|
* either because the user edited it, or the system automatically changed it.
|
||||||
|
*
|
||||||
|
* @param[in] callback The new callback, or `NULL` to remove the currently set
|
||||||
|
* callback.
|
||||||
|
* @return The previously set callback, or `NULL` if no callback was set or the
|
||||||
|
* library had not been [initialized](@ref intro_init).
|
||||||
|
*
|
||||||
|
* @callback_signature
|
||||||
|
* @code
|
||||||
|
* void function_name(GLFWtheme* theme)
|
||||||
|
* @endcode
|
||||||
|
* For more information about the callback parameters, see the
|
||||||
|
* [function pointer type](@ref GLFWthemefun).
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref theme_event
|
||||||
|
*
|
||||||
|
* @since Added in version 3.4.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
GLFWAPI GLFWthemefun glfwSetSystemThemeCallback(GLFWthemefun callback);
|
||||||
|
|
||||||
|
/*! @brief Sets the theme for a window.
|
||||||
|
*
|
||||||
|
* @param[in] window The [window](@ref window) to set the theme for.
|
||||||
|
* @param[in] theme The [theme](@ref theme) to set. Pass `NULL` to set it to the system default.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED,
|
||||||
|
* and @ref GLFW_FEATURE_UNIMPLEMENTED.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The returned theme is allocated and freed by GLFW. You
|
||||||
|
* should not free it yourself. It is valid until this function or @ref glfwGetTheme
|
||||||
|
* is called again for the specified window, or the window is destroyed.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref theme
|
||||||
|
* @sa @ref glfwGetTheme
|
||||||
|
*
|
||||||
|
* @since Added in version 3.4.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
GLFWAPI void glfwSetTheme(GLFWwindow* handle, const GLFWtheme* 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] 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
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED,
|
||||||
|
* and @ref GLFW_FEATURE_UNIMPLEMENTED.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The returned theme is allocated and freed by GLFW. You
|
||||||
|
* should not free it yourself. It is valid until this function or @ref glfwSetTheme
|
||||||
|
* is called again for the specified window, or the window is destroyed.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref theme
|
||||||
|
* @sa @ref glfwSetTheme
|
||||||
|
*
|
||||||
|
* @since Added in version 3.4.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* handle, int inlineDefaults);
|
||||||
|
|
||||||
|
/*! @brief Returns the currently active system theme.
|
||||||
|
*
|
||||||
|
* @return A mutable [theme](@ref theme) object, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED,
|
||||||
|
* and @ref GLFW_FEATURE_UNIMPLEMENTED.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The returned theme is allocated and freed by GLFW. You
|
||||||
|
* should not free it yourself. It is valid until this function is called
|
||||||
|
* again, or the library is terminated.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref theme
|
||||||
|
* @sa @ref glfwSetSystemThemeCallback
|
||||||
|
* @sa @ref glfwSetTheme
|
||||||
|
*
|
||||||
|
* @since Added in version 3.4.
|
||||||
|
*
|
||||||
|
* @ingroup theme
|
||||||
|
*/
|
||||||
|
GLFWAPI const GLFWtheme* glfwGetSystemDefaultTheme();
|
||||||
|
|
||||||
/*! @brief Returns the GLFW time.
|
/*! @brief Returns the GLFW time.
|
||||||
*
|
*
|
||||||
* This function returns the current GLFW time, in seconds. Unless the time
|
* This function returns the current GLFW time, in seconds. Unless the time
|
||||||
|
@ -3,7 +3,7 @@ add_library(glfw ${GLFW_LIBRARY_TYPE}
|
|||||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
|
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
|
||||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h"
|
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h"
|
||||||
internal.h platform.h mappings.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
|
egl_context.c osmesa_context.c null_platform.h null_joystick.h
|
||||||
null_init.c null_monitor.c null_window.c null_joystick.c)
|
null_init.c null_monitor.c null_window.c null_joystick.c)
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ endif()
|
|||||||
# Make GCC warn about declarations that VS 2010 and 2012 won't accept for all
|
# 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)
|
# source files that VS will build (Clang ignores this because we set -std=c99)
|
||||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
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
|
window.c null_init.c null_joystick.c null_monitor.c
|
||||||
null_window.c win32_init.c win32_joystick.c win32_module.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
|
win32_monitor.c win32_time.c win32_thread.c win32_window.c
|
||||||
|
191
src/cocoa_init.m
191
src/cocoa_init.m
@ -175,6 +175,119 @@ static void createMenuBar(void)
|
|||||||
[NSApp performSelector:setAppleMenuSelector withObject:appMenu];
|
[NSApp performSelector:setAppleMenuSelector withObject:appMenu];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwNSAppearanceToTheme(NSAppearance* appearance, _GLFWtheme* theme)
|
||||||
|
{
|
||||||
|
NSAppearanceName name;
|
||||||
|
|
||||||
|
if (@available(macOS 10.14, *))
|
||||||
|
{
|
||||||
|
name = [appearance bestMatchFromAppearancesWithNames:@[
|
||||||
|
NSAppearanceNameAqua,
|
||||||
|
NSAppearanceNameDarkAqua,
|
||||||
|
NSAppearanceNameVibrantLight,
|
||||||
|
NSAppearanceNameVibrantDark,
|
||||||
|
NSAppearanceNameAccessibilityHighContrastAqua,
|
||||||
|
NSAppearanceNameAccessibilityHighContrastDarkAqua,
|
||||||
|
]];
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
name = appearance.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([name isEqualToString:NSAppearanceNameAqua])
|
||||||
|
{
|
||||||
|
theme->variation = GLFW_THEME_LIGHT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@available(macOS 10.10, *)) {
|
||||||
|
if ([name isEqualToString:NSAppearanceNameVibrantLight])
|
||||||
|
{
|
||||||
|
theme->variation = GLFW_THEME_LIGHT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ([name isEqualToString:NSAppearanceNameVibrantDark])
|
||||||
|
{
|
||||||
|
theme->variation = GLFW_THEME_DARK;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@available(macOS 10.14, *))
|
||||||
|
{
|
||||||
|
if ([name isEqualToString:NSAppearanceNameDarkAqua])
|
||||||
|
{
|
||||||
|
theme->variation = GLFW_THEME_DARK;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ([name isEqualToString:NSAppearanceNameAccessibilityHighContrastAqua])
|
||||||
|
{
|
||||||
|
theme->variation = GLFW_THEME_LIGHT;
|
||||||
|
theme->flags |= GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ([name isEqualToString:NSAppearanceNameAccessibilityHighContrastDarkAqua])
|
||||||
|
{
|
||||||
|
theme->variation = GLFW_THEME_DARK;
|
||||||
|
theme->flags |= GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
theme->variation = GLFW_THEME_LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwGetSystemThemeCocoa(_GLFWtheme* theme)
|
||||||
|
{
|
||||||
|
theme->variation = GLFW_THEME_LIGHT;
|
||||||
|
theme->flags = 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.
|
||||||
|
_glfwNSAppearanceToTheme(NSApp.effectiveAppearance, theme);
|
||||||
|
|
||||||
|
NSColor* color = [[NSColor controlAccentColor] colorUsingColorSpace:NSColorSpace.genericRGBColorSpace];
|
||||||
|
|
||||||
|
theme->flags |= GLFW_THEME_COLOR_MAIN;
|
||||||
|
theme->color[0] = color.redComponent;
|
||||||
|
theme->color[1] = color.greenComponent;
|
||||||
|
theme->color[2] = color.blueComponent;
|
||||||
|
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
|
||||||
//
|
//
|
||||||
static void createKeyTables(void)
|
static void createKeyTables(void)
|
||||||
@ -393,6 +506,42 @@ static GLFWbool initializeTIS(void)
|
|||||||
- (void)doNothing:(id)object
|
- (void)doNothing:(id)object
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
- (void)themeChanged:(NSNotification*)notification
|
||||||
|
{
|
||||||
|
_glfwInputSystemTheme(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)accentColorChanged
|
||||||
|
{
|
||||||
|
_glfwInputSystemTheme(NULL);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
|
||||||
|
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||||
|
ofObject:(id)object
|
||||||
|
change:(NSDictionary *)change
|
||||||
|
context:(void *)context
|
||||||
|
{
|
||||||
|
// This class is never subclassed, so it's safe to ignore the context parameter
|
||||||
|
|
||||||
|
_GLFWtheme 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);
|
||||||
|
|
||||||
|
/*if ([keyPath isEqualToString:@"controlAccentColor"]) {
|
||||||
|
[self accentColorChanged];
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@end // GLFWHelper
|
@end // GLFWHelper
|
||||||
|
|
||||||
@ -496,8 +645,11 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
|
|||||||
const _GLFWplatform cocoa =
|
const _GLFWplatform cocoa =
|
||||||
{
|
{
|
||||||
GLFW_PLATFORM_COCOA,
|
GLFW_PLATFORM_COCOA,
|
||||||
|
// Init
|
||||||
_glfwInitCocoa,
|
_glfwInitCocoa,
|
||||||
_glfwTerminateCocoa,
|
_glfwTerminateCocoa,
|
||||||
|
_glfwGetSystemDefaultThemeCocoa,
|
||||||
|
// Input
|
||||||
_glfwGetCursorPosCocoa,
|
_glfwGetCursorPosCocoa,
|
||||||
_glfwSetCursorPosCocoa,
|
_glfwSetCursorPosCocoa,
|
||||||
_glfwSetCursorModeCocoa,
|
_glfwSetCursorModeCocoa,
|
||||||
@ -516,6 +668,7 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwPollJoystickCocoa,
|
_glfwPollJoystickCocoa,
|
||||||
_glfwGetMappingNameCocoa,
|
_glfwGetMappingNameCocoa,
|
||||||
_glfwUpdateGamepadGUIDCocoa,
|
_glfwUpdateGamepadGUIDCocoa,
|
||||||
|
// Monitor
|
||||||
_glfwFreeMonitorCocoa,
|
_glfwFreeMonitorCocoa,
|
||||||
_glfwGetMonitorPosCocoa,
|
_glfwGetMonitorPosCocoa,
|
||||||
_glfwGetMonitorContentScaleCocoa,
|
_glfwGetMonitorContentScaleCocoa,
|
||||||
@ -524,6 +677,7 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwGetVideoModeCocoa,
|
_glfwGetVideoModeCocoa,
|
||||||
_glfwGetGammaRampCocoa,
|
_glfwGetGammaRampCocoa,
|
||||||
_glfwSetGammaRampCocoa,
|
_glfwSetGammaRampCocoa,
|
||||||
|
// Window
|
||||||
_glfwCreateWindowCocoa,
|
_glfwCreateWindowCocoa,
|
||||||
_glfwDestroyWindowCocoa,
|
_glfwDestroyWindowCocoa,
|
||||||
_glfwSetWindowTitleCocoa,
|
_glfwSetWindowTitleCocoa,
|
||||||
@ -557,13 +711,18 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwSetWindowFloatingCocoa,
|
_glfwSetWindowFloatingCocoa,
|
||||||
_glfwSetWindowOpacityCocoa,
|
_glfwSetWindowOpacityCocoa,
|
||||||
_glfwSetWindowMousePassthroughCocoa,
|
_glfwSetWindowMousePassthroughCocoa,
|
||||||
|
_glfwGetThemeCocoa,
|
||||||
|
_glfwSetThemeCocoa,
|
||||||
|
// Events
|
||||||
_glfwPollEventsCocoa,
|
_glfwPollEventsCocoa,
|
||||||
_glfwWaitEventsCocoa,
|
_glfwWaitEventsCocoa,
|
||||||
_glfwWaitEventsTimeoutCocoa,
|
_glfwWaitEventsTimeoutCocoa,
|
||||||
_glfwPostEmptyEventCocoa,
|
_glfwPostEmptyEventCocoa,
|
||||||
|
// EGL
|
||||||
_glfwGetEGLPlatformCocoa,
|
_glfwGetEGLPlatformCocoa,
|
||||||
_glfwGetEGLNativeDisplayCocoa,
|
_glfwGetEGLNativeDisplayCocoa,
|
||||||
_glfwGetEGLNativeWindowCocoa,
|
_glfwGetEGLNativeWindowCocoa,
|
||||||
|
// Vulkan
|
||||||
_glfwGetRequiredInstanceExtensionsCocoa,
|
_glfwGetRequiredInstanceExtensionsCocoa,
|
||||||
_glfwGetPhysicalDevicePresentationSupportCocoa,
|
_glfwGetPhysicalDevicePresentationSupportCocoa,
|
||||||
_glfwCreateWindowSurfaceCocoa,
|
_glfwCreateWindowSurfaceCocoa,
|
||||||
@ -633,6 +792,30 @@ int _glfwInitCocoa(void)
|
|||||||
|
|
||||||
_glfwPollMonitorsCocoa();
|
_glfwPollMonitorsCocoa();
|
||||||
|
|
||||||
|
/*
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
addObserver:_glfw.ns.helper
|
||||||
|
selector:@selector(themeChanged:)
|
||||||
|
name:@"AppleInterfaceThemeChangedNotification"
|
||||||
|
object:nil];
|
||||||
|
|
||||||
|
[NSColor addObserver:_glfw.ns.helper
|
||||||
|
forKeyPath:@"controlAccentColor"
|
||||||
|
options:0
|
||||||
|
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, *))
|
||||||
|
{
|
||||||
|
[NSApp addObserver:_glfw.ns.helper
|
||||||
|
forKeyPath:@"effectiveAppearance"
|
||||||
|
options:0
|
||||||
|
context:nil];
|
||||||
|
}
|
||||||
|
|
||||||
if (![[NSRunningApplication currentApplication] isFinishedLaunching])
|
if (![[NSRunningApplication currentApplication] isFinishedLaunching])
|
||||||
[NSApp run];
|
[NSApp run];
|
||||||
|
|
||||||
@ -693,5 +876,13 @@ void _glfwTerminateCocoa(void)
|
|||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetSystemDefaultThemeCocoa(void)
|
||||||
|
{
|
||||||
|
_GLFWtheme* theme = &_glfw.theme;
|
||||||
|
_glfwGetSystemThemeCocoa(theme);
|
||||||
|
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _GLFW_COCOA
|
#endif // _GLFW_COCOA
|
||||||
|
|
||||||
|
@ -39,6 +39,12 @@
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#else
|
#else
|
||||||
typedef void* id;
|
typedef void* id;
|
||||||
|
typedef void NSAppearance;
|
||||||
|
typedef id NSString;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101300
|
||||||
|
typedef NSString *NSAppearanceName;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||||||
@ -291,6 +297,9 @@ void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor);
|
|||||||
|
|
||||||
float _glfwTransformYCocoa(float y);
|
float _glfwTransformYCocoa(float y);
|
||||||
|
|
||||||
|
void _glfwNSAppearanceToTheme(NSAppearance* appearance, _GLFWtheme* theme);
|
||||||
|
void _glfwGetSystemThemeCocoa(_GLFWtheme* theme);
|
||||||
|
|
||||||
void* _glfwLoadLocalVulkanLoaderCocoa(void);
|
void* _glfwLoadLocalVulkanLoaderCocoa(void);
|
||||||
|
|
||||||
GLFWbool _glfwInitNSGL(void);
|
GLFWbool _glfwInitNSGL(void);
|
||||||
@ -300,3 +309,6 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetSystemDefaultThemeCocoa(void);
|
||||||
|
void _glfwSetThemeCocoa(_GLFWwindow* window, const _GLFWtheme* theme);
|
||||||
|
_GLFWtheme* _glfwGetThemeCocoa(_GLFWwindow* window, int inlineDefaults);
|
||||||
|
@ -1881,6 +1881,119 @@ const char* _glfwGetClipboardStringCocoa(void)
|
|||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: move
|
||||||
|
static void replaceTheme(_GLFWwindow* window, _GLFWtheme* currentTheme, const _GLFWtheme* newTheme)
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (@available(macOS 10.10, *))
|
||||||
|
{
|
||||||
|
// TODO: support color
|
||||||
|
// TODO: fix vibrancy
|
||||||
|
|
||||||
|
// As per the Cocoa documentation, passing the high contrast names to
|
||||||
|
// appearanceNamed: will result in nil, so these can not be used.
|
||||||
|
NSAppearanceName name;
|
||||||
|
|
||||||
|
if (newTheme->variation == GLFW_THEME_LIGHT)
|
||||||
|
{
|
||||||
|
if (newTheme->flags & GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY)
|
||||||
|
name = NSAppearanceNameVibrantLight;
|
||||||
|
else
|
||||||
|
name = NSAppearanceNameAqua;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (newTheme->flags & GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY)
|
||||||
|
{
|
||||||
|
name = NSAppearanceNameVibrantDark;
|
||||||
|
}
|
||||||
|
else if (@available(macOS 10.14, *))
|
||||||
|
{
|
||||||
|
name = NSAppearanceNameDarkAqua;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name = NSAppearanceNameAqua;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSAppearance* appearance = [NSAppearance appearanceNamed:name];
|
||||||
|
[(NSWindow*)window->ns.object setAppearance:appearance];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwSetThemeCocoa(_GLFWwindow* window, const _GLFWtheme* 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->flags = 0;
|
||||||
|
|
||||||
|
if (@available(macOS 10.09, *))
|
||||||
|
{
|
||||||
|
NSAppearance* appearance = [(NSWindow*)window->ns.object appearance];
|
||||||
|
|
||||||
|
if (appearance == NULL)
|
||||||
|
appearance = [NSApp effectiveAppearance];
|
||||||
|
|
||||||
|
_glfwNSAppearanceToTheme(appearance, theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFWtheme systemTheme;
|
||||||
|
|
||||||
|
_glfwGetSystemThemeCocoa(&systemTheme);
|
||||||
|
|
||||||
|
if ((theme->flags & GLFW_THEME_COLOR_MAIN) == 0)
|
||||||
|
{
|
||||||
|
assert(systemTheme.flags & GLFW_THEME_COLOR_MAIN);
|
||||||
|
memcpy(&theme->color, &systemTheme.color, sizeof(float) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
theme->flags |= systemTheme.flags;
|
||||||
|
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs)
|
EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs)
|
||||||
{
|
{
|
||||||
if (_glfw.egl.ANGLE_platform_angle)
|
if (_glfw.egl.ANGLE_platform_angle)
|
||||||
|
22
src/init.c
22
src/init.c
@ -549,3 +549,25 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
|
|||||||
return cbfun;
|
return cbfun;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI const GLFWtheme* glfwGetSystemDefaultTheme()
|
||||||
|
{
|
||||||
|
_GLFWtheme* theme;
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
theme = _glfw.platform.getSystemDefaultTheme();
|
||||||
|
assert(theme->variation != GLFW_THEME_DEFAULT);
|
||||||
|
|
||||||
|
return (const GLFWtheme*) theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWthemefun glfwSetSystemThemeCallback(GLFWthemefun callback)
|
||||||
|
{
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
//return _glfw.platform.setSystemThemeCallback(callback
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
_GLFW_SWAP(GLFWthemefun, _glfw.callbacks.theme, callback);
|
||||||
|
return callback;
|
||||||
|
}
|
||||||
|
@ -478,6 +478,13 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
|
|||||||
js->hats[hat] = value;
|
js->hats[hat] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwInputSystemTheme(_GLFWtheme* theme)
|
||||||
|
{
|
||||||
|
assert(theme != NULL);
|
||||||
|
|
||||||
|
if (_glfw.callbacks.theme)
|
||||||
|
_glfw.callbacks.theme((GLFWtheme*) theme);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
|
@ -72,6 +72,7 @@ typedef struct _GLFWplatform _GLFWplatform;
|
|||||||
typedef struct _GLFWlibrary _GLFWlibrary;
|
typedef struct _GLFWlibrary _GLFWlibrary;
|
||||||
typedef struct _GLFWmonitor _GLFWmonitor;
|
typedef struct _GLFWmonitor _GLFWmonitor;
|
||||||
typedef struct _GLFWcursor _GLFWcursor;
|
typedef struct _GLFWcursor _GLFWcursor;
|
||||||
|
typedef struct _GLFWtheme _GLFWtheme;
|
||||||
typedef struct _GLFWmapelement _GLFWmapelement;
|
typedef struct _GLFWmapelement _GLFWmapelement;
|
||||||
typedef struct _GLFWmapping _GLFWmapping;
|
typedef struct _GLFWmapping _GLFWmapping;
|
||||||
typedef struct _GLFWjoystick _GLFWjoystick;
|
typedef struct _GLFWjoystick _GLFWjoystick;
|
||||||
@ -518,6 +519,20 @@ struct _GLFWcontext
|
|||||||
GLFW_PLATFORM_CONTEXT_STATE
|
GLFW_PLATFORM_CONTEXT_STATE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Theme structure
|
||||||
|
//
|
||||||
|
struct _GLFWtheme
|
||||||
|
{
|
||||||
|
// The light/dark variation. If set to DEFAULT, use the system theme variation.
|
||||||
|
int variation;
|
||||||
|
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
// When applying a theme, ignore this color if the HAS_COLOR
|
||||||
|
// flag is unset, and use the system theme color instead.
|
||||||
|
float color[4];
|
||||||
|
};
|
||||||
|
|
||||||
// Window and context structure
|
// Window and context structure
|
||||||
//
|
//
|
||||||
struct _GLFWwindow
|
struct _GLFWwindow
|
||||||
@ -574,6 +589,14 @@ struct _GLFWwindow
|
|||||||
GLFWdropfun drop;
|
GLFWdropfun drop;
|
||||||
} callbacks;
|
} callbacks;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
// Clients can mutate this theme data at any time
|
||||||
|
_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
|
||||||
};
|
};
|
||||||
@ -673,10 +696,11 @@ struct _GLFWmutex
|
|||||||
struct _GLFWplatform
|
struct _GLFWplatform
|
||||||
{
|
{
|
||||||
int platformID;
|
int platformID;
|
||||||
// init
|
// Init
|
||||||
GLFWbool (*init)(void);
|
GLFWbool (*init)(void);
|
||||||
void (*terminate)(void);
|
void (*terminate)(void);
|
||||||
// input
|
_GLFWtheme* (*getSystemDefaultTheme)(void);
|
||||||
|
// Input
|
||||||
void (*getCursorPos)(_GLFWwindow*,double*,double*);
|
void (*getCursorPos)(_GLFWwindow*,double*,double*);
|
||||||
void (*setCursorPos)(_GLFWwindow*,double,double);
|
void (*setCursorPos)(_GLFWwindow*,double,double);
|
||||||
void (*setCursorMode)(_GLFWwindow*,int);
|
void (*setCursorMode)(_GLFWwindow*,int);
|
||||||
@ -695,7 +719,7 @@ struct _GLFWplatform
|
|||||||
GLFWbool (*pollJoystick)(_GLFWjoystick*,int);
|
GLFWbool (*pollJoystick)(_GLFWjoystick*,int);
|
||||||
const char* (*getMappingName)(void);
|
const char* (*getMappingName)(void);
|
||||||
void (*updateGamepadGUID)(char*);
|
void (*updateGamepadGUID)(char*);
|
||||||
// monitor
|
// Monitor
|
||||||
void (*freeMonitor)(_GLFWmonitor*);
|
void (*freeMonitor)(_GLFWmonitor*);
|
||||||
void (*getMonitorPos)(_GLFWmonitor*,int*,int*);
|
void (*getMonitorPos)(_GLFWmonitor*,int*,int*);
|
||||||
void (*getMonitorContentScale)(_GLFWmonitor*,float*,float*);
|
void (*getMonitorContentScale)(_GLFWmonitor*,float*,float*);
|
||||||
@ -704,7 +728,7 @@ struct _GLFWplatform
|
|||||||
void (*getVideoMode)(_GLFWmonitor*,GLFWvidmode*);
|
void (*getVideoMode)(_GLFWmonitor*,GLFWvidmode*);
|
||||||
GLFWbool (*getGammaRamp)(_GLFWmonitor*,GLFWgammaramp*);
|
GLFWbool (*getGammaRamp)(_GLFWmonitor*,GLFWgammaramp*);
|
||||||
void (*setGammaRamp)(_GLFWmonitor*,const GLFWgammaramp*);
|
void (*setGammaRamp)(_GLFWmonitor*,const GLFWgammaramp*);
|
||||||
// window
|
// Window
|
||||||
GLFWbool (*createWindow)(_GLFWwindow*,const _GLFWwndconfig*,const _GLFWctxconfig*,const _GLFWfbconfig*);
|
GLFWbool (*createWindow)(_GLFWwindow*,const _GLFWwndconfig*,const _GLFWctxconfig*,const _GLFWfbconfig*);
|
||||||
void (*destroyWindow)(_GLFWwindow*);
|
void (*destroyWindow)(_GLFWwindow*);
|
||||||
void (*setWindowTitle)(_GLFWwindow*,const char*);
|
void (*setWindowTitle)(_GLFWwindow*,const char*);
|
||||||
@ -738,6 +762,9 @@ 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*,int);
|
||||||
|
void (*setTheme)(_GLFWwindow*,const _GLFWtheme*);
|
||||||
|
// Events
|
||||||
void (*pollEvents)(void);
|
void (*pollEvents)(void);
|
||||||
void (*waitEvents)(void);
|
void (*waitEvents)(void);
|
||||||
void (*waitEventsTimeout)(double);
|
void (*waitEventsTimeout)(double);
|
||||||
@ -746,7 +773,7 @@ struct _GLFWplatform
|
|||||||
EGLenum (*getEGLPlatform)(EGLint**);
|
EGLenum (*getEGLPlatform)(EGLint**);
|
||||||
EGLNativeDisplayType (*getEGLNativeDisplay)(void);
|
EGLNativeDisplayType (*getEGLNativeDisplay)(void);
|
||||||
EGLNativeWindowType (*getEGLNativeWindow)(_GLFWwindow*);
|
EGLNativeWindowType (*getEGLNativeWindow)(_GLFWwindow*);
|
||||||
// vulkan
|
// Vulkan
|
||||||
void (*getRequiredInstanceExtensions)(char**);
|
void (*getRequiredInstanceExtensions)(char**);
|
||||||
GLFWbool (*getPhysicalDevicePresentationSupport)(VkInstance,VkPhysicalDevice,uint32_t);
|
GLFWbool (*getPhysicalDevicePresentationSupport)(VkInstance,VkPhysicalDevice,uint32_t);
|
||||||
VkResult (*createWindowSurface)(VkInstance,_GLFWwindow*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
VkResult (*createWindowSurface)(VkInstance,_GLFWwindow*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
@ -866,8 +893,11 @@ struct _GLFWlibrary
|
|||||||
struct {
|
struct {
|
||||||
GLFWmonitorfun monitor;
|
GLFWmonitorfun monitor;
|
||||||
GLFWjoystickfun joystick;
|
GLFWjoystickfun joystick;
|
||||||
|
GLFWthemefun theme;
|
||||||
} callbacks;
|
} callbacks;
|
||||||
|
|
||||||
|
_GLFWtheme theme;
|
||||||
|
|
||||||
// These are defined in platform.h
|
// These are defined in platform.h
|
||||||
GLFW_PLATFORM_LIBRARY_WINDOW_STATE
|
GLFW_PLATFORM_LIBRARY_WINDOW_STATE
|
||||||
GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
||||||
@ -932,6 +962,8 @@ void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value);
|
|||||||
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value);
|
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value);
|
||||||
void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value);
|
void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value);
|
||||||
|
|
||||||
|
void _glfwInputSystemTheme(_GLFWtheme* theme);
|
||||||
|
|
||||||
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
|
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
|
||||||
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
|
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
|
||||||
|
|
||||||
@ -1010,3 +1042,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);
|
||||||
|
@ -42,8 +42,11 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
|
|||||||
const _GLFWplatform null =
|
const _GLFWplatform null =
|
||||||
{
|
{
|
||||||
GLFW_PLATFORM_NULL,
|
GLFW_PLATFORM_NULL,
|
||||||
|
// Init
|
||||||
_glfwInitNull,
|
_glfwInitNull,
|
||||||
_glfwTerminateNull,
|
_glfwTerminateNull,
|
||||||
|
_glfwGetSystemDefaultThemeNull,
|
||||||
|
// Input
|
||||||
_glfwGetCursorPosNull,
|
_glfwGetCursorPosNull,
|
||||||
_glfwSetCursorPosNull,
|
_glfwSetCursorPosNull,
|
||||||
_glfwSetCursorModeNull,
|
_glfwSetCursorModeNull,
|
||||||
@ -62,6 +65,7 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwPollJoystickNull,
|
_glfwPollJoystickNull,
|
||||||
_glfwGetMappingNameNull,
|
_glfwGetMappingNameNull,
|
||||||
_glfwUpdateGamepadGUIDNull,
|
_glfwUpdateGamepadGUIDNull,
|
||||||
|
// Monitor
|
||||||
_glfwFreeMonitorNull,
|
_glfwFreeMonitorNull,
|
||||||
_glfwGetMonitorPosNull,
|
_glfwGetMonitorPosNull,
|
||||||
_glfwGetMonitorContentScaleNull,
|
_glfwGetMonitorContentScaleNull,
|
||||||
@ -70,6 +74,7 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwGetVideoModeNull,
|
_glfwGetVideoModeNull,
|
||||||
_glfwGetGammaRampNull,
|
_glfwGetGammaRampNull,
|
||||||
_glfwSetGammaRampNull,
|
_glfwSetGammaRampNull,
|
||||||
|
// Window
|
||||||
_glfwCreateWindowNull,
|
_glfwCreateWindowNull,
|
||||||
_glfwDestroyWindowNull,
|
_glfwDestroyWindowNull,
|
||||||
_glfwSetWindowTitleNull,
|
_glfwSetWindowTitleNull,
|
||||||
@ -103,13 +108,17 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwSetWindowFloatingNull,
|
_glfwSetWindowFloatingNull,
|
||||||
_glfwSetWindowOpacityNull,
|
_glfwSetWindowOpacityNull,
|
||||||
_glfwSetWindowMousePassthroughNull,
|
_glfwSetWindowMousePassthroughNull,
|
||||||
|
_glfwGetThemeNull,
|
||||||
|
_glfwSetThemeNull,
|
||||||
_glfwPollEventsNull,
|
_glfwPollEventsNull,
|
||||||
_glfwWaitEventsNull,
|
_glfwWaitEventsNull,
|
||||||
_glfwWaitEventsTimeoutNull,
|
_glfwWaitEventsTimeoutNull,
|
||||||
_glfwPostEmptyEventNull,
|
_glfwPostEmptyEventNull,
|
||||||
|
// EGL
|
||||||
_glfwGetEGLPlatformNull,
|
_glfwGetEGLPlatformNull,
|
||||||
_glfwGetEGLNativeDisplayNull,
|
_glfwGetEGLNativeDisplayNull,
|
||||||
_glfwGetEGLNativeWindowNull,
|
_glfwGetEGLNativeWindowNull,
|
||||||
|
// Vulkan
|
||||||
_glfwGetRequiredInstanceExtensionsNull,
|
_glfwGetRequiredInstanceExtensionsNull,
|
||||||
_glfwGetPhysicalDevicePresentationSupportNull,
|
_glfwGetPhysicalDevicePresentationSupportNull,
|
||||||
_glfwCreateWindowSurfaceNull,
|
_glfwCreateWindowSurfaceNull,
|
||||||
@ -264,3 +273,12 @@ void _glfwTerminateNull(void)
|
|||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetSystemDefaultThemeNull(void)
|
||||||
|
{
|
||||||
|
_glfwInitDefaultTheme(&_glfw.theme);
|
||||||
|
|
||||||
|
// DEFAULT is not a valid return value.
|
||||||
|
_glfw.theme.variation = GLFW_THEME_LIGHT;
|
||||||
|
|
||||||
|
return &_glfw.theme;
|
||||||
|
}
|
||||||
|
@ -270,3 +270,6 @@ VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window,
|
|||||||
|
|
||||||
void _glfwPollMonitorsNull(void);
|
void _glfwPollMonitorsNull(void);
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetSystemDefaultThemeNull(void);
|
||||||
|
void _glfwSetThemeNull(_GLFWwindow* window, const _GLFWtheme* theme);
|
||||||
|
_GLFWtheme* _glfwGetThemeNull(_GLFWwindow* window, int inlineDefaults);
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static void applySizeLimits(_GLFWwindow* window, int* width, int* height)
|
static void applySizeLimits(_GLFWwindow* window, int* width, int* height)
|
||||||
{
|
{
|
||||||
@ -551,6 +552,18 @@ const char* _glfwGetClipboardStringNull(void)
|
|||||||
return _glfw.null.clipboardString;
|
return _glfw.null.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwSetThemeNull(_GLFWwindow* window, const _GLFWtheme* theme)
|
||||||
|
{
|
||||||
|
memcpy(&window->theme.internal, theme, sizeof(_GLFWtheme));
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetThemeNull(_GLFWwindow* window, int inlineDefaults)
|
||||||
|
{
|
||||||
|
memcpy(&window->theme.external, &window->theme.internal, sizeof(_GLFWtheme));
|
||||||
|
|
||||||
|
return &window->theme.external;
|
||||||
|
}
|
||||||
|
|
||||||
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
|
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
145
src/theme.c
Normal file
145
src/theme.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.4 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2023 Andreas O. Jansen
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.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)
|
||||||
|
{
|
||||||
|
_GLFWtheme* theme = _glfw_calloc(1, sizeof(_GLFWtheme));
|
||||||
|
_glfwInitDefaultTheme(theme);
|
||||||
|
|
||||||
|
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 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)
|
||||||
|
{
|
||||||
|
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 glfwThemeGetAttribute(const GLFWtheme* theme, int attribute)
|
||||||
|
{
|
||||||
|
assert(theme != NULL);
|
||||||
|
assert(attributesAreValid(attribute));
|
||||||
|
|
||||||
|
return ((_GLFWtheme*) theme)->flags & attribute ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwThemeSetAttribute(GLFWtheme* theme, int attribute, int value)
|
||||||
|
{
|
||||||
|
_GLFWtheme* _theme = (_GLFWtheme*) theme;
|
||||||
|
|
||||||
|
assert(theme != NULL);
|
||||||
|
assert(value == GLFW_TRUE || value == GLFW_FALSE);
|
||||||
|
assert(attributesAreValid(attribute));
|
||||||
|
|
||||||
|
if (value == GLFW_TRUE)
|
||||||
|
_theme->flags |= attribute;
|
||||||
|
else
|
||||||
|
_theme->flags &= ~attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(specifier == GLFW_THEME_COLOR_MAIN);
|
||||||
|
assert(red != NULL && green != NULL && blue != NULL && alpha != NULL);
|
||||||
|
|
||||||
|
*red = color[0];
|
||||||
|
*green = color[1];
|
||||||
|
*blue = color[2];
|
||||||
|
*alpha = color[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwThemeSetColor(GLFWtheme* theme, int specifier, float red, float green, float blue, float alpha)
|
||||||
|
{
|
||||||
|
float* color = ((_GLFWtheme*) theme)->color;
|
||||||
|
|
||||||
|
assert(theme != NULL);
|
||||||
|
assert(specifier == GLFW_THEME_COLOR_MAIN);
|
||||||
|
|
||||||
|
color[0] = red;
|
||||||
|
color[1] = green;
|
||||||
|
color[2] = blue;
|
||||||
|
color[3] = alpha;
|
||||||
|
}
|
@ -151,6 +151,8 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
||||||
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
|
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
|
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
|
||||||
|
_glfw.win32.dwmapi.SetWindowAttribute = (PFN_DwmSetWindowAttribute)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmSetWindowAttribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll");
|
_glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll");
|
||||||
@ -169,6 +171,18 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
_glfwPlatformGetModuleSymbol(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfw.win32.uxtheme.instance = _glfwPlatformLoadModule("uxtheme.dll");
|
||||||
|
if (_glfw.win32.uxtheme.instance)
|
||||||
|
{
|
||||||
|
_glfw.win32.uxtheme.ShouldAppsUseDarkMode = (ShouldAppsUseDarkModePtr)_glfwPlatformGetModuleSymbol(_glfw.win32.uxtheme.instance, MAKEINTRESOURCEA(132));
|
||||||
|
_glfw.win32.uxtheme.GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)_glfwPlatformGetModuleSymbol(_glfw.win32.uxtheme.instance, MAKEINTRESOURCEA(95));
|
||||||
|
_glfw.win32.uxtheme.GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)_glfwPlatformGetModuleSymbol(_glfw.win32.uxtheme.instance, MAKEINTRESOURCEA(96));
|
||||||
|
_glfw.win32.uxtheme.GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)_glfwPlatformGetModuleSymbol(_glfw.win32.uxtheme.instance, MAKEINTRESOURCEA(98));
|
||||||
|
|
||||||
|
_glfw.win32.uxtheme.uxThemeAvailable = _glfw.win32.uxtheme.ShouldAppsUseDarkMode && _glfw.win32.uxtheme.GetImmersiveColorFromColorSetEx && _glfw.win32.uxtheme.GetImmersiveColorTypeFromName && _glfw.win32.uxtheme.GetImmersiveUserColorSetPreference;
|
||||||
|
_glfw.win32.uxtheme.darkTitleAvailable = _glfwIsWindows10BuildOrGreaterWin32(22000);
|
||||||
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,6 +207,9 @@ static void freeLibraries(void)
|
|||||||
|
|
||||||
if (_glfw.win32.ntdll.instance)
|
if (_glfw.win32.ntdll.instance)
|
||||||
_glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
|
_glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
|
||||||
|
|
||||||
|
if (_glfw.win32.uxtheme.instance)
|
||||||
|
_glfwPlatformFreeModule(_glfw.win32.uxtheme.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create key code translation tables
|
// Create key code translation tables
|
||||||
@ -606,8 +623,11 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
|
|||||||
const _GLFWplatform win32 =
|
const _GLFWplatform win32 =
|
||||||
{
|
{
|
||||||
GLFW_PLATFORM_WIN32,
|
GLFW_PLATFORM_WIN32,
|
||||||
|
// Init
|
||||||
_glfwInitWin32,
|
_glfwInitWin32,
|
||||||
_glfwTerminateWin32,
|
_glfwTerminateWin32,
|
||||||
|
_glfwGetSystemDefaultThemeWin32,
|
||||||
|
// Input
|
||||||
_glfwGetCursorPosWin32,
|
_glfwGetCursorPosWin32,
|
||||||
_glfwSetCursorPosWin32,
|
_glfwSetCursorPosWin32,
|
||||||
_glfwSetCursorModeWin32,
|
_glfwSetCursorModeWin32,
|
||||||
@ -626,6 +646,7 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwPollJoystickWin32,
|
_glfwPollJoystickWin32,
|
||||||
_glfwGetMappingNameWin32,
|
_glfwGetMappingNameWin32,
|
||||||
_glfwUpdateGamepadGUIDWin32,
|
_glfwUpdateGamepadGUIDWin32,
|
||||||
|
// Monitor
|
||||||
_glfwFreeMonitorWin32,
|
_glfwFreeMonitorWin32,
|
||||||
_glfwGetMonitorPosWin32,
|
_glfwGetMonitorPosWin32,
|
||||||
_glfwGetMonitorContentScaleWin32,
|
_glfwGetMonitorContentScaleWin32,
|
||||||
@ -634,6 +655,7 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwGetVideoModeWin32,
|
_glfwGetVideoModeWin32,
|
||||||
_glfwGetGammaRampWin32,
|
_glfwGetGammaRampWin32,
|
||||||
_glfwSetGammaRampWin32,
|
_glfwSetGammaRampWin32,
|
||||||
|
// Window
|
||||||
_glfwCreateWindowWin32,
|
_glfwCreateWindowWin32,
|
||||||
_glfwDestroyWindowWin32,
|
_glfwDestroyWindowWin32,
|
||||||
_glfwSetWindowTitleWin32,
|
_glfwSetWindowTitleWin32,
|
||||||
@ -667,13 +689,18 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwSetWindowFloatingWin32,
|
_glfwSetWindowFloatingWin32,
|
||||||
_glfwSetWindowOpacityWin32,
|
_glfwSetWindowOpacityWin32,
|
||||||
_glfwSetWindowMousePassthroughWin32,
|
_glfwSetWindowMousePassthroughWin32,
|
||||||
|
_glfwGetThemeWin32,
|
||||||
|
_glfwSetThemeWin32,
|
||||||
|
// Events
|
||||||
_glfwPollEventsWin32,
|
_glfwPollEventsWin32,
|
||||||
_glfwWaitEventsWin32,
|
_glfwWaitEventsWin32,
|
||||||
_glfwWaitEventsTimeoutWin32,
|
_glfwWaitEventsTimeoutWin32,
|
||||||
_glfwPostEmptyEventWin32,
|
_glfwPostEmptyEventWin32,
|
||||||
|
// EGL
|
||||||
_glfwGetEGLPlatformWin32,
|
_glfwGetEGLPlatformWin32,
|
||||||
_glfwGetEGLNativeDisplayWin32,
|
_glfwGetEGLNativeDisplayWin32,
|
||||||
_glfwGetEGLNativeWindowWin32,
|
_glfwGetEGLNativeWindowWin32,
|
||||||
|
// Vulkan
|
||||||
_glfwGetRequiredInstanceExtensionsWin32,
|
_glfwGetRequiredInstanceExtensionsWin32,
|
||||||
_glfwGetPhysicalDevicePresentationSupportWin32,
|
_glfwGetPhysicalDevicePresentationSupportWin32,
|
||||||
_glfwCreateWindowSurfaceWin32,
|
_glfwCreateWindowSurfaceWin32,
|
||||||
@ -727,5 +754,20 @@ void _glfwTerminateWin32(void)
|
|||||||
freeLibraries();
|
freeLibraries();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _GLFW_WIN32
|
_GLFWtheme* _glfwGetSystemDefaultThemeWin32(void)
|
||||||
|
{
|
||||||
|
_GLFWtheme* theme = &_glfw.theme;
|
||||||
|
|
||||||
|
theme->variation = GLFW_THEME_LIGHT;
|
||||||
|
theme->flags = 0;
|
||||||
|
|
||||||
|
if (_glfw.win32.uxtheme.uxThemeAvailable && _glfw.win32.uxtheme.darkTitleAvailable) {
|
||||||
|
if (_glfw.win32.uxtheme.ShouldAppsUseDarkMode() & 0x1) {
|
||||||
|
theme->variation = GLFW_THEME_DARK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _GLFW_WIN32
|
||||||
|
@ -301,10 +301,13 @@ typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
|||||||
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
||||||
typedef HRESULT (WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
|
typedef HRESULT (WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
|
||||||
typedef HRESULT (WINAPI * PFN_DwmGetColorizationColor)(DWORD*,BOOL*);
|
typedef HRESULT (WINAPI * PFN_DwmGetColorizationColor)(DWORD*,BOOL*);
|
||||||
|
typedef HRESULT (WINAPI * PFN_DwmSetWindowAttribute)(HWND,DWORD,LPCVOID,DWORD);
|
||||||
|
|
||||||
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
||||||
#define DwmFlush _glfw.win32.dwmapi.Flush
|
#define DwmFlush _glfw.win32.dwmapi.Flush
|
||||||
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
||||||
#define DwmGetColorizationColor _glfw.win32.dwmapi.GetColorizationColor
|
#define DwmGetColorizationColor _glfw.win32.dwmapi.GetColorizationColor
|
||||||
|
#define DwmSetWindowAttribute _glfw.win32.dwmapi.SetWindowAttribute
|
||||||
|
|
||||||
// shcore.dll function pointer typedefs
|
// shcore.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||||
@ -366,6 +369,11 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
|
|||||||
#define GLFW_WGL_CONTEXT_STATE _GLFWcontextWGL wgl;
|
#define GLFW_WGL_CONTEXT_STATE _GLFWcontextWGL wgl;
|
||||||
#define GLFW_WGL_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl;
|
#define GLFW_WGL_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl;
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI * ShouldAppsUseDarkModePtr)();
|
||||||
|
typedef DWORD (WINAPI * GetImmersiveColorFromColorSetExPtr)(UINT,UINT,BOOL,UINT);
|
||||||
|
typedef int (WINAPI * GetImmersiveColorTypeFromNamePtr)(const WCHAR*);
|
||||||
|
typedef int (WINAPI * GetImmersiveUserColorSetPreferencePtr)(BOOL,BOOL);
|
||||||
|
|
||||||
|
|
||||||
// WGL-specific per-context data
|
// WGL-specific per-context data
|
||||||
//
|
//
|
||||||
@ -487,6 +495,7 @@ typedef struct _GLFWlibraryWin32
|
|||||||
PFN_DwmFlush Flush;
|
PFN_DwmFlush Flush;
|
||||||
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
||||||
PFN_DwmGetColorizationColor GetColorizationColor;
|
PFN_DwmGetColorizationColor GetColorizationColor;
|
||||||
|
PFN_DwmSetWindowAttribute SetWindowAttribute;
|
||||||
} dwmapi;
|
} dwmapi;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -499,6 +508,16 @@ typedef struct _GLFWlibraryWin32
|
|||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
|
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
|
||||||
} ntdll;
|
} ntdll;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
HINSTANCE instance;
|
||||||
|
GLFWbool uxThemeAvailable;
|
||||||
|
GLFWbool darkTitleAvailable;
|
||||||
|
ShouldAppsUseDarkModePtr ShouldAppsUseDarkMode;
|
||||||
|
GetImmersiveColorFromColorSetExPtr GetImmersiveColorFromColorSetEx;
|
||||||
|
GetImmersiveColorTypeFromNamePtr GetImmersiveColorTypeFromName;
|
||||||
|
GetImmersiveUserColorSetPreferencePtr GetImmersiveUserColorSetPreference;
|
||||||
|
} uxtheme;
|
||||||
} _GLFWlibraryWin32;
|
} _GLFWlibraryWin32;
|
||||||
|
|
||||||
// Win32-specific per-monitor data
|
// Win32-specific per-monitor data
|
||||||
@ -622,3 +641,6 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetSystemDefaultThemeWin32(void);
|
||||||
|
void _glfwSetThemeWin32(_GLFWwindow* window, const _GLFWtheme* theme);
|
||||||
|
_GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window, int inlineDefaults);
|
||||||
|
@ -37,6 +37,47 @@
|
|||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
|
||||||
|
// Ref: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
|
||||||
|
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
|
||||||
|
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Apply the system default theme
|
||||||
|
//
|
||||||
|
static void applySystemTheme(HWND handle)
|
||||||
|
{
|
||||||
|
if (_glfw.win32.uxtheme.uxThemeAvailable && _glfw.win32.uxtheme.darkTitleAvailable)
|
||||||
|
{
|
||||||
|
GLFWbool value = _glfw.win32.uxtheme.ShouldAppsUseDarkMode() & 0x1;
|
||||||
|
DwmSetWindowAttribute(handle,
|
||||||
|
DWMWA_USE_IMMERSIVE_DARK_MODE,
|
||||||
|
&value,
|
||||||
|
sizeof(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int getAccentColor(float color[4])
|
||||||
|
{
|
||||||
|
if (!_glfw.win32.uxtheme.uxThemeAvailable)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
UINT dwImmersiveColorType = _glfw.win32.uxtheme.GetImmersiveColorTypeFromName(L"ImmersiveSystemAccent");
|
||||||
|
UINT dwImmersiveColorSet = _glfw.win32.uxtheme.GetImmersiveUserColorSetPreference(FALSE, FALSE);
|
||||||
|
|
||||||
|
UINT rgba = _glfw.win32.uxtheme.GetImmersiveColorFromColorSetEx(dwImmersiveColorSet,
|
||||||
|
dwImmersiveColorType,
|
||||||
|
FALSE,
|
||||||
|
0);
|
||||||
|
|
||||||
|
color[0] = (float) (0xFF & rgba);
|
||||||
|
color[1] = (float) ((0xFF00 & rgba) >> 8);
|
||||||
|
color[2] = (float) ((0xFF0000 & rgba) >> 16);
|
||||||
|
color[3] = (float) ((0xFF000000 & rgba) >> 24);
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the window style for the specified window
|
// Returns the window style for the specified window
|
||||||
//
|
//
|
||||||
static DWORD getWindowStyle(const _GLFWwindow* window)
|
static DWORD getWindowStyle(const _GLFWwindow* window)
|
||||||
@ -1146,6 +1187,13 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_THEMECHANGED:
|
||||||
|
case WM_SETTINGCHANGE: {
|
||||||
|
if (window->theme.internal.variation == GLFW_THEME_DEFAULT) {
|
||||||
|
applySystemTheme(window->win32.handle);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
case WM_GETDPISCALEDSIZE:
|
case WM_GETDPISCALEDSIZE:
|
||||||
{
|
{
|
||||||
if (window->win32.scaleToMonitor)
|
if (window->win32.scaleToMonitor)
|
||||||
@ -1436,6 +1484,9 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
_glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height);
|
_glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height);
|
||||||
|
|
||||||
|
// Use the system default when creating a window
|
||||||
|
applySystemTheme(window->win32.handle);
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2373,6 +2424,68 @@ const char* _glfwGetClipboardStringWin32(void)
|
|||||||
return _glfw.win32.clipboardString;
|
return _glfw.win32.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwSetThemeWin32(_GLFWwindow* window, const _GLFWtheme* theme)
|
||||||
|
{
|
||||||
|
_GLFWtheme* currentTheme = &window->theme.internal;
|
||||||
|
_GLFWtheme newTheme;
|
||||||
|
|
||||||
|
if (!theme)
|
||||||
|
_glfwInitDefaultTheme(&newTheme);
|
||||||
|
else
|
||||||
|
memcpy(&newTheme, theme, sizeof(_GLFWtheme));
|
||||||
|
|
||||||
|
if (newTheme.variation == GLFW_THEME_DEFAULT)
|
||||||
|
{
|
||||||
|
applySystemTheme(window->win32.handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GLFWbool darkMode = newTheme.variation == GLFW_THEME_DARK;
|
||||||
|
|
||||||
|
DwmSetWindowAttribute(window->win32.handle,
|
||||||
|
DWMWA_USE_IMMERSIVE_DARK_MODE,
|
||||||
|
&darkMode,
|
||||||
|
sizeof(darkMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: set accent color
|
||||||
|
|
||||||
|
memcpy(currentTheme, &newTheme, sizeof(_GLFWtheme));
|
||||||
|
|
||||||
|
// Not available for setting in Win32.
|
||||||
|
currentTheme->flags &= ~(GLFW_THEME_ATTRIBUTE_HIGH_CONTRAST |
|
||||||
|
GLFW_THEME_ATTRIBUTE_REDUCE_TRANSPARENCY |
|
||||||
|
GLFW_THEME_ATTRIBUTE_REDUCE_MOTION|
|
||||||
|
GLFW_THEME_COLOR_MAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetThemeWin32(_GLFWwindow* window, int inlineDefaults)
|
||||||
|
{
|
||||||
|
_GLFWtheme* theme = &window->theme.external;
|
||||||
|
memcpy(theme, &window->theme.internal, sizeof(_GLFWtheme));
|
||||||
|
|
||||||
|
if (!inlineDefaults)
|
||||||
|
return theme;
|
||||||
|
|
||||||
|
if (theme->variation == GLFW_THEME_DEFAULT)
|
||||||
|
{
|
||||||
|
theme->variation = GLFW_THEME_LIGHT;
|
||||||
|
|
||||||
|
if (_glfw.win32.uxtheme.uxThemeAvailable && _glfw.win32.uxtheme.darkTitleAvailable)
|
||||||
|
theme->variation = GLFW_THEME_DARK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((theme->flags & GLFW_THEME_COLOR_MAIN) == 0)
|
||||||
|
{
|
||||||
|
if (getAccentColor(theme->color))
|
||||||
|
theme->flags |= GLFW_THEME_COLOR_MAIN;
|
||||||
|
else
|
||||||
|
memset(&theme->color, 0, sizeof(float) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs)
|
EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs)
|
||||||
{
|
{
|
||||||
if (_glfw.egl.ANGLE_platform_angle)
|
if (_glfw.egl.ANGLE_platform_angle)
|
||||||
@ -2501,4 +2614,3 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif // _GLFW_WIN32
|
#endif // _GLFW_WIN32
|
||||||
|
|
||||||
|
20
src/window.c
20
src/window.c
@ -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);
|
||||||
@ -1153,3 +1155,21 @@ GLFWAPI void glfwPostEmptyEvent(void)
|
|||||||
_glfw.platform.postEmptyEvent();
|
_glfw.platform.postEmptyEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwSetTheme(GLFWwindow* handle, const GLFWtheme* theme)
|
||||||
|
{
|
||||||
|
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
assert(window != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
_glfw.platform.setTheme(window, (_GLFWtheme*) theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* handle, int inlineDefaults)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
assert(window != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
return (GLFWtheme*) _glfw.platform.getTheme(window, inlineDefaults);
|
||||||
|
}
|
||||||
|
@ -408,8 +408,11 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
|
|||||||
const _GLFWplatform wayland =
|
const _GLFWplatform wayland =
|
||||||
{
|
{
|
||||||
GLFW_PLATFORM_WAYLAND,
|
GLFW_PLATFORM_WAYLAND,
|
||||||
|
// Init
|
||||||
_glfwInitWayland,
|
_glfwInitWayland,
|
||||||
_glfwTerminateWayland,
|
_glfwTerminateWayland,
|
||||||
|
_glfwGetSystemDefaultThemeWayland,
|
||||||
|
// Input
|
||||||
_glfwGetCursorPosWayland,
|
_glfwGetCursorPosWayland,
|
||||||
_glfwSetCursorPosWayland,
|
_glfwSetCursorPosWayland,
|
||||||
_glfwSetCursorModeWayland,
|
_glfwSetCursorModeWayland,
|
||||||
@ -436,6 +439,7 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwGetMappingNameNull,
|
_glfwGetMappingNameNull,
|
||||||
_glfwUpdateGamepadGUIDNull,
|
_glfwUpdateGamepadGUIDNull,
|
||||||
#endif
|
#endif
|
||||||
|
// Monitor
|
||||||
_glfwFreeMonitorWayland,
|
_glfwFreeMonitorWayland,
|
||||||
_glfwGetMonitorPosWayland,
|
_glfwGetMonitorPosWayland,
|
||||||
_glfwGetMonitorContentScaleWayland,
|
_glfwGetMonitorContentScaleWayland,
|
||||||
@ -444,6 +448,7 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwGetVideoModeWayland,
|
_glfwGetVideoModeWayland,
|
||||||
_glfwGetGammaRampWayland,
|
_glfwGetGammaRampWayland,
|
||||||
_glfwSetGammaRampWayland,
|
_glfwSetGammaRampWayland,
|
||||||
|
// Window
|
||||||
_glfwCreateWindowWayland,
|
_glfwCreateWindowWayland,
|
||||||
_glfwDestroyWindowWayland,
|
_glfwDestroyWindowWayland,
|
||||||
_glfwSetWindowTitleWayland,
|
_glfwSetWindowTitleWayland,
|
||||||
@ -477,13 +482,18 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwSetWindowFloatingWayland,
|
_glfwSetWindowFloatingWayland,
|
||||||
_glfwSetWindowOpacityWayland,
|
_glfwSetWindowOpacityWayland,
|
||||||
_glfwSetWindowMousePassthroughWayland,
|
_glfwSetWindowMousePassthroughWayland,
|
||||||
|
_glfwGetThemeWayland,
|
||||||
|
_glfwSetThemeWayland,
|
||||||
|
// Events
|
||||||
_glfwPollEventsWayland,
|
_glfwPollEventsWayland,
|
||||||
_glfwWaitEventsWayland,
|
_glfwWaitEventsWayland,
|
||||||
_glfwWaitEventsTimeoutWayland,
|
_glfwWaitEventsTimeoutWayland,
|
||||||
_glfwPostEmptyEventWayland,
|
_glfwPostEmptyEventWayland,
|
||||||
|
// EGL
|
||||||
_glfwGetEGLPlatformWayland,
|
_glfwGetEGLPlatformWayland,
|
||||||
_glfwGetEGLNativeDisplayWayland,
|
_glfwGetEGLNativeDisplayWayland,
|
||||||
_glfwGetEGLNativeWindowWayland,
|
_glfwGetEGLNativeWindowWayland,
|
||||||
|
// Vulkan
|
||||||
_glfwGetRequiredInstanceExtensionsWayland,
|
_glfwGetRequiredInstanceExtensionsWayland,
|
||||||
_glfwGetPhysicalDevicePresentationSupportWayland,
|
_glfwGetPhysicalDevicePresentationSupportWayland,
|
||||||
_glfwCreateWindowSurfaceWayland,
|
_glfwCreateWindowSurfaceWayland,
|
||||||
@ -944,5 +954,11 @@ void _glfwTerminateWayland(void)
|
|||||||
_glfw_free(_glfw.wl.clipboardString);
|
_glfw_free(_glfw.wl.clipboardString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetSystemDefaultThemeWayland(void)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
|
||||||
|
return NULL; // TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _GLFW_WAYLAND
|
#endif // _GLFW_WAYLAND
|
||||||
|
|
||||||
|
@ -686,3 +686,6 @@ void _glfwUpdateContentScaleWayland(_GLFWwindow* window);
|
|||||||
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
|
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
|
||||||
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
|
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetSystemDefaultThemeWayland(void);
|
||||||
|
void _glfwSetThemeWayland(_GLFWwindow* window, const _GLFWtheme* theme);
|
||||||
|
_GLFWtheme* _glfwGetThemeWayland(_GLFWwindow* window, int inlineDefaults);
|
||||||
|
@ -3063,6 +3063,18 @@ const char* _glfwGetClipboardStringWayland(void)
|
|||||||
return _glfw.wl.clipboardString;
|
return _glfw.wl.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwSetThemeWayland(_GLFWwindow* window, const _GLFWtheme* theme)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
|
||||||
|
// TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetThemeWayland(_GLFWwindow* window, int inlineDefaults)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
|
||||||
|
return NULL; // TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs)
|
EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs)
|
||||||
{
|
{
|
||||||
if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_wayland)
|
if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_wayland)
|
||||||
|
@ -1169,8 +1169,11 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
|||||||
const _GLFWplatform x11 =
|
const _GLFWplatform x11 =
|
||||||
{
|
{
|
||||||
GLFW_PLATFORM_X11,
|
GLFW_PLATFORM_X11,
|
||||||
|
// Init
|
||||||
_glfwInitX11,
|
_glfwInitX11,
|
||||||
_glfwTerminateX11,
|
_glfwTerminateX11,
|
||||||
|
_glfwGetSystemDefaultThemeX11,
|
||||||
|
// Input
|
||||||
_glfwGetCursorPosX11,
|
_glfwGetCursorPosX11,
|
||||||
_glfwSetCursorPosX11,
|
_glfwSetCursorPosX11,
|
||||||
_glfwSetCursorModeX11,
|
_glfwSetCursorModeX11,
|
||||||
@ -1197,6 +1200,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwGetMappingNameNull,
|
_glfwGetMappingNameNull,
|
||||||
_glfwUpdateGamepadGUIDNull,
|
_glfwUpdateGamepadGUIDNull,
|
||||||
#endif
|
#endif
|
||||||
|
// Monitor
|
||||||
_glfwFreeMonitorX11,
|
_glfwFreeMonitorX11,
|
||||||
_glfwGetMonitorPosX11,
|
_glfwGetMonitorPosX11,
|
||||||
_glfwGetMonitorContentScaleX11,
|
_glfwGetMonitorContentScaleX11,
|
||||||
@ -1205,6 +1209,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwGetVideoModeX11,
|
_glfwGetVideoModeX11,
|
||||||
_glfwGetGammaRampX11,
|
_glfwGetGammaRampX11,
|
||||||
_glfwSetGammaRampX11,
|
_glfwSetGammaRampX11,
|
||||||
|
// Window
|
||||||
_glfwCreateWindowX11,
|
_glfwCreateWindowX11,
|
||||||
_glfwDestroyWindowX11,
|
_glfwDestroyWindowX11,
|
||||||
_glfwSetWindowTitleX11,
|
_glfwSetWindowTitleX11,
|
||||||
@ -1238,13 +1243,18 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwSetWindowFloatingX11,
|
_glfwSetWindowFloatingX11,
|
||||||
_glfwSetWindowOpacityX11,
|
_glfwSetWindowOpacityX11,
|
||||||
_glfwSetWindowMousePassthroughX11,
|
_glfwSetWindowMousePassthroughX11,
|
||||||
|
_glfwGetThemeX11,
|
||||||
|
_glfwSetThemeX11,
|
||||||
|
// Events
|
||||||
_glfwPollEventsX11,
|
_glfwPollEventsX11,
|
||||||
_glfwWaitEventsX11,
|
_glfwWaitEventsX11,
|
||||||
_glfwWaitEventsTimeoutX11,
|
_glfwWaitEventsTimeoutX11,
|
||||||
_glfwPostEmptyEventX11,
|
_glfwPostEmptyEventX11,
|
||||||
|
// EGL
|
||||||
_glfwGetEGLPlatformX11,
|
_glfwGetEGLPlatformX11,
|
||||||
_glfwGetEGLNativeDisplayX11,
|
_glfwGetEGLNativeDisplayX11,
|
||||||
_glfwGetEGLNativeWindowX11,
|
_glfwGetEGLNativeWindowX11,
|
||||||
|
// Vulkan
|
||||||
_glfwGetRequiredInstanceExtensionsX11,
|
_glfwGetRequiredInstanceExtensionsX11,
|
||||||
_glfwGetPhysicalDevicePresentationSupportX11,
|
_glfwGetPhysicalDevicePresentationSupportX11,
|
||||||
_glfwCreateWindowSurfaceX11,
|
_glfwCreateWindowSurfaceX11,
|
||||||
@ -1654,5 +1664,11 @@ void _glfwTerminateX11(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetSystemDefaultThemeX11(void)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
|
||||||
|
return NULL; // TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _GLFW_X11
|
#endif // _GLFW_X11
|
||||||
|
|
||||||
|
@ -1002,3 +1002,6 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
|||||||
const _GLFWfbconfig* fbconfig,
|
const _GLFWfbconfig* fbconfig,
|
||||||
Visual** visual, int* depth);
|
Visual** visual, int* depth);
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetSystemDefaultThemeX11(void);
|
||||||
|
void _glfwSetThemeX11(_GLFWwindow* window, const _GLFWtheme* theme);
|
||||||
|
_GLFWtheme* _glfwGetThemeX11(_GLFWwindow* window, int inlineDefaults);
|
||||||
|
@ -3082,6 +3082,18 @@ const char* _glfwGetClipboardStringX11(void)
|
|||||||
return getSelectionString(_glfw.x11.CLIPBOARD);
|
return getSelectionString(_glfw.x11.CLIPBOARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwSetThemeX11(_GLFWwindow* window, const _GLFWtheme* theme)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
|
||||||
|
// TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFWtheme* _glfwGetThemeX11(_GLFWwindow* window, int inlineDefaults)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, NULL);
|
||||||
|
return NULL; // TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
EGLenum _glfwGetEGLPlatformX11(EGLint** attribs)
|
EGLenum _glfwGetEGLPlatformX11(EGLint** attribs)
|
||||||
{
|
{
|
||||||
if (_glfw.egl.ANGLE_platform_angle)
|
if (_glfw.egl.ANGLE_platform_angle)
|
||||||
|
@ -40,6 +40,7 @@ add_executable(timeout WIN32 MACOSX_BUNDLE timeout.c ${GLAD_GL})
|
|||||||
add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD_GL})
|
add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD_GL})
|
||||||
add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN})
|
add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN})
|
||||||
add_executable(window WIN32 MACOSX_BUNDLE window.c ${GLAD_GL})
|
add_executable(window WIN32 MACOSX_BUNDLE window.c ${GLAD_GL})
|
||||||
|
add_executable(theming WIN32 MACOSX_BUNDLE theming.c ${GLAD_GL})
|
||||||
|
|
||||||
target_link_libraries(empty Threads::Threads)
|
target_link_libraries(empty Threads::Threads)
|
||||||
target_link_libraries(threads Threads::Threads)
|
target_link_libraries(threads Threads::Threads)
|
||||||
@ -49,7 +50,7 @@ if (RT_LIBRARY)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks tearing threads
|
set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks tearing threads
|
||||||
timeout title triangle-vulkan window)
|
timeout title triangle-vulkan window theming)
|
||||||
set(CONSOLE_BINARIES allocator clipboard events msaa glfwinfo iconify monitors
|
set(CONSOLE_BINARIES allocator clipboard events msaa glfwinfo iconify monitors
|
||||||
reopen cursor)
|
reopen cursor)
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ if (APPLE)
|
|||||||
set_target_properties(timeout PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Timeout")
|
set_target_properties(timeout PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Timeout")
|
||||||
set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title")
|
set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title")
|
||||||
set_target_properties(window PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Window")
|
set_target_properties(window PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Window")
|
||||||
|
set_target_properties(theming PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Theming")
|
||||||
|
|
||||||
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
||||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
||||||
|
245
tests/theming.c
Normal file
245
tests/theming.c
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
//========================================================================
|
||||||
|
// Theming test program
|
||||||
|
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
//
|
||||||
|
// This program is used to test the theming features.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define GLAD_GL_IMPLEMENTATION
|
||||||
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
const float theme_colors[6][4] =
|
||||||
|
{
|
||||||
|
{ 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 void print_theme(const GLFWtheme* theme, const char* title)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
int variation = glfwThemeGetVariation(theme);
|
||||||
|
|
||||||
|
printf("%s: {\n", title);
|
||||||
|
printf(" Variation: %s\n", variation == GLFW_THEME_DEFAULT ? "default" : variation == GLFW_THEME_LIGHT ? "light" : "dark");
|
||||||
|
printf(" Attributes: [");
|
||||||
|
|
||||||
|
if (glfwThemeGetAttribute(theme, GLFW_THEME_COLOR_MAIN))
|
||||||
|
printf(n++ > 0 ? ", %s" : "%s", "COLOR_MAIN");
|
||||||
|
|
||||||
|
if (glfwThemeGetAttribute(theme, GLFW_THEME_ATTRIBUTE_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");
|
||||||
|
|
||||||
|
if (glfwThemeGetAttribute(theme, GLFW_THEME_COLOR_MAIN))
|
||||||
|
{
|
||||||
|
float r, g, b, a;
|
||||||
|
glfwThemeGetColor(theme, GLFW_THEME_COLOR_MAIN, &r, &g, &b, &a);
|
||||||
|
printf(" Main color: [%f, %f, %f, %f]\n", r, g, b, a);
|
||||||
|
}
|
||||||
|
printf("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_theme(GLFWwindow* window, int theme_color)
|
||||||
|
{
|
||||||
|
glfwThemeSetColor(
|
||||||
|
theme,
|
||||||
|
GLFW_THEME_COLOR_MAIN,
|
||||||
|
theme_colors[theme_color][0],
|
||||||
|
theme_colors[theme_color][1],
|
||||||
|
theme_colors[theme_color][2],
|
||||||
|
theme_colors[theme_color][3]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (theme_color == 5)
|
||||||
|
glfwThemeSetAttribute(theme, GLFW_THEME_COLOR_MAIN, GLFW_FALSE);
|
||||||
|
else
|
||||||
|
glfwThemeSetAttribute(theme, GLFW_THEME_COLOR_MAIN, GLFW_TRUE);
|
||||||
|
|
||||||
|
const char* title;
|
||||||
|
|
||||||
|
switch (glfwThemeGetVariation(theme)) {
|
||||||
|
case GLFW_THEME_DEFAULT:
|
||||||
|
title = "Default theme";
|
||||||
|
break;
|
||||||
|
case GLFW_THEME_LIGHT:
|
||||||
|
title = "Light theme";
|
||||||
|
break;
|
||||||
|
case GLFW_THEME_DARK:
|
||||||
|
title = "Dark theme";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwSetWindowTitle(window, title);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (action != GLFW_PRESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
// No theme specified
|
||||||
|
case GLFW_KEY_0:
|
||||||
|
glfwSetWindowTitle(window, "Default theme (NULL)");
|
||||||
|
glfwSetTheme(window, NULL);
|
||||||
|
break;
|
||||||
|
// Theme with default variation
|
||||||
|
case GLFW_KEY_1:
|
||||||
|
glfwThemeSetVariation(theme, GLFW_THEME_DEFAULT);
|
||||||
|
set_theme(window, cur_theme_color);
|
||||||
|
break;
|
||||||
|
// Theme with light variation
|
||||||
|
case GLFW_KEY_2:
|
||||||
|
glfwThemeSetVariation(theme, GLFW_THEME_LIGHT);
|
||||||
|
set_theme(window, cur_theme_color);
|
||||||
|
break;
|
||||||
|
// Theme with dark variation
|
||||||
|
case GLFW_KEY_3:
|
||||||
|
glfwThemeSetVariation(theme, GLFW_THEME_DARK);
|
||||||
|
set_theme(window, cur_theme_color);
|
||||||
|
break;
|
||||||
|
// Traverse colors
|
||||||
|
case GLFW_KEY_SPACE:
|
||||||
|
cur_theme_color = (cur_theme_color + 1) % 6;
|
||||||
|
set_theme(window, cur_theme_color);
|
||||||
|
break;
|
||||||
|
// Inspect
|
||||||
|
case GLFW_KEY_I:
|
||||||
|
print_theme(theme, "Constructed theme");
|
||||||
|
break;
|
||||||
|
// Print
|
||||||
|
case GLFW_KEY_P:
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void theme_callback(GLFWtheme* theme)
|
||||||
|
{
|
||||||
|
print_theme(theme, "System theme changed to");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
GLFWwindow* window;
|
||||||
|
|
||||||
|
if (!glfwInit())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to initialize GLFW\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_theme(glfwGetSystemDefaultTheme(), "System theme");
|
||||||
|
|
||||||
|
window = glfwCreateWindow(200, 200, "Window Icon", NULL, NULL);
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
glfwTerminate();
|
||||||
|
|
||||||
|
fprintf(stderr, "Failed to open GLFW window\n");
|
||||||
|
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);
|
||||||
|
gladLoadGL(glfwGetProcAddress);
|
||||||
|
|
||||||
|
glfwSetKeyCallback(window, key_callback);
|
||||||
|
|
||||||
|
theme = glfwCreateTheme();
|
||||||
|
set_theme(window, cur_theme_color);
|
||||||
|
|
||||||
|
glfwSetSystemThemeCallback(theme_callback);
|
||||||
|
|
||||||
|
while (!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
glClearColor(
|
||||||
|
theme_colors[cur_theme_color][0],
|
||||||
|
theme_colors[cur_theme_color][1],
|
||||||
|
theme_colors[cur_theme_color][2],
|
||||||
|
theme_colors[cur_theme_color][3]
|
||||||
|
);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
glfwWaitEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwDestroyTheme(theme);
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user