diff --git a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift index 8407c3f5b..fd9b5810b 100644 --- a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift @@ -781,7 +781,7 @@ class MachineDocument: optionsFader.animateIn() } - internal func scanTargetViewWillHideOSMouseCursor(_ view: CSScanTargetView) { + internal func scanTargetViewWouldHideOSMouseCursor(_ view: CSScanTargetView) { // The OS mouse cursor will be hidden, so hide the volume controls. optionsFader.animateOut(delay: 0.0) } diff --git a/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.h b/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.h index 330e24b99..5373e2be2 100644 --- a/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.h +++ b/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.h @@ -80,10 +80,12 @@ - (void)scanTargetViewDidShowOSMouseCursor:(nonnull CSScanTargetView *)view; /*! - Announces that the OS mouse cursor will now be hidden. + Announces that the OS mouse cursor would now be hidden; 'would' means that if this is not + a mouse capture-enabled view then it will be hidden, but otherwise it might or might not be + as per whatever is user-friendly. @param view The view making the announcement. */ -- (void)scanTargetViewWillHideOSMouseCursor:(nonnull CSScanTargetView *)view; +- (void)scanTargetViewWouldHideOSMouseCursor:(nonnull CSScanTargetView *)view; /*! Announces receipt of a file by drag and drop to the delegate. diff --git a/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.m b/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.m index eb6615745..3b7af0af5 100644 --- a/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.m +++ b/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.m @@ -241,14 +241,16 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const } - (void)scheduleMouseHideAfter:(NSTimeInterval)interval { - if(!self.shouldCaptureMouse) { - [_mouseHideTimer invalidate]; + [_mouseHideTimer invalidate]; - _mouseHideTimer = [NSTimer scheduledTimerWithTimeInterval:interval repeats:NO block:^(__unused NSTimer * _Nonnull timer) { + _mouseHideTimer = [NSTimer scheduledTimerWithTimeInterval:interval repeats:NO block:^(__unused NSTimer * _Nonnull timer) { + // Don't actually hide the mouse if this is a mouse-capture machine; that makes + // it fairly confusing as to current application state. + if(!self.shouldCaptureMouse) { [NSCursor setHiddenUntilMouseMoves:YES]; - [self.responderDelegate scanTargetViewWillHideOSMouseCursor:self]; - }]; - } + } + [self.responderDelegate scanTargetViewWouldHideOSMouseCursor:self]; + }]; } - (void)mouseEntered:(NSEvent *)event { @@ -279,30 +281,26 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const #pragma mark - Mouse motion - (void)applyMouseMotion:(NSEvent *)event { - if(!self.shouldCaptureMouse) { + if(!_mouseIsCaptured) { // Mouse capture is off, so don't play games with the cursor, just schedule it to // hide in the near future. [self scheduleMouseHideAfter:standardMouseHideInterval]; [self.responderDelegate scanTargetViewDidShowOSMouseCursor:self]; } else { - if(_mouseIsCaptured) { - // Mouse capture is on, so move the cursor back to the middle of the window, and - // forward the deltas to the listener. - // - // TODO: should I really need to invert the y coordinate myself? It suggests I - // might have an error in mapping here. - const NSPoint windowCentre = [self convertPoint:CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5) toView:nil]; - const NSPoint screenCentre = [self.window convertPointToScreen:windowCentre]; - const CGRect screenFrame = self.window.screen.frame; - CGWarpMouseCursorPosition(NSMakePoint( - screenFrame.origin.x + screenCentre.x, - screenFrame.origin.y + screenFrame.size.height - screenCentre.y - )); + // Mouse capture is on, so move the cursor back to the middle of the window, and + // forward the deltas to the listener. + // + // TODO: should I really need to invert the y coordinate myself? It suggests I + // might have an error in mapping here. + const NSPoint windowCentre = [self convertPoint:CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5) toView:nil]; + const NSPoint screenCentre = [self.window convertPointToScreen:windowCentre]; + const CGRect screenFrame = self.window.screen.frame; + CGWarpMouseCursorPosition(NSMakePoint( + screenFrame.origin.x + screenCentre.x, + screenFrame.origin.y + screenFrame.size.height - screenCentre.y + )); - [self.responderDelegate mouseMoved:event]; - } else { - [self.responderDelegate scanTargetViewDidShowOSMouseCursor:self]; - } + [self.responderDelegate mouseMoved:event]; } } @@ -334,7 +332,7 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const _mouseIsCaptured = YES; [NSCursor hide]; CGAssociateMouseAndMouseCursorPosition(false); - [self.responderDelegate scanTargetViewWillHideOSMouseCursor:self]; + [self.responderDelegate scanTargetViewWouldHideOSMouseCursor:self]; [self.responderDelegate scanTargetViewDidCaptureMouse:self]; if(self.shouldUsurpCommand) { ((CSApplication *)[NSApplication sharedApplication]).eventDelegate = self;