NSView capture mouse movement after exceeding bounds

543 views Asked by At

I know the title isn't well chosen, but I didn't know how to describe it better...

I have an instance of NSView that I add to a window at the right screen edge:

CGRect zoneFrame = CGRectMake(screenFrame.size.width - 50, 0, 50, screenFrame.size.height);

When the user gets to the screens edge I want to capture the mouse. I then use this method to send the location to a custom delegate protocol:

- (void)mouseMoved:(NSEvent *)mouseEvent {
    [_delegate mouseMovedTo:[mouseEvent locationInWindow]];
}

I now want to continue capturing the real mouses movement, when the user continues dragging it to the right side. But, as expected, the NSView does not receive movement actions, when the pointer exceeded the views bound, resp. the edge of the screen.

I want to create something you can think of an imaginary view that is placed right beside the screen.

Is there a possibility to continuing the mouse capture? And then let the mouse move outside the view only after it is moved all the way back to the left edge of the "imaginary" view?

1

There are 1 answers

1
cocoafan On

if you want to track the mouse while mouse is down you must track the events manually. Here is a template code to do that.

- (void)trackMouseWithEvent:(NSEvent *)theEvent {
  NSPoint curPoint = [self convertPoint: [theEvent locationInWindow] fromView: nil];
  while (1) {
    NSEvent *theEvent = [[self window] nextEventMatchingMask: (NSLeftMouseDraggedMask | NSLeftMouseUpMask)];
    NSPoint newPoint = [self convertPoint: [theEvent locationInWindow] fromView: nil];
    // Drag distance is curPoint - newPoint
    if ([theEvent type] == NSLeftMouseUp)
      break;
  }
}

If you want the framework to send mouse move events when the it is not even dragged then you must explicitly setup your view for receiving mouse move events. Since dispatching every mouse move is an expensive action you will get only mouse enter and mouse out events if you not ask explicitly for mouse move events to receive.