diff --git a/Source/EventFilter.h b/Source/EventFilter.h index 207ffcf..0c3f64d 100644 --- a/Source/EventFilter.h +++ b/Source/EventFilter.h @@ -80,6 +80,9 @@ * _emulationButton: The button number that mouse button #1 is currently being emulated as. A mouse up * event on button #1 will be mapped to a mouse up event on this button. * + * _lastMousePoint: Maintains the last unpublished mouse move. Mouse moves are cached and only sent to the + * server on a periodic basis so as not to flood the server with mouse moves. + * * When an event is received from the NSResponder, it is added to _pendingEvents. Then, _pendingEvents * is scanned to determine whether any action can be taken. Things that might occur at this point are: * @@ -127,6 +130,10 @@ typedef enum { NSTimeInterval _tapAndClickButtonSpeed[2]; NSTimeInterval _tapAndClickTimeout[2]; NSTimer *_tapAndClickTimer; + + NSTimer *_mouseTimer; + NSPoint _lastMousePoint; + bool _unsentMouseMoveExists; } // Talking to the server @@ -147,6 +154,8 @@ typedef enum { - (void)mouseDragged:(NSEvent *)theEvent; - (void)rightMouseDragged:(NSEvent *)theEvent; - (void)otherMouseDragged:(NSEvent *)theEvent; +- (void)sendUnpublishedMouseMove; +- (void)clearUnpublishedMouseMove; // Local Keyboard Events - (void)keyDown: (NSEvent *)theEvent; diff --git a/Source/EventFilter.m b/Source/EventFilter.m index 851c7fb..a39a66d 100644 --- a/Source/EventFilter.m +++ b/Source/EventFilter.m @@ -75,6 +75,10 @@ - (id)init _pendingEvents = [[NSMutableArray alloc] init]; _pressedKeys = [[NSMutableSet alloc] init]; _emulationButton = 1; + _mouseTimer = nil; + _unsentMouseMoveExists = NO; + _lastMousePoint.x = -1; + _lastMousePoint.y = -1; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(applicationDidBecomeActive:) name: NSApplicationDidBecomeActiveNotification object: nil]; } @@ -172,6 +176,7 @@ - (void)scrollWheel: (NSEvent *)theEvent addMask = rfbButton4Mask; else addMask = rfbButton5Mask; + [self clearUnpublishedMouseMove]; [_connection mouseAt: p buttons: _pressedButtons | addMask]; // 'Mouse button down' [_connection mouseAt: p buttons: _pressedButtons]; // 'Mouse button up' } @@ -180,43 +185,94 @@ - (void)mouseMoved:(NSEvent *)theEvent { if ( _viewOnly ) return; + + if( nil != _mouseTimer ) + { + [_mouseTimer invalidate]; + [_mouseTimer release]; + _mouseTimer = nil; + } - // send this out of order, in front of anything we've got pending - NSPoint p = [_view convertPoint: [theEvent locationInWindow] fromView: nil]; - [_connection mouseAt: p buttons: _pressedButtons]; + NSPoint currentPoint = [_view convertPoint: [theEvent locationInWindow] fromView: nil]; + + //#define CHANGE_DIFF 5 + #define IGNORE_COUNT 10 + + static int ct = IGNORE_COUNT; + bool bSendEventImmediately = NO; + + if( IGNORE_COUNT == ct ) + { + // if( (_lastMousePoint.x - currentPoint.x <= CHANGE_DIFF && _lastMousePoint.x - currentPoint.x >= -CHANGE_DIFF) && + // (_lastMousePoint.y - currentPoint.y <= CHANGE_DIFF && _lastMousePoint.y - currentPoint.y >= -CHANGE_DIFF) ) + // { + bSendEventImmediately = YES; + // } + + ct = 0; + } + else + { + ++ct; + } + + _unsentMouseMoveExists = YES; + _lastMousePoint = currentPoint; + + if( YES == bSendEventImmediately ) + { + NSLog( @"Forced Mouse Move." ); + [self sendUnpublishedMouseMove]; + } + else + { + NSLog( @"Ignored Mouse Move." ); + _mouseTimer = [NSTimer scheduledTimerWithTimeInterval: 0.05 + target: self + selector: @selector(handleMouseTimer:) + userInfo: nil + repeats: NO]; + [_mouseTimer retain]; + } } -- (void)mouseDragged:(NSEvent *)theEvent +- (void)handleMouseTimer: (NSTimer *) timer { - if ( _viewOnly ) - return; + [_mouseTimer release]; + _mouseTimer = nil; + + [self sendUnpublishedMouseMove]; + + NSLog( @"Sent Mouse Move." ); +} - // getting this implies that we've gotten a mouse down, so we can just send it directly - NSPoint p = [_view convertPoint: [theEvent locationInWindow] fromView: nil]; - [_connection mouseAt: p buttons: _pressedButtons]; +- (void)clearUnpublishedMouseMove +{ + _unsentMouseMoveExists = NO; } -- (void)rightMouseDragged:(NSEvent *)theEvent +- (void)sendUnpublishedMouseMove { - if ( _viewOnly ) - return; + if( YES == _unsentMouseMoveExists ) + { + [self clearUnpublishedMouseMove]; + [_connection mouseAt: _lastMousePoint buttons: _pressedButtons]; + } +} - // getting this implies that we've gotten a mouse down, so we can just send it directly - NSPoint p = [_view convertPoint: [theEvent locationInWindow] fromView: nil]; - [_connection mouseAt: p buttons: _pressedButtons]; +- (void)mouseDragged:(NSEvent *)theEvent +{ + [self mouseMoved:theEvent]; } -- (void)otherMouseDragged:(NSEvent *)theEvent +- (void)rightMouseDragged:(NSEvent *)theEvent { - if ( _viewOnly ) - return; + [self mouseMoved:theEvent]; +} - // getting this implies that we've gotten a mouse down, so we can just send it directly - if ( 2 == [theEvent buttonNumber] ) - { - NSPoint p = [_view convertPoint: [theEvent locationInWindow] fromView: nil]; - [_connection mouseAt: p buttons: _pressedButtons]; - } +- (void)otherMouseDragged:(NSEvent *)theEvent +{ + [self mouseMoved:theEvent]; } @@ -570,7 +626,10 @@ - (void)_sendMouseEvent: (QueuedEvent *)event } if ( _pressedButtons != oldPressedButtons ) + { + [self clearUnpublishedMouseMove]; [_connection mouseAt: [event locationInWindow] buttons: _pressedButtons]; + } } @@ -596,11 +655,13 @@ - (void)_sendKeyEvent: (QueuedEvent *)event if ( kQueuedKeyDownEvent == [event type] ) { + [self sendUnpublishedMouseMove]; [_pressedKeys addObject: encodedChar]; [_connection sendKey: sendKey pressed: YES]; } else if ( [_pressedKeys containsObject: encodedChar] ) { + [self sendUnpublishedMouseMove]; [_pressedKeys removeObject: encodedChar]; [_connection sendKey: sendKey pressed: NO]; } @@ -613,11 +674,13 @@ - (void)_sendModifierEvent: (QueuedEvent *)event if ( kQueuedModifierDownEvent == [event type] ) { + [self sendUnpublishedMouseMove]; _pressedModifiers |= modifier; [_connection sendModifier: modifier pressed: YES]; } else if ( _pressedModifiers & modifier ) { + [self sendUnpublishedMouseMove]; _pressedModifiers &= ~modifier; [_connection sendModifier: modifier pressed: NO]; } @@ -852,6 +915,7 @@ - (unsigned int)handleMultiTapForButton: (unsigned int)button NSPoint p = [_view convertPoint: [[_view window] convertScreenToBase: [NSEvent mouseLocation]] fromView: nil]; unsigned int rfbButton = ButtonNumberToRFBButtomMask( button ); + [self clearUnpublishedMouseMove]; [_connection mouseAt: p buttons: _pressedButtons | rfbButton]; // 'Mouse button down' [_connection mouseAt: p buttons: _pressedButtons]; // 'Mouse button up' return 0;