diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index f3ef8b205..9496c0c40 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -3253,6 +3253,14 @@ bool _glfwPlatformToggleFullscreen(_GLFWwindow* w, unsigned int flags) { // As of Big Turd NSWindowStyleMaskFullScreen is no longer usable // Also no longer compatible after a minor release of macOS 10.15.7 if (!w->ns.in_traditional_fullscreen) { + // Apple throws NSGenericException if setStyleMask: clears + // NSWindowStyleMaskFullScreen outside a transition (see #9572). + // Split View sets this flag via the system, so fall back to + // Cocoa fullscreen toggle instead of the traditional path. + if (sm & NSWindowStyleMaskFullScreen) { + [window toggleFullScreen:nil]; + return false; + } w->ns.pre_full_screen_style_mask = sm; [window setStyleMask: NSWindowStyleMaskBorderless]; [[NSApplication sharedApplication] setPresentationOptions: NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock]; @@ -3260,7 +3268,9 @@ bool _glfwPlatformToggleFullscreen(_GLFWwindow* w, unsigned int flags) { w->ns.in_traditional_fullscreen = true; } else { made_fullscreen = false; - [window setStyleMask: w->ns.pre_full_screen_style_mask]; + // Same NSWindowStyleMaskFullScreen guard as glfwCocoaSetWindowChrome + NSWindowStyleMask fsmask = sm & NSWindowStyleMaskFullScreen; + [window setStyleMask: w->ns.pre_full_screen_style_mask | fsmask]; [[NSApplication sharedApplication] setPresentationOptions: NSApplicationPresentationDefault]; w->ns.in_traditional_fullscreen = false; } diff --git a/kitty/glfw.c b/kitty/glfw.c index 0741a3a48..5f842bc05 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -1291,6 +1291,14 @@ intercept_cocoa_fullscreen(GLFWwindow *w) { global_state.callback_os_window); return false; } + // macOS Split View uses Cocoa fullscreen internally, so the window + // can end up with NSWindowStyleMaskFullScreen set even when + // macos_traditional_fullscreen is enabled. Redirecting to traditional + // fullscreen would crash in setStyleMask: (see #9572). + if (glfwIsFullscreen(w, 1)) { + global_state.callback_os_window->background_opacity.os_forces_opaque = false; + return false; + } toggle_fullscreen_for_os_window(global_state.callback_os_window); global_state.callback_os_window = NULL; return true;