Skip to content

Macos: Rendering to an external NSView doesn't work in practice #12141

Description

@leksiso

I'm trying to use SDL to render custom content in a mac cocoa application with Metal as the SDL backend. What I want to do is to manually initialize an NSView (that doesn't fill the whole window) and tell SDL to render to it. I can see that there's some support for the above scenario in SDL. However, it doesn't seem to work very well (unless I'm missing something).

As a proof of concept, I'm trying to achieve the following:

  • Create a native view with some coords & size, make it blue with the platform APIs:
Image
  • Create a SDL window with a reference to that native view using SDL_PROP_WINDOW_CREATE_COCOA_VIEW_POINTER.
  • When the button is pressed, fill the SDL window with red
Image

What currently happens:

Image

SDL_CreateWindowWithProperties takes the view I gave to it and makes it the window root view (NSWindow.contentView).
I understand that SDL is usually used in a full window context, but I'd argue that it's a bug in this case.

This can be fixed by moving [nswindow setContentView:nsview]; from line 2357 in SDL_cocoawindow.m to line 2319 (i.e. to the end of the else branch of if (nswindow) {)

With that change, the window constructor doesn't hijack the whole window. However pressing the button doesn't still do quite what I'd like it to do:

Image

Clearing the SDL window fills the whole NSWindow instead of just the NSView. This is caused by the fact that Cocoa_Metal_CreateView uses data.nswindow.contentView as the superview of the metal view. I think using data.sdlContentView would be more appropriate in that function.
If we do that, my test works almost as expected:

Image

Now the only problem is that the origin of the metal view is wrong. This could be fixed by changing line SDL_cocoametalview.m:144 from newview = [[SDL3_cocoametalview alloc] initWithFrame:view.frame to newview = [[SDL3_cocoametalview alloc] initWithFrame:view.bounds.

With these changes, the rendering works more like I would expect it to. Could give some comments on this? Is the API even supposed to work as I'm presenting above? If yes, would you like me to submit a PR with the above changes?

I'll include my test setup code as a zip.

SDLMetalViewTest.zip

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions