macOS: Don't set cursor for non-key windows

The system behavior when using NSTrackingArea with
NSTrackingCursorUpdate is that cursorUpdate is called whenever
the mouse enters a key window. In response, we use [NSCursor set]
to apply the QWindow's cursor that was set earlier though
QCocoaWindow::setWindowCursor().

As a QWidget can manage a hierarchy of child widgets, each with
their own cursor, we may see multiple calls to setWindowCursor()
when hovering the mouse over a window.

In ae8e96d4c2 we worked around an
AppKit bug where an override cursor would prevent our call to
invalidateCursorRectsForView from resulting in a cursorUpdate
call. But, in doing so, we ignored one of the documented behaviors
of invalidateCursorRectsForView, namely that the cursor is only
updated immediately if the window is currently the key window.

As a result, we would call [NSCursor set] for non-key windows,
which creates an inconsistent behavior. As long as we're not
consistently supporting cursor updates for non-key windows
we should align our workaround behavior with the existing
behavior.

Task-number: QTBUG-96374
Change-Id: I36e4c7802b177230a7e81133cd38557590f041b7
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
bb10
Tor Arne Vestbø 2022-12-12 18:04:50 +01:00
parent 49dbedacf5
commit faffaa7292
1 changed files with 2 additions and 2 deletions

View File

@ -1809,10 +1809,10 @@ void QCocoaWindow::setWindowCursor(NSCursor *cursor)
// 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.
// if we detect that the mouse is currently over the view, and the window key.
auto locationInWindow = m_view.window.mouseLocationOutsideOfEventStream;
auto locationInSuperview = [m_view.superview convertPoint:locationInWindow fromView:nil];
if ([m_view hitTest:locationInSuperview] == m_view) {
if (m_view.window.keyWindow && [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