mirror of https://github.com/encounter/SDL.git
cocoa: allow calling CreateWindowFrom on an NSView
This lets applications embed SDL with other widgets surrounding it. Already possible on Windows and X11. Fixes Bugzilla #5060.
This commit is contained in:
parent
8641f6e99d
commit
361417c0a4
|
@ -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) {
|
||||
|
@ -382,7 +371,7 @@ void
|
|||
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) {
|
||||
|
|
|
@ -88,10 +88,10 @@ Cocoa_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowSha
|
|||
[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);
|
||||
|
|
|
@ -113,7 +113,7 @@ struct SDL_WindowData
|
|||
{
|
||||
SDL_Window *window;
|
||||
NSWindow *nswindow;
|
||||
NSView *sdlContentView; /* nil if window is created via CreateWindowFrom */
|
||||
NSView *sdlContentView;
|
||||
NSMutableArray *nscontexts;
|
||||
SDL_bool created;
|
||||
SDL_bool inWindowFullscreenTransition;
|
||||
|
|
|
@ -297,15 +297,15 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
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 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
{
|
||||
NSNotificationCenter *center;
|
||||
NSWindow *window = data->nswindow;
|
||||
NSView *view = [window contentView];
|
||||
NSView *view = data->nsview;
|
||||
|
||||
_data = data;
|
||||
observingVisible = YES;
|
||||
|
@ -1360,7 +1360,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
@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 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created
|
|||
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 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
|
|||
[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 @@ int
|
|||
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 @@ Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
|
|||
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 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
|
|||
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 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
|
Loading…
Reference in New Issue