SDL3 error on SDL_DestroyWindow in full-screen mode
I create a window and set it to full-screen via SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN), everything works fine. However, when I call SDL_DestroyWindow(window) while the window is still in full-screen mode, it throws an error.
1 HIToolbox 0x00007ff822e17726 _ZN15MenuBarInstance22EnsureAutoShowObserverEv + 102 2 HIToolbox 0x00007ff822e172b8 _ZN15MenuBarInstance14EnableAutoShowEv + 52 3 HIToolbox 0x00007ff822d86cd7 _ZN15MenuBarInstance21UpdateAggregateUIModeE21MenuBarAnimationStylehhh + 1113 4 HIToolbox 0x00007ff822d8681f _ZN15MenuBarInstance16ForEachMenuBarDoEU13block_pointerFvPS_E + 169 5 HIToolbox 0x00007ff822d86762 SetSystemUIMode + 209 6 AppKit 0x00007ff81cc00f08 +[NSMenu setMenuBarVisible:] + 11 7 CoreFoundation 0x00007ff81944e3d4 CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER + 137 8 CoreFoundation 0x00007ff8194e841a ___CFXRegistrationPost_block_invoke + 88 9 CoreFoundation 0x00007ff8194e8369 _CFXRegistrationPost + 536 10 CoreFoundation 0x00007ff8194218f9 _CFXNotificationPost + 735 11 Foundation 0x00007ff81a25dabc -[NSNotificationCenter postNotificationName:object:userInfo:] + 82 12 AppKit 0x00007ff81c7443d1 -[NSWindow resignKeyWindow] + 758 13 AppKit 0x00007ff81cef2efe -[NSWindow _orderOut:calculatingKeyWithOptions:documentWindow:] + 319 14 AppKit 0x00007ff81c5f3302 NSPerformVisuallyAtomicChange + 132 15 AppKit 0x00007ff81cef4fa9 -[NSWindow _reallyDoOrderWindowOutRelativeTo:] + 634 16 AppKit 0x00007ff81cef53b4 -[NSWindow _reallyDoOrderWindow:] + 99 17 AppKit 0x00007ff81cef562a -[NSWindow _doOrderWindow:] + 295 18 libSDL3.0.dylib 0x000000010d4479a8 Cocoa_HideWindow + 133 19 libSDL3.0.dylib 0x000000010d3f5c2b SDL_HideWindow_REAL + 133 20 libSDL3.0.dylib 0x000000010d3f5233 SDL_DestroyWindow_REAL + 155
If I use windowed mode (SDL_SetWindowFullscreen(window, 0)) and then destroy the window, there is no error.
This isn't crashing for me. I've modified the renderer-clear example to take the window and make it fullscreen on the first press of the space bar, and then destroy it on the second.
/*
* This example code creates an SDL window and renderer, and then clears the
* window to a different color every frame, so you'll effectively get a window
* that's smoothly fading between colors.
*
* This code is public domain. Feel free to use it for any purpose!
*/
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
/* We will use this renderer to draw into this window every frame. */
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
/* This function runs once at startup. */
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
SDL_SetAppMetadata("Example Renderer Clear", "1.0", "com.example.renderer-clear");
if (!SDL_Init(SDL_INIT_VIDEO)) {
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
if (!SDL_CreateWindowAndRenderer("examples/renderer/clear", 640, 480, 0, &window, &renderer)) {
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
SDL_SetRenderLogicalPresentation(renderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX);
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
if (event->type == SDL_EVENT_QUIT) {
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
} else if ((event->type == SDL_EVENT_KEY_DOWN) && (event->key.key == SDLK_SPACE)) {
if (window) {
static int pass = 0;
pass++;
if (pass == 1) {
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
} else if (pass == 2) {
SDL_DestroyWindow(window);
window = NULL;
}
}
}
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs once per frame, and is the heart of the program. */
SDL_AppResult SDL_AppIterate(void *appstate)
{
const double now = ((double)SDL_GetTicks()) / 1000.0; /* convert from milliseconds to seconds. */
/* choose the color for the frame we will draw. The sine wave trick makes it fade between colors smoothly. */
const float red = (float) (0.5 + 0.5 * SDL_sin(now));
const float green = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 2 / 3));
const float blue = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 4 / 3));
SDL_SetRenderDrawColorFloat(renderer, red, green, blue, SDL_ALPHA_OPAQUE_FLOAT); /* new color, full alpha. */
/* clear the window to the draw color. */
SDL_RenderClear(renderer);
/* put the newly-cleared rendering on the screen. */
SDL_RenderPresent(renderer);
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs once at shutdown. */
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
/* SDL will clean up the window/renderer for us. */
}
Does this also crash for you? And if so, what versions of SDL and macOS are you using? It might be something we already fixed, or something that macOS fixed (or broke!) in a different version.
I'm on Sequoia 15.4.1, and the latest in SDL3 revision control.
Can confirm, this problem happens to me too (in a codebase that's too big to make an example out of) and in that case I get a Bad Window Parameter crash on X11 XFCE. The problem is, this bug is very inconsistent. Perhaps try waiting a moment while you make your example code draw a lot of stuff ? It never happens right away.
The original report was on macOS, and looks Cocoa-specific, so this is likely a different problem.
If you can reproduce this in your program and it's something I can run here, I'm happy to see if I can trigger it.
mac 13.2 sdl 3.2.22
Can you provide a complete executable example for this— including the main() function — and show the exact steps to run it? I’m not familiar with how to set up the example from examples/renderer/clear. Should I clone the SDL project and build it myself, or can I dynamically link against the SDL version installed through Homebrew?
In my case, the fullscreen mode always triggers that error, and it’s 100% reproducible.