SDL_WINDOW_OPENGL on Mac Sonoma, SDL 2.28.5 not working

Trying to upgrade my SDL2 OpenGL game to run on my new Mac. Previously on OSX Monterey it worked, and with an old SDL2.0.4 I think. Now on Sonoma and Apple Silicon, I downloaded the 2.28.5 SDL2 release and use it as a Framework. But SDL_CreateWindow using the SDL_WINDOW_OPENGL flag does not create an OpenGL-capable window, as is evident by SDL_GL_CreateContext failing subsequently with the error “The specified window isn’t an OpenGL window”. Enabling debug printouts from SDL2 it gives this:

2024-01-30 02:23:03.242 thegame[39355:3961750] INFO: Created renderer: metal
Got SDL surface of 1024 by 600 pixels <--- my own debug printout from the window returned
2024-01-30 02:23:03.242 thegame[39355:3961750] DEBUG: The specified window isn't an OpenGL window

I don’t call SDL_CreateRenderer at all (neither do the SDL examples using GL). Isn’t it supposed to say Created renderer: OpenGL and not metal?

Any ideas? I’ve read a bunch of threads talking about a similar situation, but all of them were caused by calling CreateRenderer with inappropriate parameters and I don’t do that at all, or by using incorrect SDL2 includes etc. I’ve checked that everything is linked from the 2.28.5 SDL2 Framework and all SDL2 headers come from that…

So I found the problem, answering myself here in case someone else runs into this sometime.

In between my SDL_CreateWindow() call and SDL_GL_CreateContext() call I discovered that the window->flags SDL_WINDOW_OPENGL flag disappeared magically!

The only thing in between I did, was call two functions I had called since very long back, to get the window’s width and height:

	int dwidth = SDL_GetWindowSurface(sdl_window)->w;
	int dheight = SDL_GetWindowSurface(sdl_window)->h;
	
	printf("Got SDL surface of %d by %d pixels\n", dwidth, dheight);

But as it turns out, that code was NOT without side-effects - the GetWindowSurface calls actually destroys the window and re-creates it, this time clearing the SDL_WINDOW_OPENGL flag. So when the code got to the SDL_GL_CreateContext, the window was a “Metal” window and not an “OpenGL” window anymore.

I replaced the code with SDL_GetWindowSize() and everything works.

In the doc for GetWindowSurface it does state “You may not combine this with 3D or the rendering API on this window.” so I guess this makes sense, but was confusing that it has worked since previous versions of SDL2. It could be useful to log at least in the debug log that a window surface is destroyed and re-created with other parameters and capabilities, even if my use of GetWindowSurface() was stupid in this case.

It’s worth mentioning that SDL_WINDOW_OPENGL (and equivalents for Vulkan, Metal, etc) are no longer required by SDL.

You can create a regular window, and when creating the GL context SDL will do whatever is necessary on the given platform to make that window work with OpenGL.

(trying to access the window surface still makes creating GL context fail)