diff options
author | Morten Johan Sørvig <morten.sorvig@digia.com> | 2013-02-27 10:27:20 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-03-26 19:21:38 +0100 |
commit | b2c73c73cd0a68aae0586cf447c2612c13aeb52c (patch) | |
tree | 35c387cf8f14240e4cc3c5f10fa0acacfe27cdc7 /src/plugins/platforms/cocoa/qnsview.mm | |
parent | a2fc37044ce3e7a51317a6528d121df632df5d68 (diff) |
Cocoa: Correct enter/leave event handling.
Make top-level windows generate enter/leave events
for sub-windows. Keep track of the current "under mouse"
window in mouseMoved and send EnterLeave events when
it changes.
mouseEntered/mouseExited handles enters and leaves
from the top-level window.
Add tests/manual/cocoa/nativewidgets.
Task-number: QTBUG-27550
Task-number: QTBUG-29751
Change-Id: If4b9f9e0f39d9fb05fdab45a100ffdcf107965ad
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
Diffstat (limited to 'src/plugins/platforms/cocoa/qnsview.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 12a6bb9e69..3046b898df 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -599,6 +599,7 @@ static QTouchDevice *touchDevice = 0; if (NSIsEmptyRect([self visibleRect])) return; + // Remove current trakcing areas: QCocoaAutoReleasePool pool; if (NSArray *trackingArray = [self trackingAreas]) { NSUInteger size = [trackingArray count]; @@ -611,7 +612,7 @@ static QTouchDevice *touchDevice = 0; // 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 QCocoaView gets to pay the cost of + // 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 @@ -628,23 +629,58 @@ static QTouchDevice *touchDevice = 0; { if (m_window->flags() & Qt::WindowTransparentForInput) return [super mouseMoved:theEvent]; - [self handleMouseEvent:theEvent]; + + QPoint windowPoint, screenPoint; + [self convertFromEvent:theEvent toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindow *childWindow = m_platformWindow->childWindowAt(windowPoint); + + // Top-level windows generate enter-leave events for sub-windows. + // Qt wants to know which window (if any) will be entered at the + // the time of the leave. This is dificult to accomplish by + // handling mouseEnter and mouseLeave envents, since they are sent + // individually to different views. + if (m_platformWindow->m_nsWindow && childWindow) { + if (childWindow != m_platformWindow->m_underMouseWindow) { + QWindowSystemInterface::handleEnterLeaveEvent(childWindow, m_platformWindow->m_underMouseWindow, windowPoint, screenPoint); + m_platformWindow->m_underMouseWindow = childWindow; + } + } + + // Cocoa keeps firing mouse move events for obscured parent views. Qt should not + // send those events so filter them out here. + if (childWindow != m_window) + return; + + [self handleMouseEvent: theEvent]; } - (void)mouseEntered:(NSEvent *)theEvent { if (m_window->flags() & Qt::WindowTransparentForInput) return [super mouseEntered:theEvent]; + + // Top-level windows generate enter events for sub-windows. + if (!m_platformWindow->m_nsWindow) + return; + QPoint windowPoint, screenPoint; [self convertFromEvent:theEvent toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; - QWindowSystemInterface::handleEnterEvent(m_window, windowPoint, screenPoint); + m_platformWindow->m_underMouseWindow = m_platformWindow->childWindowAt(windowPoint); + QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_underMouseWindow, windowPoint, screenPoint); } - (void)mouseExited:(NSEvent *)theEvent { if (m_window->flags() & Qt::WindowTransparentForInput) return [super mouseExited:theEvent]; - QWindowSystemInterface::handleLeaveEvent(m_window); + Q_UNUSED(theEvent); + + // Top-level windows generate leave events for sub-windows. + if (!m_platformWindow->m_nsWindow) + return; + + QWindowSystemInterface::handleLeaveEvent(m_platformWindow->m_underMouseWindow); + m_platformWindow->m_underMouseWindow = 0; } - (void)rightMouseDown:(NSEvent *)theEvent |