Mojave workarounds from dosbox-x: https://github.com/joncampbell123/dosbox-x/commit/fdf6061c05dcb35a1ea111ad5b75ade350059df3 https://github.com/joncampbell123/dosbox-x/commit/347ffff35507177a2004a62e28493126d5f4dc81 https://github.com/joncampbell123/dosbox-x/commit/53e3ab2306ba2f2724ca3cb9f2c27608313c1ea5 https://github.com/joncampbell123/dosbox-x/commit/2c683142151171ba28a603b0724b6663bcd8ed98 diff --git a/src/video/quartz/SDL_QuartzVideo.m b/src/video/quartz/SDL_QuartzVideo.m --- a/src/video/quartz/SDL_QuartzVideo.m +++ b/src/video/quartz/SDL_QuartzVideo.m @@ -938,10 +938,14 @@ static SDL_Surface* QZ_SetVideoFullScree mode_flags = current->flags; /* Set app state, hide cursor if necessary, ... */ QZ_DoActivate(this); + [ window_view setNeedsDisplay:YES ]; + [ [ qz_window contentView ] setNeedsDisplay:YES ]; + [ qz_window displayIfNeeded ]; + return current; /* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */ ERR_NO_GL: goto ERR_DOUBLEBUF; /* this goto is to stop a compiler warning on newer SDKs. */ ERR_DOUBLEBUF: QZ_RestoreDisplayMode(this); @@ -1114,10 +1118,14 @@ static SDL_Surface* QZ_SetVideoWindowed } /* Save flags to ensure correct teardown */ mode_flags = current->flags; + [ window_view setNeedsDisplay:YES ]; + [ [ qz_window contentView ] setNeedsDisplay:YES ]; + [ qz_window displayIfNeeded ]; + /* Fade in again (asynchronously) if we came from a fullscreen mode and faded to black */ if (fade_token != kCGDisplayFadeReservationInvalidToken) { CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); CGReleaseDisplayFadeReservation (fade_token); } @@ -1153,11 +1161,17 @@ static SDL_Surface* QZ_SetVideoModeInter return NULL; } if (qz_window != nil) { nsgfx_context = [NSGraphicsContext graphicsContextWithWindow:qz_window]; - [NSGraphicsContext setCurrentContext:nsgfx_context]; + if (nsgfx_context != NULL) { + [NSGraphicsContext setCurrentContext:nsgfx_context]; + } + else { + /* Whoops, looks like Mojave doesn't support this anymore */ + fprintf(stderr,"Unable to obtain graphics context for NSWindow (Mojave behavior)\n"); + } } /* Setup the new pixel format */ { int amask = 0, @@ -1498,23 +1512,32 @@ static void QZ_DrawResizeIcon (_THIS) SDL_BlitSurface (resize_icon, NULL, SDL_VideoSurface, &icon_rect); } } -static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) +static SDL_VideoDevice *last_this = NULL; + +void QZ_UpdateRectsOnDrawRect (/*TODO: NSRect from drawRect*/) { + SDL_VideoDevice *this = last_this; /* HACK */ + + if (this == NULL) return; + if (SDL_VideoSurface == NULL) + return; + if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) { - QZ_GL_SwapBuffers (this); + /* TODO? */ } else if ( [ qz_window isMiniaturized ] ) { /* Do nothing if miniaturized */ } else { NSGraphicsContext *ctx = [NSGraphicsContext currentContext]; + /* NTS: nsgfx_context == NULL will occur on Mojave, may be non-NULL on older versions of OS X */ - if (ctx != nsgfx_context) { /* uhoh, you might be rendering from another thread... */ + if (nsgfx_context != NULL && ctx != nsgfx_context) { /* uhoh, you might be rendering from another thread... */ [NSGraphicsContext setCurrentContext:nsgfx_context]; ctx = nsgfx_context; } CGContextRef cgc = (CGContextRef) [ctx graphicsPort]; QZ_DrawResizeIcon (this); @@ -1526,10 +1549,28 @@ static void QZ_UpdateRects (_THIS, int n CGImageRelease(image); CGContextFlush (cgc); } } +static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) +{ + last_this = this; /* HACK */ + + if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) { + QZ_GL_SwapBuffers (this); + /* TODO? */ + } + else if ( [ qz_window isMiniaturized ] ) { + /* Do nothing if miniaturized */ + } + else { + [ window_view setNeedsDisplay:YES ]; + [ [ qz_window contentView ] setNeedsDisplay:YES ]; + [ qz_window displayIfNeeded ]; + } +} + static void QZ_VideoQuit (_THIS) { CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken; /* Restore gamma settings */ diff --git a/src/video/quartz/SDL_QuartzWindow.h b/src/video/quartz/SDL_QuartzWindow.h --- a/src/video/quartz/SDL_QuartzWindow.h +++ b/src/video/quartz/SDL_QuartzWindow.h @@ -45,7 +45,8 @@ typedef unsigned int NSUInteger; - (BOOL)windowShouldClose:(id)sender; @end /* Subclass of NSView to set cursor rectangle */ @interface SDL_QuartzView : NSView +- (void)drawRect:(NSRect)dirtyRect; - (void)resetCursorRects; @end diff --git a/src/video/quartz/SDL_QuartzWindow.m b/src/video/quartz/SDL_QuartzWindow.m --- a/src/video/quartz/SDL_QuartzWindow.m +++ b/src/video/quartz/SDL_QuartzWindow.m @@ -218,10 +218,17 @@ static void QZ_SetPortAlphaOpaque () { @end @implementation SDL_QuartzView +void QZ_UpdateRectsOnDrawRect(/*TODO: NSRect from drawRect*/); + +- (void)drawRect:(NSRect)dirtyRect +{ + QZ_UpdateRectsOnDrawRect(); +} + - (void)resetCursorRects { SDL_Cursor *sdlc = SDL_GetCursor(); if (sdlc != NULL && sdlc->wm_cursor != NULL) { [self addCursorRect: [self visibleRect] cursor: sdlc->wm_cursor->nscursor];