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>
This commit is contained in:
parent
dfc1e23972
commit
432aaf05da
@ -54,6 +54,8 @@ class QCocoaBackingStore;
|
|||||||
class QCocoaGLContext;
|
class QCocoaGLContext;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
Q_FORWARD_DECLARE_OBJC_CLASS(QNSViewMouseMoveHelper);
|
||||||
|
|
||||||
@interface QNSView : NSView <NSTextInputClient> {
|
@interface QNSView : NSView <NSTextInputClient> {
|
||||||
QCocoaBackingStore* m_backingStore;
|
QCocoaBackingStore* m_backingStore;
|
||||||
QPoint m_backingStoreOffset;
|
QPoint m_backingStoreOffset;
|
||||||
@ -72,6 +74,7 @@ QT_END_NAMESPACE
|
|||||||
QCocoaGLContext *m_glContext;
|
QCocoaGLContext *m_glContext;
|
||||||
bool m_shouldSetGLContextinDrawRect;
|
bool m_shouldSetGLContextinDrawRect;
|
||||||
NSString *m_inputSource;
|
NSString *m_inputSource;
|
||||||
|
QNSViewMouseMoveHelper *m_mouseMoveHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)init;
|
- (id)init;
|
||||||
@ -102,9 +105,10 @@ QT_END_NAMESPACE
|
|||||||
- (void)mouseDown:(NSEvent *)theEvent;
|
- (void)mouseDown:(NSEvent *)theEvent;
|
||||||
- (void)mouseDragged:(NSEvent *)theEvent;
|
- (void)mouseDragged:(NSEvent *)theEvent;
|
||||||
- (void)mouseUp:(NSEvent *)theEvent;
|
- (void)mouseUp:(NSEvent *)theEvent;
|
||||||
- (void)mouseMoved:(NSEvent *)theEvent;
|
- (void)mouseMovedImpl:(NSEvent *)theEvent;
|
||||||
- (void)mouseEntered:(NSEvent *)theEvent;
|
- (void)mouseEnteredImpl:(NSEvent *)theEvent;
|
||||||
- (void)mouseExited:(NSEvent *)theEvent;
|
- (void)mouseExitedImpl:(NSEvent *)theEvent;
|
||||||
|
- (void)cursorUpdateImpl:(NSEvent *)theEvent;
|
||||||
- (void)rightMouseDown:(NSEvent *)theEvent;
|
- (void)rightMouseDown:(NSEvent *)theEvent;
|
||||||
- (void)rightMouseDragged:(NSEvent *)theEvent;
|
- (void)rightMouseDragged:(NSEvent *)theEvent;
|
||||||
- (void)rightMouseUp:(NSEvent *)theEvent;
|
- (void)rightMouseUp:(NSEvent *)theEvent;
|
||||||
|
@ -75,6 +75,53 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
- (CGFloat)deviceDeltaZ;
|
- (CGFloat)deviceDeltaZ;
|
||||||
@end
|
@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
|
@implementation QNSView
|
||||||
|
|
||||||
+ (void)initialize
|
+ (void)initialize
|
||||||
@ -100,6 +147,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
currentCustomDragTypes = 0;
|
currentCustomDragTypes = 0;
|
||||||
m_sendUpAsRightButton = false;
|
m_sendUpAsRightButton = false;
|
||||||
m_inputSource = 0;
|
m_inputSource = 0;
|
||||||
|
m_mouseMoveHelper = [[QNSViewMouseMoveHelper alloc] initWithView:self];
|
||||||
|
|
||||||
if (!touchDevice) {
|
if (!touchDevice) {
|
||||||
touchDevice = new QTouchDevice;
|
touchDevice = new QTouchDevice;
|
||||||
@ -119,6 +167,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
m_subscribesForGlobalFrameNotifications = false;
|
m_subscribesForGlobalFrameNotifications = false;
|
||||||
[m_inputSource release];
|
[m_inputSource release];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
[m_mouseMoveHelper release];
|
||||||
|
|
||||||
delete currentCustomDragTypes;
|
delete currentCustomDragTypes;
|
||||||
|
|
||||||
@ -753,13 +802,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
| NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate;
|
| NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate;
|
||||||
NSTrackingArea *ta = [[[NSTrackingArea alloc] initWithRect:[self frame]
|
NSTrackingArea *ta = [[[NSTrackingArea alloc] initWithRect:[self frame]
|
||||||
options:trackingOptions
|
options:trackingOptions
|
||||||
owner:self
|
owner:m_mouseMoveHelper
|
||||||
userInfo:nil]
|
userInfo:nil]
|
||||||
autorelease];
|
autorelease];
|
||||||
[self addTrackingArea:ta];
|
[self addTrackingArea:ta];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)cursorUpdate:(NSEvent *)theEvent
|
-(void)cursorUpdateImpl:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
Q_UNUSED(theEvent)
|
Q_UNUSED(theEvent)
|
||||||
// Set the cursor manually if there is no NSWindow.
|
// 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];
|
[self addCursorRect:[self visibleRect] cursor:m_platformWindow->m_windowCursor];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseMoved:(NSEvent *)theEvent
|
- (void)mouseMovedImpl:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
if (m_window->flags() & Qt::WindowTransparentForInput)
|
if (m_window->flags() & Qt::WindowTransparentForInput)
|
||||||
return [super mouseMoved:theEvent];
|
return;
|
||||||
|
|
||||||
QPointF windowPoint;
|
QPointF windowPoint;
|
||||||
QPointF screenPoint;
|
QPointF screenPoint;
|
||||||
@ -806,12 +855,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
[self handleMouseEvent: theEvent];
|
[self handleMouseEvent: theEvent];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseEntered:(NSEvent *)theEvent
|
- (void)mouseEnteredImpl:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(theEvent)
|
||||||
m_platformWindow->m_windowUnderMouse = true;
|
m_platformWindow->m_windowUnderMouse = true;
|
||||||
|
|
||||||
if (m_window->flags() & Qt::WindowTransparentForInput)
|
if (m_window->flags() & Qt::WindowTransparentForInput)
|
||||||
return [super mouseEntered:theEvent];
|
return;
|
||||||
|
|
||||||
// Top-level windows generate enter events for sub-windows.
|
// Top-level windows generate enter events for sub-windows.
|
||||||
if (!m_platformWindow->m_nsWindow)
|
if (!m_platformWindow->m_nsWindow)
|
||||||
@ -824,13 +874,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
|
QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseExited:(NSEvent *)theEvent
|
- (void)mouseExitedImpl:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(theEvent);
|
||||||
m_platformWindow->m_windowUnderMouse = false;
|
m_platformWindow->m_windowUnderMouse = false;
|
||||||
|
|
||||||
if (m_window->flags() & Qt::WindowTransparentForInput)
|
if (m_window->flags() & Qt::WindowTransparentForInput)
|
||||||
return [super mouseExited:theEvent];
|
return;
|
||||||
Q_UNUSED(theEvent);
|
|
||||||
|
|
||||||
// Top-level windows generate leave events for sub-windows.
|
// Top-level windows generate leave events for sub-windows.
|
||||||
if (!m_platformWindow->m_nsWindow)
|
if (!m_platformWindow->m_nsWindow)
|
||||||
|
Loading…
Reference in New Issue
Block a user