diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index a8f09f30c..0605494f2 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -592,6 +592,17 @@ static GLFWapplicationshouldhandlereopenfun handle_reopen_callback = NULL; return YES; } +- (void) viewWillStartLiveResize +{ + _glfwInputLiveResize(window, true); +} + +- (void)viewDidEndLiveResize +{ + _glfwInputLiveResize(window, false); +} + + - (BOOL)wantsUpdateLayer { return YES; diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 6f8cbf662..d531d2243 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1474,6 +1474,8 @@ typedef void (* GLFWkeyboardfun)(GLFWwindow*, int, int, int, int, const char*, i */ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); +typedef void (* GLFWliveresizefun)(GLFWwindow*, bool); + /*! @brief The function signature for monitor configuration callbacks. * * This is the function signature for monitor configuration callback functions. @@ -4343,6 +4345,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb * @ingroup input */ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); +GLFWAPI GLFWliveresizefun glfwSetLiveResizeCallback(GLFWwindow* window, GLFWliveresizefun cbfun); /*! @brief Returns whether the specified joystick is present. * diff --git a/glfw/internal.h b/glfw/internal.h index e40b8fd87..dce8d7ae1 100644 --- a/glfw/internal.h +++ b/glfw/internal.h @@ -419,6 +419,7 @@ struct _GLFWwindow GLFWscrollfun scroll; GLFWkeyboardfun keyboard; GLFWdropfun drop; + GLFWliveresizefun liveResize; } callbacks; // This is defined in the window API's platform.h @@ -653,6 +654,7 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int maxwidth, int maxheight); void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom); void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height); +void _glfwInputLiveResize(_GLFWwindow* window, bool started); void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom); diff --git a/glfw/window.c b/glfw/window.c index b341279dd..4ce6edda1 100644 --- a/glfw/window.c +++ b/glfw/window.c @@ -139,6 +139,14 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height) window->callbacks.fbsize((GLFWwindow*) window, width, height); } +// Notifies shared code that a window live resize is in progress +// +void _glfwInputLiveResize(_GLFWwindow* window, bool started) +{ + if (window->callbacks.liveResize) + window->callbacks.liveResize((GLFWwindow*) window, started); +} + // Notifies shared code that a window content scale has changed // The scale is specified as the ratio between the current and default DPI // @@ -1122,6 +1130,17 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle return cbfun; } +GLFWAPI GLFWliveresizefun glfwSetLiveResizeCallback(GLFWwindow* handle, + GLFWliveresizefun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.liveResize, cbfun); + return cbfun; +} + GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* handle, GLFWwindowcontentscalefun cbfun) { diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 83c02dd31..94823fefe 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -808,10 +808,14 @@ process_pending_resizes(double now) { for (size_t i = 0; i < global_state.num_os_windows; i++) { OSWindow *w = global_state.os_windows + i; if (w->has_pending_resizes) { - if (now - w->last_resize_event_at >= RESIZE_DEBOUNCE_TIME) update_os_window_viewport(w, true); - else { - global_state.has_pending_resizes = true; - set_maximum_wait(RESIZE_DEBOUNCE_TIME - now + w->last_resize_event_at); + if (w->has_live_resize_information) { + if (!w->live_resize_in_progress) update_os_window_viewport(w, true); + } else { + if (now - w->last_resize_event_at >= RESIZE_DEBOUNCE_TIME) update_os_window_viewport(w, true); + else { + global_state.has_pending_resizes = true; + set_maximum_wait(RESIZE_DEBOUNCE_TIME - now + w->last_resize_event_at); + } } } } diff --git a/kitty/glfw-wrapper.c b/kitty/glfw-wrapper.c index c6d027d67..3f5595582 100644 --- a/kitty/glfw-wrapper.c +++ b/kitty/glfw-wrapper.c @@ -290,6 +290,9 @@ load_glfw(const char* path) { *(void **) (&glfwSetDropCallback_impl) = dlsym(handle, "glfwSetDropCallback"); if (glfwSetDropCallback_impl == NULL) fail("Failed to load glfw function glfwSetDropCallback with error: %s", dlerror()); + *(void **) (&glfwSetLiveResizeCallback_impl) = dlsym(handle, "glfwSetLiveResizeCallback"); + if (glfwSetLiveResizeCallback_impl == NULL) fail("Failed to load glfw function glfwSetLiveResizeCallback with error: %s", dlerror()); + *(void **) (&glfwJoystickPresent_impl) = dlsym(handle, "glfwJoystickPresent"); if (glfwJoystickPresent_impl == NULL) fail("Failed to load glfw function glfwJoystickPresent with error: %s", dlerror()); diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index 903c83a2d..3f09e8354 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -1231,6 +1231,8 @@ typedef void (* GLFWkeyboardfun)(GLFWwindow*, int, int, int, int, const char*, i */ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); +typedef void (* GLFWliveresizefun)(GLFWwindow*, bool); + /*! @brief The function signature for monitor configuration callbacks. * * This is the function signature for monitor configuration callback functions. @@ -1791,6 +1793,10 @@ typedef GLFWdropfun (*glfwSetDropCallback_func)(GLFWwindow*, GLFWdropfun); glfwSetDropCallback_func glfwSetDropCallback_impl; #define glfwSetDropCallback glfwSetDropCallback_impl +typedef GLFWliveresizefun (*glfwSetLiveResizeCallback_func)(GLFWwindow*, GLFWliveresizefun); +glfwSetLiveResizeCallback_func glfwSetLiveResizeCallback_impl; +#define glfwSetLiveResizeCallback glfwSetLiveResizeCallback_impl + typedef int (*glfwJoystickPresent_func)(int); glfwJoystickPresent_func glfwJoystickPresent_impl; #define glfwJoystickPresent glfwJoystickPresent_impl diff --git a/kitty/glfw.c b/kitty/glfw.c index 262eed208..09b488524 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -128,6 +128,15 @@ window_iconify_callback(GLFWwindow *window, int iconified UNUSED) { global_state.callback_os_window = NULL; } +static void +live_resize_callback(GLFWwindow *w, bool started) { + if (!set_callback_window(w)) return; + global_state.callback_os_window->has_live_resize_information = true; + global_state.callback_os_window->live_resize_in_progress = started; + if (!started) request_tick_callback(); + global_state.callback_os_window = NULL; +} + static void framebuffer_size_callback(GLFWwindow *w, int width, int height) { if (!set_callback_window(w)) return; @@ -610,6 +619,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args) { glfwSetWindowIconifyCallback(glfw_window, window_iconify_callback); // missing maximize/restore callback glfwSetFramebufferSizeCallback(glfw_window, framebuffer_size_callback); + glfwSetLiveResizeCallback(glfw_window, live_resize_callback); glfwSetWindowContentScaleCallback(glfw_window, dpi_change_callback); glfwSetMouseButtonCallback(glfw_window, mouse_button_callback); glfwSetCursorPosCallback(glfw_window, cursor_pos_callback); diff --git a/kitty/state.h b/kitty/state.h index 84862ec07..1ff9f9410 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -126,6 +126,7 @@ typedef struct { bool is_key_pressed[MAX_KEY_COUNT]; bool viewport_size_dirty; double last_resize_event_at; + bool has_live_resize_information, live_resize_in_progress; bool has_pending_resizes, is_semi_transparent, shown_once, is_damaged; uint32_t offscreen_texture_id; unsigned int clear_count;