summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qnsview.mm
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@digia.com>2014-05-19 14:32:31 +0200
committerEike Ziller <eike.ziller@digia.com>2014-06-24 09:35:56 +0200
commit432aaf05dabec82214ae018338aac827a8b326f8 (patch)
tree58c13856442c3a87b7021410c5d9be5d5d906a1a /src/plugins/platforms/cocoa/qnsview.mm
parentdfc1e23972136e8d86c45d43f3bf9048aa02c59a (diff)
Cocoa: Do mouse move and cursor update handling separate from view
We are using tracking areas for mouse move, enter/leave and cursor update events, so we should keep handling of that out of the "normal" event chain. If we handle mouse moved events in the views' mouseMoved method, we need to pass the event up the responder chain if we didn't handle it, or we would break for example hover behavior in native WebViews, because these do not handle mouse moved events directly in their mouseMoved:, but only if the event wasn't handled otherwise (arguably a bug in Web(HTML)View). But passing the event up the responder chain is not good either, because the QNSViews in the parent hierarchy get the event from their tracking areas already. Change-Id: I636a84ab1b7ef73070f81a8e33b5fa734ff4a42c Task-number: QTBUG-26593 Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com> Reviewed-by: Eike Ziller <eike.ziller@digia.com>
Diffstat (limited to 'src/plugins/platforms/cocoa/qnsview.mm')
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm68
1 files changed, 59 insertions, 9 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index a2047bf550..4a744245f0 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -75,6 +75,53 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
- (CGFloat)deviceDeltaZ;
@end
+@interface QNSViewMouseMoveHelper : NSObject
+{
+ QNSView *view;
+}
+
+- (id)initWithView:(QNSView *)theView;
+
+- (void)mouseMoved:(NSEvent *)theEvent;
+- (void)mouseEntered:(NSEvent *)theEvent;
+- (void)mouseExited:(NSEvent *)theEvent;
+- (void)cursorUpdate:(NSEvent *)theEvent;
+
+@end
+
+@implementation QNSViewMouseMoveHelper
+
+- (id)initWithView:(QNSView *)theView
+{
+ self = [super init];
+ if (self) {
+ view = theView;
+ }
+ return self;
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ [view mouseMovedImpl:theEvent];
+}
+
+- (void)mouseEntered:(NSEvent *)theEvent
+{
+ [view mouseEnteredImpl:theEvent];
+}
+
+- (void)mouseExited:(NSEvent *)theEvent
+{
+ [view mouseExitedImpl:theEvent];
+}
+
+- (void)cursorUpdate:(NSEvent *)theEvent
+{
+ [view cursorUpdateImpl:theEvent];
+}
+
+@end
+
@implementation QNSView
+ (void)initialize
@@ -100,6 +147,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
currentCustomDragTypes = 0;
m_sendUpAsRightButton = false;
m_inputSource = 0;
+ m_mouseMoveHelper = [[QNSViewMouseMoveHelper alloc] initWithView:self];
if (!touchDevice) {
touchDevice = new QTouchDevice;
@@ -119,6 +167,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
m_subscribesForGlobalFrameNotifications = false;
[m_inputSource release];
[[NSNotificationCenter defaultCenter] removeObserver:self];
+ [m_mouseMoveHelper release];
delete currentCustomDragTypes;
@@ -753,13 +802,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
| NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate;
NSTrackingArea *ta = [[[NSTrackingArea alloc] initWithRect:[self frame]
options:trackingOptions
- owner:self
+ owner:m_mouseMoveHelper
userInfo:nil]
autorelease];
[self addTrackingArea:ta];
}
--(void)cursorUpdate:(NSEvent *)theEvent
+-(void)cursorUpdateImpl:(NSEvent *)theEvent
{
Q_UNUSED(theEvent)
// Set the cursor manually if there is no NSWindow.
@@ -776,10 +825,10 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
[self addCursorRect:[self visibleRect] cursor:m_platformWindow->m_windowCursor];
}
-- (void)mouseMoved:(NSEvent *)theEvent
+- (void)mouseMovedImpl:(NSEvent *)theEvent
{
if (m_window->flags() & Qt::WindowTransparentForInput)
- return [super mouseMoved:theEvent];
+ return;
QPointF windowPoint;
QPointF screenPoint;
@@ -806,12 +855,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
[self handleMouseEvent: theEvent];
}
-- (void)mouseEntered:(NSEvent *)theEvent
+- (void)mouseEnteredImpl:(NSEvent *)theEvent
{
+ Q_UNUSED(theEvent)
m_platformWindow->m_windowUnderMouse = true;
if (m_window->flags() & Qt::WindowTransparentForInput)
- return [super mouseEntered:theEvent];
+ return;
// Top-level windows generate enter events for sub-windows.
if (!m_platformWindow->m_nsWindow)
@@ -824,13 +874,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
}
-- (void)mouseExited:(NSEvent *)theEvent
+- (void)mouseExitedImpl:(NSEvent *)theEvent
{
+ Q_UNUSED(theEvent);
m_platformWindow->m_windowUnderMouse = false;
if (m_window->flags() & Qt::WindowTransparentForInput)
- return [super mouseExited:theEvent];
- Q_UNUSED(theEvent);
+ return;
// Top-level windows generate leave events for sub-windows.
if (!m_platformWindow->m_nsWindow)