Embedding SDL within an NSView on macOS

I’m working on a macOS app using SDL and need the SDL content to be rendered in a window in which SDL isn’t the only thing presented. In particular, I need my SDL content to be presented as a panel in an NSSplitView, so that my window can have one or more Cocoa sidebars.

I looked at SDL_CreateWindowFrom(), but that doesn’t affect the hierarchy of views (and in fact, looking through the code, it seems that the SDLView doesn’t get created at all if you use SDL_CreateWindowFrom(), which is curious).

Then I toyed with deviously creating a standard SDL window, then yanking the content view (which is the SDLView) and moving it to be a child of a new NSSplitView, which I then make the content view (see my previous post on this) but that didn’t work quite right, as SDL gets confused about the resolution of the view, and events don’t reliably reach SDL. This didn’t really surprise me but I wanted to give it a shot.

It feels like what’s needed is a way for Cocoa applications to either:

  • Create a window using SDL_CreateWindow(), specifying either an existing NSView or a string identifying a nib file to load a the content view from, with that view then being inserted into the new window, with the SDLView then made a child of that view
  • Create a window using SDL_CreateWindowFrom(), specifying an NSView within that window to insert the new SDLView into

The second one makes more sense, though it would require either a SDL function like SDL_CreateView() to do the create and insert, or perhaps a platform-specific SDL_EmbedInCocoaView() function, which would take as input an existing NSView into which the SDLView would be placed, with the size and other such information being taken from the new parent view and its owning window as appropriate.

I’m sure there’s more involved than just stuffing it in a view; for one, event routing would have to be sorted out, but it’s not an insurmountable problem, I think. Of course, if there isn’t any broader need for this, I can save myself time by just hacking something up by directly embedding SDL and fudging things more deeply, but curious to see if anyone else has been needing this kind of capability – and if anyone has found a faster solution.

Looking through things further, I think one of the biggest issues I see is the use of [nswindow contentView] everywhere to find the SDLView’s parent view, rather than just saving an SDLView reference in the Cocoa-specific fields in the SDL_Window object and then using [((SDLView*)window->sdlView) superview] to get the parent view; this will work whether it’s the contentView (for regular SDL windows) or some other view (for embedding as a subview).

That and tweaking the places that access the view based on the created flag and we should be a lot of the way along…

1 Like

I found a SDL fork from 2017 that has code to accomplish NSView rendering on macOS (e.g. when using Qt). The relevant changes are here: https://github.com/flowercodec/sdl2/commit/616e6c429a037ef50ab9d0e454771a643f52e3fb

When I have some time I’ll rebase the patch on current SDL and upload to Bugzilla.

This would be great for feature-parity between Windows, Linux, and macOS!

Started a Bugzilla conversation with patch here: https://bugzilla.libsdl.org/show_bug.cgi?id=5060