src/video/cocoa/SDL_cocoamouse.m
changeset 8261 841b66e4397a
parent 8260 028ed8da2524
child 8262 acc0dcf38b3d
     1.1 --- a/src/video/cocoa/SDL_cocoamouse.m	Tue Feb 25 17:27:41 2014 -0800
     1.2 +++ b/src/video/cocoa/SDL_cocoamouse.m	Wed Feb 26 11:35:02 2014 -0800
     1.3 @@ -223,16 +223,7 @@
     1.4      SDL_Mouse *mouse = SDL_GetMouse();
     1.5      CGPoint point = CGPointMake(x + (float)window->x, y + (float)window->y);
     1.6  
     1.7 -    {
     1.8 -        /* This makes Cocoa_HandleMouseEvent ignore this delta in the next
     1.9 -         * movement event.
    1.10 -         */
    1.11 -        SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata;
    1.12 -        NSPoint location =  [NSEvent mouseLocation];
    1.13 -        driverdata->deltaXOffset = location.x - point.x;
    1.14 -        driverdata->deltaYOffset = point.y - location.y;
    1.15 -        DLog("Warp to (%g, %g), offsetting next movement event by (%i, %i)", point.x, point.y, driverdata->deltaXOffset, driverdata->deltaYOffset);
    1.16 -    }
    1.17 +    Cocoa_HandleMouseWarp(point.x, point.y);
    1.18  
    1.19      /* According to the docs, this was deprecated in 10.6, but it's still
    1.20       * around. The substitute requires a CGEventSource, but I'm not entirely
    1.21 @@ -285,18 +276,16 @@
    1.22      SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
    1.23  
    1.24      Cocoa_InitMouseEventTap(mouse->driverdata);
    1.25 +
    1.26 +    SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata;
    1.27 +    const NSPoint location =  [NSEvent mouseLocation];
    1.28 +    driverdata->lastMoveX = location.x;
    1.29 +    driverdata->lastMoveY = location.y;
    1.30  }
    1.31  
    1.32  void
    1.33  Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
    1.34  {
    1.35 -    SDL_Mouse *mouse = SDL_GetMouse();
    1.36 -
    1.37 -    /* Non-relative movement is handled in -[Cocoa_WindowListener mouseMoved:] */
    1.38 -    if (!mouse->relative_mode) {
    1.39 -        return;
    1.40 -    }
    1.41 -
    1.42      switch ([event type])
    1.43      {
    1.44          case NSMouseMoved:
    1.45 @@ -310,6 +299,24 @@
    1.46              return;
    1.47      }
    1.48  
    1.49 +    SDL_Mouse *mouse = SDL_GetMouse();
    1.50 +
    1.51 +    SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata;
    1.52 +    const SDL_bool seenWarp = driverdata->seenWarp;
    1.53 +    driverdata->seenWarp = NO;
    1.54 +
    1.55 +    const NSPoint location =  [NSEvent mouseLocation];
    1.56 +    const CGFloat lastMoveX = driverdata->lastMoveX;
    1.57 +    const CGFloat lastMoveY = driverdata->lastMoveY;
    1.58 +    driverdata->lastMoveX = location.x;
    1.59 +    driverdata->lastMoveY = location.y;
    1.60 +    DLog("Last seen mouse: (%g, %g)", location.x, location.y);
    1.61 +
    1.62 +    /* Non-relative movement is handled in -[Cocoa_WindowListener mouseMoved:] */
    1.63 +    if (!mouse->relative_mode) {
    1.64 +        return;
    1.65 +    }
    1.66 +
    1.67      /* Ignore events that aren't inside the client area (i.e. title bar.) */
    1.68      if ([event window]) {
    1.69          NSRect windowRect = [[[event window] contentView] frame];
    1.70 @@ -318,16 +325,18 @@
    1.71          }
    1.72      }
    1.73  
    1.74 -    SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata;
    1.75 -    float x = [event deltaX] + driverdata->deltaXOffset;
    1.76 -    float y = [event deltaY] + driverdata->deltaYOffset;
    1.77 -    driverdata->deltaXOffset = driverdata->deltaYOffset = 0;
    1.78 +    float deltaX = [event deltaX];
    1.79 +    float deltaY = [event deltaY];
    1.80  
    1.81 -    if (driverdata->deltaYOffset > 0 || driverdata->deltaXOffset > 0) {
    1.82 -        DLog("Relative move was (%g, %g), offset to (%g, %g)", [event deltaX], [event deltaY], x, y);
    1.83 +    if (seenWarp)
    1.84 +    {
    1.85 +        deltaX += (lastMoveX - driverdata->lastWarpX);
    1.86 +        deltaY += ((CGDisplayPixelsHigh(kCGDirectMainDisplay) - lastMoveY) - driverdata->lastWarpY);
    1.87 +
    1.88 +        DLog("Motion was (%g, %g), offset to (%g, %g)", [event deltaX], [event deltaY], deltaX, deltaY);
    1.89      }
    1.90  
    1.91 -    SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, (int)x, (int)y);
    1.92 +    SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, (int)deltaX, (int)deltaY);
    1.93  }
    1.94  
    1.95  void
    1.96 @@ -352,6 +361,20 @@
    1.97  }
    1.98  
    1.99  void
   1.100 +Cocoa_HandleMouseWarp(CGFloat x, CGFloat y)
   1.101 +{
   1.102 +    /* This makes Cocoa_HandleMouseEvent ignore the delta caused by the warp,
   1.103 +     * since it gets included in the next movement event.
   1.104 +     */
   1.105 +    SDL_MouseData *driverdata = (SDL_MouseData*)SDL_GetMouse()->driverdata;
   1.106 +    driverdata->lastWarpX = x;
   1.107 +    driverdata->lastWarpY = y;
   1.108 +    driverdata->seenWarp = SDL_TRUE;
   1.109 +
   1.110 +    DLog("(%g, %g)", x, y);
   1.111 +}
   1.112 +
   1.113 +void
   1.114  Cocoa_QuitMouse(_THIS)
   1.115  {
   1.116      SDL_Mouse *mouse = SDL_GetMouse();