diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qnsview_mouse.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_mouse.mm | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm index 3d6471005d..49c94f18db 100644 --- a/src/plugins/platforms/cocoa/qnsview_mouse.mm +++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm @@ -39,6 +39,22 @@ // This file is included from qnsview.mm, and only used to organize the code +/* + The reason for using this helper is to ensure that QNSView doesn't implement + the NSResponder callbacks for mouseEntered, mouseExited, and mouseMoved. + + If it did, we would get mouse events though the responder chain as well, + for example if a subview has a tracking area of its own and calls super + in the handler, which results in forwarding the event though the responder + chain. The same applies if NSWindow.acceptsMouseMovedEvents is YES. + + By having a helper as the target for our tracking areas, we know for sure + that the events we are getting stem from our own tracking areas. + + FIXME: Ideally we wouldn't need this workaround, and would correctly + interact with the responder chain by e.g. calling super if Qt does not + accept the mouse event +*/ @implementation QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) { QNSView *view; } @@ -135,6 +151,28 @@ @implementation QT_MANGLE_NAMESPACE(QNSView) (Mouse) +- (void)initMouse +{ + NSUInteger trackingOptions = NSTrackingActiveInActiveApp + | NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate; + + // Ideally, NSTrackingMouseMoved should be turned on only if QWidget::mouseTracking + // is enabled, hover is on, or a tool tip is set. Unfortunately, Qt will send "tooltip" + // events on mouse moves, so we need to turn it on in ALL case. That means EVERY QWindow + // gets to pay the cost of mouse moves delivered to it (Apple recommends keeping it OFF + // because there is a performance hit). + trackingOptions |= NSTrackingMouseMoved; + + // Using NSTrackingInVisibleRect means AppKit will automatically synchronize the + // tracking rect with changes in the view's visible area, so leave it undefined. + trackingOptions |= NSTrackingInVisibleRect; + static const NSRect trackingRect = NSZeroRect; + + QMacAutoReleasePool pool; + [self addTrackingArea:[[[NSTrackingArea alloc] initWithRect:trackingRect + options:trackingOptions owner:m_mouseMoveHelper userInfo:nil] autorelease]]; +} + - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { Q_UNUSED(theEvent) @@ -406,35 +444,9 @@ [super otherMouseUp:theEvent]; } -- (void)updateTrackingAreas -{ - [super updateTrackingAreas]; - - QMacAutoReleasePool pool; - - // NSTrackingInVisibleRect keeps care of updating once the tracking is set up, so bail out early - if (m_trackingArea && [[self trackingAreas] containsObject:m_trackingArea]) - return; - - // Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should - // only be turned on if mouseTracking, hover is on or a tool tip is set. - // Unfortunately, Qt will send "tooltip" events on mouse moves, so we need to - // turn it on in ALL case. That means EVERY QWindow gets to pay the cost of - // mouse moves delivered to it (Apple recommends keeping it OFF because there - // is a performance hit). So it goes. - NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp - | NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate; - [m_trackingArea release]; - m_trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame] - options:trackingOptions - owner:m_mouseMoveHelper - userInfo:nil]; - [self addTrackingArea:m_trackingArea]; -} - - (void)cursorUpdate:(NSEvent *)theEvent { - qCDebug(lcQpaMouse) << "[QNSView cursorUpdate:]" << self.cursor; + qCDebug(lcQpaMouse) << "Updating cursor for" << self << "to" << self.cursor; // Note: We do not get this callback when moving from a subview that // uses the legacy cursorRect API, so the cursor is reset to the arrow |