diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 96b2c8a41..9e4e8f9e3 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1662,6 +1662,7 @@ GLFWAPI void glfwRunMainLoop(GLFWtickcallback callback, void *callback_data); GLFWAPI void glfwStopMainLoop(void); GLFWAPI void glfwRequestTickCallback(void); GLFWAPI unsigned long long glfwAddTimer(double interval, bool repeats, GLFWuserdatafun callback, void * callback_data, GLFWuserdatafun free_callback); +GLFWAPI void glfwUpdateTimer(unsigned long long timer_id, double interval, bool enabled); GLFWAPI void glfwRemoveTimer(unsigned long long); /*! @brief Terminates the GLFW library. diff --git a/glfw/init.c b/glfw/init.c index 6e9fe4db2..436d87c31 100644 --- a/glfw/init.c +++ b/glfw/init.c @@ -344,6 +344,10 @@ GLFWAPI unsigned long long glfwAddTimer( return _glfwPlatformAddTimer(interval, repeats, callback, callback_data, free_callback); } +GLFWAPI void glfwUpdateTimer(unsigned long long timer_id, double interval, bool enabled) { + _glfwPlatformUpdateTimer(timer_id, interval, enabled); +} + GLFWAPI void glfwRemoveTimer(unsigned long long timer_id) { _glfwPlatformRemoveTimer(timer_id); } diff --git a/glfw/internal.h b/glfw/internal.h index e09e29959..ca7ff108b 100644 --- a/glfw/internal.h +++ b/glfw/internal.h @@ -787,6 +787,7 @@ void _glfwPlatformRunMainLoop(GLFWtickcallback, void*); void _glfwPlatformRequestTickCallback(); void _glfwPlatformStopMainLoop(void); unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuserdatafreefun callback, void *callback_data, GLFWuserdatafreefun free_callback); +void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, GLFWbool enabled); void _glfwPlatformRemoveTimer(unsigned long long timer_id); char* _glfw_strdup(const char* source); diff --git a/glfw/main_loop.h b/glfw/main_loop.h index 1353abdbb..56b337978 100644 --- a/glfw/main_loop.h +++ b/glfw/main_loop.h @@ -44,3 +44,8 @@ unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuser void _glfwPlatformRemoveTimer(unsigned long long timer_id) { removeTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id); } + +void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, GLFWbool enabled) { + changeTimerInterval(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id, interval); + toggleTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id, enabled); +} diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index ebe672901..98c83604b 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -865,7 +865,6 @@ set_cocoa_pending_action(CocoaPendingAction action, const char *wd) { } #endif -static id_type state_check_timer = 0; static void process_global_state(void *data); static void @@ -874,20 +873,13 @@ do_state_check(id_type timer_id UNUSED, void *data) { process_global_state(self); } -static void -request_global_state_check_in(double seconds, ChildMonitor *self) { - if (state_check_timer) remove_main_loop_timer(state_check_timer); - state_check_timer = add_main_loop_timer(seconds, false, do_state_check, self, NULL); -} +static id_type state_check_timer = 0; static void process_global_state(void *data) { ChildMonitor *self = data; - if (state_check_timer) { - remove_main_loop_timer(state_check_timer); - state_check_timer = 0; - } maximum_wait = -1; + bool state_check_timer_enabled = false; double now = monotonic(); if (global_state.has_pending_resizes) process_pending_resizes(now); @@ -918,16 +910,18 @@ process_global_state(void *data) { if (has_open_windows) { if (maximum_wait >= 0) { if (maximum_wait == 0) request_tick_callback(); - else request_global_state_check_in(maximum_wait, self); + else state_check_timer_enabled = true; } } else { stop_main_loop(); } + update_main_loop_timer(state_check_timer, MAX(0, maximum_wait), state_check_timer_enabled); } static PyObject* main_loop(ChildMonitor *self, PyObject *a UNUSED) { #define main_loop_doc "The main thread loop" + state_check_timer = add_main_loop_timer(1000, true, do_state_check, self, NULL); run_main_loop(process_global_state, self); #ifdef __APPLE__ if (cocoa_pending_actions_wd) { free(cocoa_pending_actions_wd); cocoa_pending_actions_wd = NULL; } diff --git a/kitty/glfw-wrapper.c b/kitty/glfw-wrapper.c index 08d2b76b8..b6c17e7d1 100644 --- a/kitty/glfw-wrapper.c +++ b/kitty/glfw-wrapper.c @@ -29,6 +29,9 @@ load_glfw(const char* path) { *(void **) (&glfwAddTimer_impl) = dlsym(handle, "glfwAddTimer"); if (glfwAddTimer_impl == NULL) fail("Failed to load glfw function glfwAddTimer with error: %s", dlerror()); + *(void **) (&glfwUpdateTimer_impl) = dlsym(handle, "glfwUpdateTimer"); + if (glfwUpdateTimer_impl == NULL) fail("Failed to load glfw function glfwUpdateTimer with error: %s", dlerror()); + *(void **) (&glfwRemoveTimer_impl) = dlsym(handle, "glfwRemoveTimer"); if (glfwRemoveTimer_impl == NULL) fail("Failed to load glfw function glfwRemoveTimer with error: %s", dlerror()); diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index f060b3ecc..34977f0c3 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -1443,6 +1443,10 @@ typedef unsigned long long (*glfwAddTimer_func)(double, bool, GLFWuserdatafun, v glfwAddTimer_func glfwAddTimer_impl; #define glfwAddTimer glfwAddTimer_impl +typedef void (*glfwUpdateTimer_func)(unsigned long long, double, bool); +glfwUpdateTimer_func glfwUpdateTimer_impl; +#define glfwUpdateTimer glfwUpdateTimer_impl + typedef void (*glfwRemoveTimer_func)(unsigned long); glfwRemoveTimer_func glfwRemoveTimer_impl; #define glfwRemoveTimer glfwRemoveTimer_impl diff --git a/kitty/glfw.c b/kitty/glfw.c index 8da249695..34fb0aefb 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -1130,6 +1130,11 @@ add_main_loop_timer(double interval, bool repeats, timer_callback_fun callback, return glfwAddTimer(interval, repeats, callback, callback_data, free_callback); } +void +update_main_loop_timer(id_type timer_id, double interval, bool enabled) { + glfwUpdateTimer(timer_id, interval, enabled); +} + void remove_main_loop_timer(id_type timer_id) { glfwRemoveTimer(timer_id); diff --git a/kitty/state.h b/kitty/state.h index 6bece32ca..569397128 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -223,6 +223,7 @@ typedef void (* timer_callback_fun)(id_type, void*); typedef void (* tick_callback_fun)(void*); id_type add_main_loop_timer(double interval, bool repeats, timer_callback_fun callback, void *callback_data, timer_callback_fun free_callback); void remove_main_loop_timer(id_type timer_id); +void update_main_loop_timer(id_type timer_id, double interval, bool enabled); void run_main_loop(tick_callback_fun, void*); void request_tick_callback(void); void stop_main_loop(void);