Another workaround for another macOS Tahoe bug

Dont redraw an OSWindow during a resize event if the resize event is
accompanied by a screen change as it causes a crash in macOS OpenGL
driver. Fixes #8983
This commit is contained in:
Kovid Goyal 2025-09-19 12:05:34 +05:30
parent 24b31d96e9
commit 7af7aa95c6
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
2 changed files with 36 additions and 3 deletions

View file

@ -179,6 +179,10 @@ Detailed list of changes
- macOS: Workaround for bug in macOS Tahoe that caused closed OS Windows to
remain as invisible rectangles that intercept mouse events (:iss:`8952`)
- macOS: Workaround for bug in macOS Tahoe that caused OS Windows that are
fullscreen on a monitor that is disconnected while macOS is asleep to crash kitty (:iss:`8983`)
0.42.2 [2025-07-16]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -521,6 +521,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
@interface GLFWWindowDelegate : NSObject
{
_GLFWwindow* window;
NSArray<NSDictionary *> *_lastScreenStates;
}
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;
@ -533,12 +534,26 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow
{
self = [super init];
if (self != nil)
if (self != nil) {
window = initWindow;
_lastScreenStates = [self captureScreenStates];
}
return self;
}
- (NSArray<NSDictionary *> *)captureScreenStates {
NSMutableArray *states = [NSMutableArray array];
for (NSScreen *screen in [NSScreen screens]) {
// Use the screen's deviceDescription, which contains a stable ID.
[states addObject:screen.deviceDescription];
}
return [states copy];
}
- (void)cleanup {
[_lastScreenStates release]; _lastScreenStates = nil;
}
- (BOOL)windowShouldClose:(id)sender
{
(void)sender;
@ -549,6 +564,16 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidResize:(NSNotification *)notification
{
(void)notification;
NSArray<NSDictionary *> *currentScreenStates = [self captureScreenStates];
const bool is_screen_change = ![_lastScreenStates isEqualToArray:currentScreenStates];
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.
[_lastScreenStates release];
_lastScreenStates = [currentScreenStates retain];
}
[currentScreenStates release];
if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update];
@ -580,7 +605,10 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
window->ns.height = (int)contentRect.size.height;
_glfwInputWindowSize(window, (int)contentRect.size.width, (int)contentRect.size.height);
}
if (window->ns.resizeCallback) window->ns.resizeCallback((GLFWwindow*)window);
// 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);
}
- (void)windowDidMove:(NSNotification *)notification
@ -1913,6 +1941,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
window->context.destroy(window);
[window->ns.object setDelegate:nil];
[window->ns.delegate cleanup];
[window->ns.delegate release];
window->ns.delegate = nil;