diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2021-08-31 23:48:45 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-09-03 23:20:13 +0000 |
commit | 37b4c2c2c7da0aa8fe67676e49fb92a34e725e92 (patch) | |
tree | d8a5507a42a4b6be9a07fbf61173f42042c693a4 | |
parent | 93c934acc82ae8f62566387deaadb53a04535717 (diff) |
macOS: Don't rely on invalidateCursorRectsForView when mouse is over view
Calling invalidateCursorRectsForView will normally result in a updateCursor
callback, where we then set the current cursor using [NSCursor set]. But
if an override cursor is set by AppKit, which happens for example when
hovering over a resizable window's theme frame, then AppKit ignores the
call to invalidateCursorRectsForView. And it will not consult the view
when the override cursor is unset again, which results in the cursor
being reset back to the default arrow cursor instead of the cursor
that was set when we initiated the invalidateCursorRectsForView call.
We need to hit-test to confirm that the mouse is over the view,
as there might be child views in the mix that also have custom
cursors, and we don't want to activate the parent view's cursor
unless we're actually over that view.
Fixes: QTBUG-81552
Fixes: QTBUG-96003
Change-Id: I52573ab7be82f28c6a1cf686bd4b133551cfe98b
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit ae8e96d4c2fc430ed6f71e422ef4aff2c7f15186)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 6e7fc5cdbb..dcf65e9fa8 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1727,6 +1727,20 @@ void QCocoaWindow::setWindowCursor(NSCursor *cursor) view.cursor = cursor; [m_view.window invalidateCursorRectsForView:m_view]; + + // There's a bug in AppKit where calling invalidateCursorRectsForView when + // there's an override cursor active (for example when hovering over the + // window frame), will not result in a cursorUpdate: callback. To work around + // this we synthesize a cursor update event and call the callback ourselves, + // if we detect that the mouse is currently over the view. + auto locationInWindow = m_view.window.mouseLocationOutsideOfEventStream; + auto locationInSuperview = [m_view.superview convertPoint:locationInWindow fromView:nil]; + if ([m_view hitTest:locationInSuperview] == m_view) { + [m_view cursorUpdate:[NSEvent enterExitEventWithType:NSEventTypeCursorUpdate + location:locationInWindow modifierFlags:0 timestamp:0 + windowNumber:m_view.window.windowNumber context:nil + eventNumber:0 trackingNumber:0 userData:0]]; + } } void QCocoaWindow::registerTouch(bool enable) |