macOS: Simplify mouse tracking

We don't need to react to updateTrackingAreas, as we only have a
single tracking area that we can add once and forget. By asking
AppKit to track all events in the visible rect, we can also pass
a zero-rect for the tracking area.

Change-Id: I2545712adc49b51904d5adc11f1faca36901b49d
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
bb10
Tor Arne Vestbø 2019-02-04 23:39:42 +01:00
parent 4697467e98
commit 21e25ff38b
2 changed files with 25 additions and 33 deletions

View File

@ -85,6 +85,7 @@
@end
@interface QT_MANGLE_NAMESPACE(QNSView) (Mouse)
- (void)initMouse;
- (NSPoint)screenMousePoint:(NSEvent *)theEvent;
- (void)mouseMovedImpl:(NSEvent *)theEvent;
- (void)mouseEnteredImpl:(NSEvent *)theEvent;
@ -114,7 +115,6 @@
@implementation QT_MANGLE_NAMESPACE(QNSView) {
QPointer<QCocoaWindow> m_platformWindow;
NSTrackingArea *m_trackingArea;
Qt::MouseButtons m_buttons;
Qt::MouseButtons m_acceptedMouseDowns;
Qt::MouseButtons m_frameStrutButtons;
@ -150,7 +150,6 @@
m_currentlyInterpretedKeyEvent = nil;
m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, platformWindow->window(),
"_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB");
m_trackingArea = nil;
self.focusRingType = NSFocusRingTypeNone;
self.cursor = nil;
@ -159,6 +158,7 @@
self.previousWindow = nil;
[self initDrawing];
[self initMouse];
[self registerDragTypes];
[[NSNotificationCenter defaultCenter] addObserver:self
@ -173,10 +173,6 @@
{
qCDebug(lcQpaWindow) << "Deallocating" << self;
if (m_trackingArea) {
[self removeTrackingArea:m_trackingArea];
[m_trackingArea release];
}
[m_inputSource release];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[m_mouseMoveHelper release];

View File

@ -151,6 +151,28 @@
@implementation QT_MANGLE_NAMESPACE(QNSView) (Mouse)
- (void)initMouse
{
NSUInteger trackingOptions = NSTrackingActiveInActiveApp
| NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate;
// Ideally, NSTrackingMouseMoved should be turned on only if QWidget::mouseTracking
// is enabled, 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 QWindow
// gets to pay the cost of mouse moves delivered to it (Apple recommends keeping it OFF
// because there is a performance hit).
trackingOptions |= NSTrackingMouseMoved;
// Using NSTrackingInVisibleRect means AppKit will automatically synchronize the
// tracking rect with changes in the view's visible area, so leave it undefined.
trackingOptions |= NSTrackingInVisibleRect;
static const NSRect trackingRect = NSZeroRect;
QMacAutoReleasePool pool;
[self addTrackingArea:[[[NSTrackingArea alloc] initWithRect:trackingRect
options:trackingOptions owner:m_mouseMoveHelper userInfo:nil] autorelease]];
}
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
Q_UNUSED(theEvent)
@ -422,35 +444,9 @@
[super otherMouseUp:theEvent];
}
- (void)updateTrackingAreas
{
[super updateTrackingAreas];
QMacAutoReleasePool pool;
// NSTrackingInVisibleRect keeps care of updating once the tracking is set up, so bail out early
if (m_trackingArea && [[self trackingAreas] containsObject:m_trackingArea])
return;
// 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 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
| NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate;
[m_trackingArea release];
m_trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame]
options:trackingOptions
owner:m_mouseMoveHelper
userInfo:nil];
[self addTrackingArea:m_trackingArea];
}
- (void)cursorUpdate:(NSEvent *)theEvent
{
qCDebug(lcQpaMouse) << "[QNSView cursorUpdate:]" << self.cursor;
qCDebug(lcQpaMouse) << "Updating cursor for" << self << "to" << self.cursor;
// Note: We do not get this callback when moving from a subview that
// uses the legacy cursorRect API, so the cursor is reset to the arrow