# HG changeset patch # User Michael Maltese # Date 1585179643 25200 # Wed Mar 25 16:40:43 2020 -0700 # Node ID ca4a429b22e89989ffe9eaf02edb2ab3d827ce8b # Parent 389ce8cfa2a31f765c3d751c911c73abf5c60e33 cocoa: allow calling CreateWindowFrom on an NSView This lets applications embed SDL with other widgets surrounding it. Already possible on Windows and X11. diff -r 389ce8cfa2a3 -r ca4a429b22e8 src/video/cocoa/SDL_cocoaopengl.m --- a/src/video/cocoa/SDL_cocoaopengl.m Wed Mar 25 09:38:45 2020 -0700 +++ b/src/video/cocoa/SDL_cocoaopengl.m Wed Mar 25 16:40:43 2020 -0700 @@ -97,17 +97,6 @@ SDL_WindowData *windowdata = (SDL_WindowData *)newWindow->driverdata; NSView *contentview = windowdata->sdlContentView; - /* This should never be nil since sdlContentView is only nil if the - window was created via SDL_CreateWindowFrom, and SDL doesn't allow - OpenGL contexts to be created in that case. However, it doesn't hurt - to check. */ - if (contentview == nil) { - /* Prefer to access the cached content view above instead of this, - since as of Xcode 11 + SDK 10.15, [window contentView] causes - Apple's Main Thread Checker to output a warning. */ - contentview = [windowdata->nswindow contentView]; - } - /* Now sign up for scheduled updates for the new window. */ NSMutableArray *contexts = windowdata->nscontexts; @synchronized (contexts) { @@ -362,7 +351,7 @@ Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) { SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - NSView *contentView = [windata->nswindow contentView]; + NSView *contentView = windata->sdlContentView; NSRect viewport = [contentView bounds]; if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { diff -r 389ce8cfa2a3 -r ca4a429b22e8 src/video/cocoa/SDL_cocoashape.m --- a/src/video/cocoa/SDL_cocoashape.m Wed Mar 25 09:38:45 2020 -0700 +++ b/src/video/cocoa/SDL_cocoashape.m Wed Mar 25 16:40:43 2020 -0700 @@ -88,10 +88,10 @@ [NSGraphicsContext setCurrentContext:data->context]; [[NSColor clearColor] set]; - NSRectFill([[windata->nswindow contentView] frame]); + NSRectFill([windata->sdlContentView frame]); data->shape = SDL_CalculateShapeTree(*shape_mode,shape); - closure.view = [windata->nswindow contentView]; + closure.view = windata->sdlContentView; closure.path = [NSBezierPath bezierPath]; closure.window = shaper->window; SDL_TraverseShapeTree(data->shape,&ConvertRects,&closure); diff -r 389ce8cfa2a3 -r ca4a429b22e8 src/video/cocoa/SDL_cocoawindow.h --- a/src/video/cocoa/SDL_cocoawindow.h Wed Mar 25 09:38:45 2020 -0700 +++ b/src/video/cocoa/SDL_cocoawindow.h Wed Mar 25 16:40:43 2020 -0700 @@ -113,7 +113,7 @@ { SDL_Window *window; NSWindow *nswindow; - NSView *sdlContentView; /* nil if window is created via CreateWindowFrom */ + NSView *sdlContentView; NSMutableArray *nscontexts; SDL_bool created; SDL_bool inWindowFullscreenTransition; diff -r 389ce8cfa2a3 -r ca4a429b22e8 src/video/cocoa/SDL_cocoawindow.m --- a/src/video/cocoa/SDL_cocoawindow.m Wed Mar 25 09:38:45 2020 -0700 +++ b/src/video/cocoa/SDL_cocoawindow.m Wed Mar 25 16:40:43 2020 -0700 @@ -297,15 +297,15 @@ NSWindow *nswindow = data->nswindow; /* The view responder chain gets messed with during setStyleMask */ - if ([[nswindow contentView] nextResponder] == data->listener) { - [[nswindow contentView] setNextResponder:nil]; + if ([data->sdlContentView nextResponder] == data->listener) { + [data->sdlContentView setNextResponder:nil]; } [nswindow setStyleMask:style]; /* The view responder chain gets messed with during setStyleMask */ - if ([[nswindow contentView] nextResponder] != data->listener) { - [[nswindow contentView] setNextResponder:data->listener]; + if ([data->sdlContentView nextResponder] != data->listener) { + [data->sdlContentView setNextResponder:data->listener]; } return SDL_TRUE; @@ -318,7 +318,7 @@ { NSNotificationCenter *center; NSWindow *window = data->nswindow; - NSView *view = [window contentView]; + NSView *view = data->nsview; _data = data; observingVisible = YES; @@ -1360,7 +1360,7 @@ @end static int -SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created) +SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview, SDL_bool created) { @autoreleasepool { SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; @@ -1376,11 +1376,7 @@ data->created = created; data->videodata = videodata; data->nscontexts = [[NSMutableArray alloc] init]; - - /* Only store this for windows created by us since the content view might - * get replaced from under us otherwise, and we only need it when the - * window is guaranteed to be created by us (OpenGL contexts). */ - data->sdlContentView = created ? [nswindow contentView] : nil; + data->sdlContentView = nsview; /* Create an event listener for the window */ data->listener = [[Cocoa_WindowListener alloc] init]; @@ -1541,7 +1537,7 @@ [nswindow setContentView:contentView]; [contentView release]; - if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) { + if (SetupWindowData(_this, window, nswindow, contentView, SDL_TRUE) < 0) { [nswindow release]; return -1; } @@ -1571,7 +1567,19 @@ Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { @autoreleasepool { - NSWindow *nswindow = (NSWindow *) data; + NSView* nsview; + NSWindow *nswindow; + + if ([(id)data isKindOfClass:[NSWindow class]]) { + nswindow = (NSWindow*)data; + nsview = [nswindow contentView]; + } else if ([(id)data isKindOfClass:[NSView class]]) { + nsview = (NSView*)data; + nswindow = [nsview window]; + } else { + SDL_assert(false); + } + NSString *title; /* Query the title from the existing window */ @@ -1580,7 +1588,7 @@ window->title = SDL_strdup([title UTF8String]); } - return SetupWindowData(_this, window, nswindow, SDL_FALSE); + return SetupWindowData(_this, window, nswindow, nsview, SDL_FALSE); }} void @@ -1795,8 +1803,8 @@ NSRect rect; /* The view responder chain gets messed with during setStyleMask */ - if ([[nswindow contentView] nextResponder] == data->listener) { - [[nswindow contentView] setNextResponder:nil]; + if ([data->sdlContentView nextResponder] == data->listener) { + [data->sdlContentView setNextResponder:nil]; } if (fullscreen) { @@ -1852,8 +1860,8 @@ } /* The view responder chain gets messed with during setStyleMask */ - if ([[nswindow contentView] nextResponder] != data->listener) { - [[nswindow contentView] setNextResponder:data->listener]; + if ([data->sdlContentView nextResponder] != data->listener) { + [data->sdlContentView setNextResponder:data->listener]; } s_moveHack = 0;