src/video/cocoa/SDL_cocoametalview.m
changeset 13113 eab802de5fbb
parent 13029 3e281c2da43a
child 13422 fd6a12de91c7
     1.1 --- a/src/video/cocoa/SDL_cocoametalview.m	Sun Oct 13 12:16:40 2019 -0300
     1.2 +++ b/src/video/cocoa/SDL_cocoametalview.m	Sun Oct 13 15:18:28 2019 -0300
     1.3 @@ -30,6 +30,28 @@
     1.4  #if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL)
     1.5  
     1.6  #include "SDL_assert.h"
     1.7 +#include "SDL_events.h"
     1.8 +
     1.9 +static int SDLCALL
    1.10 +SDL_MetalViewEventWatch(void *userdata, SDL_Event *event)
    1.11 +{
    1.12 +    /* Update the drawable size when SDL receives a size changed event for
    1.13 +     * the window that contains the metal view. It would be nice to use
    1.14 +     * - (void)resizeWithOldSuperviewSize:(NSSize)oldSize and
    1.15 +     * - (void)viewDidChangeBackingProperties instead, but SDL's size change
    1.16 +     * events don't always happen in the same frame (for example when a
    1.17 +     * resizable window exits a fullscreen Space via the user pressing the OS
    1.18 +     * exit-space button). */
    1.19 +    if (event->type == SDL_WINDOWEVENT && event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
    1.20 +        @autoreleasepool {
    1.21 +            SDL_cocoametalview *view = (__bridge SDL_cocoametalview *)userdata;
    1.22 +            if (view.sdlWindowID == event->window.windowID) {
    1.23 +                [view updateDrawableSize];
    1.24 +            }
    1.25 +        }
    1.26 +    }
    1.27 +    return 0;
    1.28 +}
    1.29  
    1.30  @implementation SDL_cocoametalview
    1.31  
    1.32 @@ -55,20 +77,30 @@
    1.33  
    1.34  - (instancetype)initWithFrame:(NSRect)frame
    1.35                        highDPI:(BOOL)highDPI
    1.36 +                     windowID:(Uint32)windowID;
    1.37  {
    1.38      if ((self = [super initWithFrame:frame])) {
    1.39          self.highDPI = highDPI;
    1.40 +        self.sdlWindowID = windowID;
    1.41          self.wantsLayer = YES;
    1.42  
    1.43          /* Allow resize. */
    1.44          self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
    1.45  
    1.46 +        SDL_AddEventWatch(SDL_MetalViewEventWatch, self);
    1.47 +
    1.48          [self updateDrawableSize];
    1.49      }
    1.50    
    1.51      return self;
    1.52  }
    1.53  
    1.54 +- (void)dealloc
    1.55 +{
    1.56 +    SDL_DelEventWatch(SDL_MetalViewEventWatch, self);
    1.57 +    [super dealloc];
    1.58 +}
    1.59 +
    1.60  - (NSInteger)tag
    1.61  {
    1.62      return METALVIEW_TAG;
    1.63 @@ -91,13 +123,6 @@
    1.64      metalLayer.drawableSize = NSSizeToCGSize(backingSize);
    1.65  }
    1.66  
    1.67 -/* Set the size of the metal drawables when the view is resized. */
    1.68 -- (void)resizeWithOldSuperviewSize:(NSSize)oldSize
    1.69 -{
    1.70 -    [super resizeWithOldSuperviewSize:oldSize];
    1.71 -    [self updateDrawableSize];
    1.72 -}
    1.73 -
    1.74  @end
    1.75  
    1.76  SDL_MetalView
    1.77 @@ -106,10 +131,13 @@
    1.78      SDL_WindowData* data = (__bridge SDL_WindowData *)window->driverdata;
    1.79      NSView *view = data->nswindow.contentView;
    1.80      BOOL highDPI = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
    1.81 +    Uint32 windowID = SDL_GetWindowID(window);
    1.82      SDL_cocoametalview *newview;
    1.83      SDL_MetalView metalview;
    1.84  
    1.85 -    newview = [[SDL_cocoametalview alloc] initWithFrame:view.frame highDPI:highDPI];
    1.86 +    newview = [[SDL_cocoametalview alloc] initWithFrame:view.frame
    1.87 +                                                highDPI:highDPI
    1.88 +                                                windowID:windowID];
    1.89      if (newview == nil) {
    1.90          return NULL;
    1.91      }