macOS: Synthesize cursor updates on QCocoaWindow::setWindowCursor
The original issue for doing this was that invalidateCursorRectsForView would not result in an updateCursor callback in certain scenarios on macOS 11 and below. In macOS 13, improvements to how tracking areas work now result in also missing cursorUpdate calls when the mouse is pressed, which makes sense for tracking areas in general (you don't want a drag over a text field to reset the cursor to the I-bream), but not for our specific case of setting a cursor synchronously. To ensure the cursor is updated immediately, even if the mouse is pressed, we synthesize a updateCursor event, just like we did for the invalidateCursorRectsForView workaround. It's up to clients of QWindow to manage their setCursor calls to not happen during a drag operation, which we already manage in Qt Widgets. Pick-to: 6.5 6.2 Change-Id: I67d6e0f8e270b40da9879828455f4de943da7839 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
parent
1f5c4af500
commit
75995d8e58
@ -1788,14 +1788,17 @@ void QCocoaWindow::setWindowCursor(NSCursor *cursor)
|
||||
|
||||
view.cursor = cursor;
|
||||
|
||||
// We're not using the the legacy cursor rects API to manage our
|
||||
// cursor, but calling this function also invalidates AppKit's
|
||||
// view of whether or not we need a cursorUpdate callback for
|
||||
// our tracking area.
|
||||
[m_view.window invalidateCursorRectsForView:m_view];
|
||||
|
||||
if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::MacOSMonterey) {
|
||||
// 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.
|
||||
// We only do this is if the window would normally receive cursor updates.
|
||||
// We've informed AppKit that we need a cursorUpdate, but cursor
|
||||
// updates for tracking areas are deferred in some cases, such as
|
||||
// when the mouse is down, whereas we want a synchronous update.
|
||||
// To ensure an updated cursor we synthesize a cursor update event
|
||||
// now if the window is otherwise allowed to change the cursor.
|
||||
auto locationInWindow = m_view.window.mouseLocationOutsideOfEventStream;
|
||||
auto locationInSuperview = [m_view.superview convertPoint:locationInWindow fromView:nil];
|
||||
bool mouseIsOverView = [m_view hitTest:locationInSuperview] == m_view;
|
||||
@ -1808,7 +1811,6 @@ void QCocoaWindow::setWindowCursor(NSCursor *cursor)
|
||||
windowNumber:m_view.window.windowNumber context:nil
|
||||
eventNumber:0 trackingNumber:0 userData:0]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QCocoaWindow::registerTouch(bool enable)
|
||||
|
Loading…
Reference in New Issue
Block a user