src/video/cocoa/SDL_cocoawindow.m
changeset 8260 028ed8da2524
parent 8258 569354dec4e9
child 8261 841b66e4397a
     1.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Tue Feb 25 17:25:49 2014 -0800
     1.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Tue Feb 25 17:27:41 2014 -0800
     1.3 @@ -39,6 +39,44 @@
     1.4  #include "SDL_cocoamouse.h"
     1.5  #include "SDL_cocoaopengl.h"
     1.6  
     1.7 +@interface SDLWindow : NSWindow
     1.8 +/* These are needed for borderless/fullscreen windows */
     1.9 +- (BOOL)canBecomeKeyWindow;
    1.10 +- (BOOL)canBecomeMainWindow;
    1.11 +- (void)sendEvent:(NSEvent *)event;
    1.12 +@end
    1.13 +
    1.14 +@implementation SDLWindow
    1.15 +- (BOOL)canBecomeKeyWindow
    1.16 +{
    1.17 +    return YES;
    1.18 +}
    1.19 +
    1.20 +- (BOOL)canBecomeMainWindow
    1.21 +{
    1.22 +    return YES;
    1.23 +}
    1.24 +
    1.25 +- (void)sendEvent:(NSEvent *)event
    1.26 +{
    1.27 +  [super sendEvent:event];
    1.28 +
    1.29 +  if ([event type] != NSLeftMouseUp) {
    1.30 +      return;
    1.31 +  }
    1.32 +
    1.33 +  id delegate = [self delegate];
    1.34 +  if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) {
    1.35 +      return;
    1.36 +  }
    1.37 +
    1.38 +  if ([delegate isMoving]) {
    1.39 +      [delegate windowDidFinishMoving];
    1.40 +  }
    1.41 +}
    1.42 +@end
    1.43 +
    1.44 +
    1.45  static Uint32 s_moveHack;
    1.46  
    1.47  static void ConvertNSRect(NSRect *r)
    1.48 @@ -130,6 +168,7 @@
    1.49      isFullscreenSpace = NO;
    1.50      inFullscreenTransition = NO;
    1.51      pendingWindowOperation = PENDING_OPERATION_NONE;
    1.52 +    isMoving = NO;
    1.53  
    1.54      center = [NSNotificationCenter defaultCenter];
    1.55  
    1.56 @@ -315,6 +354,34 @@
    1.57      }
    1.58  }
    1.59  
    1.60 +- (BOOL)isMoving
    1.61 +{
    1.62 +    return isMoving;
    1.63 +}
    1.64 +
    1.65 +-(void) setPendingMoveX:(int)x Y:(int)y
    1.66 +{
    1.67 +    pendingWindowWarpX = x;
    1.68 +    pendingWindowWarpY = y;
    1.69 +}
    1.70 +
    1.71 +- (void)windowDidFinishMoving
    1.72 +{
    1.73 +    if ([self isMoving])
    1.74 +    {
    1.75 +        isMoving = NO;
    1.76 +
    1.77 +        SDL_Mouse *mouse = SDL_GetMouse();
    1.78 +        if (pendingWindowWarpX >= 0 && pendingWindowWarpY >= 0) {
    1.79 +            mouse->WarpMouse(_data->window, pendingWindowWarpX, pendingWindowWarpY);
    1.80 +            pendingWindowWarpX = pendingWindowWarpY = -1;
    1.81 +        }
    1.82 +        if (mouse->relative_mode && SDL_GetMouseFocus() == _data->window) {
    1.83 +            mouse->SetRelativeMouseMode(SDL_TRUE);
    1.84 +        }
    1.85 +    }
    1.86 +}
    1.87 +
    1.88  - (BOOL)windowShouldClose:(id)sender
    1.89  {
    1.90      SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
    1.91 @@ -326,6 +393,14 @@
    1.92      SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
    1.93  }
    1.94  
    1.95 +- (void)windowWillMove:(NSNotification *)aNotification
    1.96 +{
    1.97 +    if ([_data->nswindow isKindOfClass:[SDLWindow class]]) {
    1.98 +        pendingWindowWarpX = pendingWindowWarpY = -1;
    1.99 +        isMoving = YES;
   1.100 +    }
   1.101 +}
   1.102 +
   1.103  - (void)windowDidMove:(NSNotification *)aNotification
   1.104  {
   1.105      int x, y;
   1.106 @@ -407,6 +482,9 @@
   1.107  {
   1.108      SDL_Window *window = _data->window;
   1.109      SDL_Mouse *mouse = SDL_GetMouse();
   1.110 +    if (mouse->relative_mode && ![self isMoving]) {
   1.111 +        mouse->SetRelativeMouseMode(SDL_TRUE);
   1.112 +    }
   1.113  
   1.114      /* We're going to get keyboard events, since we're key. */
   1.115      SDL_SetKeyboardFocus(window);
   1.116 @@ -431,6 +509,11 @@
   1.117  
   1.118  - (void)windowDidResignKey:(NSNotification *)aNotification
   1.119  {
   1.120 +    SDL_Mouse *mouse = SDL_GetMouse();
   1.121 +    if (mouse->relative_mode) {
   1.122 +        mouse->SetRelativeMouseMode(SDL_FALSE);
   1.123 +    }
   1.124 +
   1.125      /* Some other window will get mouse events, since we're not key. */
   1.126      if (SDL_GetMouseFocus() == _data->window) {
   1.127          SDL_SetMouseFocus(NULL);
   1.128 @@ -624,8 +707,6 @@
   1.129  
   1.130      if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
   1.131          if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
   1.132 -            CGPoint cgpoint;
   1.133 -
   1.134              if (x < 0) {
   1.135                  x = 0;
   1.136              } else if (x >= window->w) {
   1.137 @@ -638,6 +719,8 @@
   1.138              }
   1.139  
   1.140  #if !SDL_MAC_NO_SANDBOX
   1.141 +            CGPoint cgpoint;
   1.142 +
   1.143              /* When SDL_MAC_NO_SANDBOX is set, this is handled by
   1.144               * SDL_cocoamousetap.m.
   1.145               */
   1.146 @@ -754,24 +837,6 @@
   1.147  
   1.148  @end
   1.149  
   1.150 -@interface SDLWindow : NSWindow
   1.151 -/* These are needed for borderless/fullscreen windows */
   1.152 -- (BOOL)canBecomeKeyWindow;
   1.153 -- (BOOL)canBecomeMainWindow;
   1.154 -@end
   1.155 -
   1.156 -@implementation SDLWindow
   1.157 -- (BOOL)canBecomeKeyWindow
   1.158 -{
   1.159 -    return YES;
   1.160 -}
   1.161 -
   1.162 -- (BOOL)canBecomeMainWindow
   1.163 -{
   1.164 -    return YES;
   1.165 -}
   1.166 -@end
   1.167 -
   1.168  @interface SDLView : NSView
   1.169  
   1.170  /* The default implementation doesn't pass rightMouseDown to responder chain */
   1.171 @@ -1338,7 +1403,8 @@
   1.172  Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
   1.173  {
   1.174      /* Move the cursor to the nearest point in the window */
   1.175 -    if (grabbed) {
   1.176 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   1.177 +    if (grabbed && data && ![data->listener isMoving]) {
   1.178          int x, y;
   1.179          CGPoint cgpoint;
   1.180