diff options
author | Morten Johan Sørvig <morten.sorvig@theqtcompany.com> | 2015-11-11 22:19:16 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@theqtcompany.com> | 2016-03-21 16:26:31 +0000 |
commit | 0694751c3323beebca167100c203f533755622c2 (patch) | |
tree | 12827bbfc4054d01fe44199ef9cecc970608a4be /src/plugins/platforms | |
parent | 68987d5454a347807c227ba3e2e2db3e050911df (diff) |
Cocoa: Forward masked out mouse events.
Forward mouse events hitting the a masked out window
area to the next responder by calling the superclass
event handler.
Implement "inverse mouse grabbing": Qt will not take
dragged and up events if the mouseDown was in a masked
out area.
Change-Id: Ie86281245513cad515b77a468ac63f31ae41bfe0
Task-number: QTBUG-41839
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@theqtcompany.com>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 31 |
2 files changed, 29 insertions, 4 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index e5f136d0cd..b5738abf4c 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -60,6 +60,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); @interface QT_MANGLE_NAMESPACE(QNSView) : NSView <NSTextInputClient> { QCocoaBackingStore* m_backingStore; QPoint m_backingStoreOffset; + QRegion m_maskRegion; CGImageRef m_maskImage; uchar *m_maskData; bool m_shouldInvalidateWindowShadow; @@ -67,6 +68,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); QCocoaWindow *m_platformWindow; NSTrackingArea *m_trackingArea; Qt::MouseButtons m_buttons; + Qt::MouseButtons m_acceptedMouseDowns; Qt::MouseButtons m_frameStrutButtons; QString m_composingText; bool m_sendKeyEvent; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index fb83f3211a..9905c85d77 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -145,6 +145,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; m_shouldInvalidateWindowShadow = false; m_window = 0; m_buttons = Qt::NoButton; + m_acceptedMouseDowns = Qt::NoButton; m_frameStrutButtons = Qt::NoButton; m_sendKeyEvent = false; m_subscribesForGlobalFrameNotifications = false; @@ -529,7 +530,7 @@ QT_WARNING_POP - (BOOL) hasMask { - return m_maskImage != 0; + return !m_maskRegion.isEmpty(); } - (BOOL) isOpaque @@ -542,6 +543,7 @@ QT_WARNING_POP - (void) setMaskRegion:(const QRegion *)region { m_shouldInvalidateWindowShadow = true; + m_maskRegion = *region; if (m_maskImage) CGImageRelease(m_maskImage); if (region->isEmpty()) { @@ -825,6 +827,22 @@ QT_WARNING_POP Qt::MouseButton button = cocoaButton2QtButton([theEvent buttonNumber]); + QPointF qtWindowPoint; + QPointF qtScreenPoint; + [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; + Q_UNUSED(qtScreenPoint); + + // Maintain masked state for the button for use by MouseDragged and MouseUp. + const bool masked = m_maskRegion.contains(qtWindowPoint.toPoint()); + if (masked) + m_acceptedMouseDowns &= ~button; + else + m_acceptedMouseDowns |= button; + + // Forward masked out events to the next responder + if (masked) + return false; + if (button == Qt::RightButton) m_sendUpAsRightButton = true; @@ -843,7 +861,7 @@ QT_WARNING_POP // Forward the event to the next responder if Qt did not accept the // corresponding mouse down for this button - if (!m_acceptedMouseDowns.contains(button)) + if (!(m_acceptedMouseDowns & button) == button) return false; if (!(m_buttons & (m_sendUpAsRightButton ? Qt::RightButton : Qt::LeftButton))) { @@ -862,6 +880,11 @@ QT_WARNING_POP Qt::MouseButton button = cocoaButton2QtButton([theEvent buttonNumber]); + // Forward the event to the next responder if Qt did not accept the + // corresponding mouse down for this button + if (!(m_acceptedMouseDowns & button) == button) + return false; + if (m_sendUpAsRightButton && button == Qt::LeftButton) button = Qt::RightButton; if (button == Qt::RightButton) @@ -920,9 +943,9 @@ QT_WARNING_POP // Maintain masked state for the button for use by MouseDragged and Up. if (masked) - m_acceptedMouseDowns.remove(Qt::LeftButton); + m_acceptedMouseDowns &= ~Qt::LeftButton; else - m_acceptedMouseDowns.insert(Qt::LeftButton); + m_acceptedMouseDowns |= Qt::LeftButton; // Forward masked out events to the next responder if (masked) { |