diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 9a8ed8751..22a42cec7 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -1010,6 +1010,18 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; _glfwInputCursorEnter(window, true); } +- (void)viewDidChangeEffectiveAppearance +{ + static int appearance = 0; + if (_glfw.callbacks.system_color_theme_change) { + int new_appearance = glfwGetCurrentSystemColorTheme(); + if (new_appearance != appearance) { + appearance = new_appearance; + _glfw.callbacks.system_color_theme_change(appearance); + } + } +} + - (void)viewDidChangeBackingProperties { if (!window) return; @@ -2957,6 +2969,19 @@ GLFWAPI void glfwCocoaRequestRenderFrame(GLFWwindow *w, GLFWcocoarenderframefun requestRenderFrame((_GLFWwindow*)w, callback); } +GLFWAPI int glfwGetCurrentSystemColorTheme(void) { + int theme_type = 0; + NSAppearance *changedAppearance = NSApp.effectiveAppearance; + NSAppearanceName newAppearance = [changedAppearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]]; + if([newAppearance isEqualToString:NSAppearanceNameDarkAqua]){ + theme_type = 1; + } else { + theme_type = 2; + } + return theme_type; +} + + GLFWAPI uint32_t glfwGetCocoaKeyEquivalent(uint32_t glfw_key, int glfw_mods, int *cocoa_mods) { *cocoa_mods = 0; diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 35507f9b3..9e60ed4af 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1368,6 +1368,22 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow*); */ typedef void (* GLFWapplicationclosefun)(int); +/*! @brief The function pointer type for system color theme change callbacks. + * + * This is the function pointer type for system color theme changes. + * @code + * void function_name(int theme_type) + * @endcode + * + * @param[in] theme_type 0 for unknown, 1 for dark and 2 for light + * + * @sa @ref glfwSetSystemColorThemeChangeCallback + * + * @ingroup window + */ +typedef void (* GLFWsystemcolorthemechangefun)(int); + + /*! @brief The function pointer type for window content refresh callbacks. * * This is the function pointer type for window content refresh callbacks. @@ -3906,6 +3922,8 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind */ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun callback); GLFWAPI GLFWapplicationclosefun glfwSetApplicationCloseCallback(GLFWapplicationclosefun callback); +GLFWAPI GLFWsystemcolorthemechangefun glfwSetSystemColorThemeChangeCallback(GLFWsystemcolorthemechangefun callback); +GLFWAPI int glfwGetCurrentSystemColorTheme(void); /*! @brief Sets the refresh callback for the specified window. * diff --git a/glfw/init.c b/glfw/init.c index d9fff1ae1..fb91f1c04 100644 --- a/glfw/init.c +++ b/glfw/init.c @@ -382,6 +382,14 @@ GLFWAPI GLFWapplicationclosefun glfwSetApplicationCloseCallback(GLFWapplicationc return cbfun; } +GLFWAPI GLFWapplicationclosefun glfwSetSystemColorThemeChangeCallback(GLFWsystemcolorthemechangefun cbfun) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(_glfw.callbacks.system_color_theme_change, cbfun); + return cbfun; +} + + GLFWAPI GLFWdrawtextfun glfwSetDrawTextFunction(GLFWdrawtextfun cbfun) { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); diff --git a/glfw/internal.h b/glfw/internal.h index f4044f6e7..d7729ecef 100644 --- a/glfw/internal.h +++ b/glfw/internal.h @@ -632,13 +632,13 @@ struct _GLFWlibrary GLFWmonitorfun monitor; GLFWjoystickfun joystick; GLFWapplicationclosefun application_close; + GLFWsystemcolorthemechangefun system_color_theme_change; GLFWdrawtextfun draw_text; GLFWcurrentselectionfun get_current_selection; GLFWhascurrentselectionfun has_current_selection; GLFWimecursorpositionfun get_ime_cursor_position; } callbacks; - // This is defined in the window API's platform.h _GLFW_PLATFORM_LIBRARY_WINDOW_STATE; // This is defined in the context API's context.h diff --git a/glfw/linux_desktop_settings.c b/glfw/linux_desktop_settings.c index 4cad9d97f..9a1a06ac9 100644 --- a/glfw/linux_desktop_settings.c +++ b/glfw/linux_desktop_settings.c @@ -24,6 +24,11 @@ static uint32_t appearance = 0; static bool is_gnome = false; static bool cursor_theme_changed = false; +int +glfw_current_system_color_theme(void) { + return appearance; +} + #define HANDLER(name) static void name(DBusMessage *msg, const char* errmsg, void *data) { \ (void)data; \ if (errmsg) { \ @@ -155,6 +160,9 @@ on_color_scheme_change(DBusMessage *message) { if (val > 2) val = 0; if (val != appearance) { appearance = val; + if (_glfw.callbacks.system_color_theme_change) { + _glfw.callbacks.system_color_theme_change(appearance); + } } } break; diff --git a/glfw/linux_desktop_settings.h b/glfw/linux_desktop_settings.h index 212974815..105100a67 100644 --- a/glfw/linux_desktop_settings.h +++ b/glfw/linux_desktop_settings.h @@ -12,3 +12,4 @@ void glfw_initialize_desktop_settings(void); void glfw_current_cursor_theme(const char **theme, int *size); +int glfw_current_system_color_theme(void); diff --git a/glfw/wl_init.c b/glfw/wl_init.c index 162df0431..6994afe3e 100644 --- a/glfw/wl_init.c +++ b/glfw/wl_init.c @@ -789,6 +789,10 @@ glfwWaylandCheckForServerSideDecorations(void) { return has_ssd ? "YES" : "NO"; } +GLFWAPI int glfwGetCurrentSystemColorTheme(void) { + return glfw_current_system_color_theme(); +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// diff --git a/glfw/x11_init.c b/glfw/x11_init.c index 40524d0ab..75e6c1a79 100644 --- a/glfw/x11_init.c +++ b/glfw/x11_init.c @@ -614,6 +614,10 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// +GLFWAPI int glfwGetCurrentSystemColorTheme(void) { + return 0; +} + int _glfwPlatformInit(void) { XInitThreads(); diff --git a/kitty/glfw-wrapper.c b/kitty/glfw-wrapper.c index 784615412..4753b0753 100644 --- a/kitty/glfw-wrapper.c +++ b/kitty/glfw-wrapper.c @@ -239,6 +239,12 @@ load_glfw(const char* path) { *(void **) (&glfwSetApplicationCloseCallback_impl) = dlsym(handle, "glfwSetApplicationCloseCallback"); if (glfwSetApplicationCloseCallback_impl == NULL) fail("Failed to load glfw function glfwSetApplicationCloseCallback with error: %s", dlerror()); + *(void **) (&glfwSetSystemColorThemeChangeCallback_impl) = dlsym(handle, "glfwSetSystemColorThemeChangeCallback"); + if (glfwSetSystemColorThemeChangeCallback_impl == NULL) fail("Failed to load glfw function glfwSetSystemColorThemeChangeCallback with error: %s", dlerror()); + + *(void **) (&glfwGetCurrentSystemColorTheme_impl) = dlsym(handle, "glfwGetCurrentSystemColorTheme"); + if (glfwGetCurrentSystemColorTheme_impl == NULL) fail("Failed to load glfw function glfwGetCurrentSystemColorTheme with error: %s", dlerror()); + *(void **) (&glfwSetWindowRefreshCallback_impl) = dlsym(handle, "glfwSetWindowRefreshCallback"); if (glfwSetWindowRefreshCallback_impl == NULL) fail("Failed to load glfw function glfwSetWindowRefreshCallback with error: %s", dlerror()); diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index 501220d9b..678a79187 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -1106,6 +1106,22 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow*); */ typedef void (* GLFWapplicationclosefun)(int); +/*! @brief The function pointer type for system color theme change callbacks. + * + * This is the function pointer type for system color theme changes. + * @code + * void function_name(int theme_type) + * @endcode + * + * @param[in] theme_type 0 for unknown, 1 for dark and 2 for light + * + * @sa @ref glfwSetSystemColorThemeChangeCallback + * + * @ingroup window + */ +typedef void (* GLFWsystemcolorthemechangefun)(int); + + /*! @brief The function pointer type for window content refresh callbacks. * * This is the function pointer type for window content refresh callbacks. @@ -1928,6 +1944,14 @@ typedef GLFWapplicationclosefun (*glfwSetApplicationCloseCallback_func)(GLFWappl GFW_EXTERN glfwSetApplicationCloseCallback_func glfwSetApplicationCloseCallback_impl; #define glfwSetApplicationCloseCallback glfwSetApplicationCloseCallback_impl +typedef GLFWsystemcolorthemechangefun (*glfwSetSystemColorThemeChangeCallback_func)(GLFWsystemcolorthemechangefun); +GFW_EXTERN glfwSetSystemColorThemeChangeCallback_func glfwSetSystemColorThemeChangeCallback_impl; +#define glfwSetSystemColorThemeChangeCallback glfwSetSystemColorThemeChangeCallback_impl + +typedef int (*glfwGetCurrentSystemColorTheme_func)(void); +GFW_EXTERN glfwGetCurrentSystemColorTheme_func glfwGetCurrentSystemColorTheme_impl; +#define glfwGetCurrentSystemColorTheme glfwGetCurrentSystemColorTheme_impl + typedef GLFWwindowrefreshfun (*glfwSetWindowRefreshCallback_func)(GLFWwindow*, GLFWwindowrefreshfun); GFW_EXTERN glfwSetWindowRefreshCallback_func glfwSetWindowRefreshCallback_impl; #define glfwSetWindowRefreshCallback glfwSetWindowRefreshCallback_impl