From 270c598f2c73ad8dda9121d9e2063c6e7e3b0aef Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 2 Oct 2025 19:39:13 +0530 Subject: [PATCH] macOS: Only live resize for resize events that occur in quick succession Apparently on some systems Tahoe sends a resize event on wake from sleep/lid open for obscure reasons and then proceeds to crash if one redraws during that event. Sigh. --- glfw/cocoa_window.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index bdfb79169..e70434ad5 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -522,6 +522,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; { _GLFWwindow* window; NSArray *_lastScreenStates; + monotonic_t last_resize_event_at; } - (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow; @@ -537,6 +538,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; if (self != nil) { window = initWindow; _lastScreenStates = [self captureScreenStates]; + last_resize_event_at = 0; } return self; } @@ -566,6 +568,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; (void)notification; NSArray *currentScreenStates = [self captureScreenStates]; const bool is_screen_change = ![_lastScreenStates isEqualToArray:currentScreenStates]; + monotonic_t now = monotonic(); debug_rendering("windowDidResize() called, is_screen_change: %d\n", is_screen_change); if (is_screen_change) { // This resize likely happened because a screen was added, removed, or changed resolution. @@ -605,10 +608,14 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; window->ns.height = (int)contentRect.size.height; _glfwInputWindowSize(window, (int)contentRect.size.width, (int)contentRect.size.height); } + monotonic_t time_since_last_resize_event = now - last_resize_event_at; + last_resize_event_at = now; // Because of a bug in macOS Tahoe we cannot redraw the window in response // to a resize event that was caused by a screen change as the OpenGL // context is not ready yet. See: https://github.com/kovidgoyal/kitty/issues/8983 - if (window->ns.resizeCallback && !is_screen_change) window->ns.resizeCallback((GLFWwindow*)window); + // Similarly, on some systems there is resize on lid open, so only do live + // resizing for events arriving in quick sequence. + if (window->ns.resizeCallback && !is_screen_change && time_since_last_resize_event <= ms_to_monotonic_t(1000)) window->ns.resizeCallback((GLFWwindow*)window); } - (void)windowDidMove:(NSNotification *)notification