diff --git a/MMBackend.m b/MMBackend.m index aae22afe67..99b9bfa49c 100644 --- a/MMBackend.m +++ b/MMBackend.m @@ -1249,6 +1249,10 @@ static int specialKeyToNSKey(int key); int col = *((int*)bytes); bytes += sizeof(int); gui_mouse_moved(col, row); + } else if (SetMouseShapeMsgID == msgid) { + const void *bytes = [data bytes]; + int shape = *((int*)bytes); bytes += sizeof(int); + update_mouseshape(shape); } else { NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid); } diff --git a/MMTextView.h b/MMTextView.h index 8bc50ca70c..41bc3742f8 100644 --- a/MMTextView.h +++ b/MMTextView.h @@ -14,7 +14,7 @@ @interface MMTextView : NSTextView { BOOL shouldDrawInsertionPoint; NSEvent *lastMouseDownEvent; - //NSTrackingRectTag trackingRectTag; + NSTrackingRectTag trackingRectTag; } - (NSEvent *)lastMouseDownEvent; diff --git a/MMTextView.m b/MMTextView.m index f8d9b48f11..0f968d87ee 100644 --- a/MMTextView.m +++ b/MMTextView.m @@ -18,6 +18,7 @@ @interface MMTextView (Private) - (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column; +- (NSRect)trackingRect; - (void)dispatchKeyEvent:(NSEvent *)event; - (MMVimController *)vimController; @end @@ -262,54 +263,85 @@ - (void)mouseMoved:(NSEvent *)event { + MMTextStorage *ts = (MMTextStorage*)[self textStorage]; + if (!ts) return; + NSPoint pt = [self convertPoint:[event locationInWindow] fromView:nil]; int row, col; if (![self convertPoint:pt toRow:&row column:&col]) return; - NSMutableData *data = [NSMutableData data]; + // HACK! It seems impossible to get the tracking rects set up before the + // view is visible, which means that the first mouseEntered: or + // mouseExited: events are never received. This forces us to check if the + // mouseMoved: event really happened over the text. + int rows, cols; + [ts getMaxRows:&rows columns:&cols]; + if (row >= 0 && row < rows && col >= 0 && col < cols) { + NSMutableData *data = [NSMutableData data]; - [data appendBytes:&row length:sizeof(int)]; - [data appendBytes:&col length:sizeof(int)]; + [data appendBytes:&row length:sizeof(int)]; + [data appendBytes:&col length:sizeof(int)]; - [[self vimController] sendMessage:MouseMovedMsgID data:data wait:NO]; + [[self vimController] sendMessage:MouseMovedMsgID data:data wait:NO]; + } } -#if 0 - (void)mouseEntered:(NSEvent *)event { - NSLog(@"%s", _cmd); + //NSLog(@"%s", _cmd); [[self window] setAcceptsMouseMovedEvents:YES]; } - (void)mouseExited:(NSEvent *)event { - NSLog(@"%s", _cmd); + //NSLog(@"%s", _cmd); + + int shape = 0; + NSMutableData *data = [NSMutableData data]; + [[self window] setAcceptsMouseMovedEvents:NO]; - [[NSCursor arrowCursor] set]; + + [data appendBytes:&shape length:sizeof(int)]; + [[self vimController] sendMessage:SetMouseShapeMsgID data:data wait:NO]; } - (void)setFrame:(NSRect)frame { - NSLog(@"%s", _cmd); + //NSLog(@"%s", _cmd); - // NOTE: Set a tracking rect which covers the text view. While the mouse - // cursor is in this rect the view will receive 'mouseMoved:' events so - // that Vim can take care of updating the mouse cursor. + // When the frame changes we also need to update the tracking rect. [super setFrame:frame]; [self removeTrackingRect:trackingRectTag]; - trackingRectTag = [self addTrackingRect:frame owner:self userData:NULL - assumeInside:YES]; + trackingRectTag = [self addTrackingRect:[self trackingRect] owner:self + userData:NULL assumeInside:YES]; +} + +- (void)viewDidMoveToWindow +{ + //NSLog(@"%s (window=%@)", _cmd, [self window]); + + // Set a tracking rect which covers the text. + // NOTE: While the mouse cursor is in this rect the view will receive + // 'mouseMoved:' events so that Vim can take care of updating the mouse + // cursor. + if ([self window]) { + [[self window] setAcceptsMouseMovedEvents:YES]; + trackingRectTag = [self addTrackingRect:[self trackingRect] owner:self + userData:NULL assumeInside:YES]; + } } - (void)viewWillMoveToWindow:(NSWindow *)newWindow { + //NSLog(@"%s%@", _cmd, newWindow); + // Remove tracking rect if view moves or is removed. if ([self window] && trackingRectTag) { [self removeTrackingRect:trackingRectTag]; + trackingRectTag = 0; } } -#endif - (NSMenu*)menuForEvent:(NSEvent *)event { @@ -444,6 +476,7 @@ - (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column { +#if 0 NSLayoutManager *lm = [self layoutManager]; NSTextContainer *tc = [self textContainer]; MMTextStorage *ts = (MMTextStorage*)[self textStorage]; @@ -459,7 +492,42 @@ if (row) *row = (int)(charIdx / mod); if (column) *column = (int)(charIdx % mod); + NSLog(@"convertPoint:%@ toRow:%d column:%d", NSStringFromPoint(point), + *row, *column); + return YES; +#else + MMTextStorage *ts = (MMTextStorage*)[self textStorage]; + NSSize cellSize = [ts cellSize]; + if (!(cellSize.width > 0 && cellSize.height > 0)) + return NO; + NSPoint origin = [self textContainerOrigin]; + + if (row) *row = floor((point.y-origin.y-1) / cellSize.height); + if (column) *column = floor((point.x-origin.x-1) / cellSize.width); + + //NSLog(@"convertPoint:%@ toRow:%d column:%d", NSStringFromPoint(point), + // *row, *column); + + return YES; +#endif +} + +- (NSRect)trackingRect +{ + NSRect rect = [self frame]; + NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; + int left = [ud integerForKey:MMTextInsetLeftKey]; + int top = [ud integerForKey:MMTextInsetTopKey]; + int right = [ud integerForKey:MMTextInsetRightKey]; + int bot = [ud integerForKey:MMTextInsetBottomKey]; + + rect.origin.x = left; + rect.origin.y = top; + rect.size.width -= left + right - 1; + rect.size.height -= top + bot - 1; + + return rect; } - (void)keyDown:(NSEvent *)event diff --git a/MMWindowController.m b/MMWindowController.m index 3a72e87eb9..1a6b0d6bc7 100644 --- a/MMWindowController.m +++ b/MMWindowController.m @@ -283,7 +283,7 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) [self addNewTabViewItem]; - [[self window] setAcceptsMouseMovedEvents:YES]; + //[[self window] setAcceptsMouseMovedEvents:YES]; setupDone = YES; diff --git a/gui_macvim.m b/gui_macvim.m index 73a30da602..5ef871b915 100644 --- a/gui_macvim.m +++ b/gui_macvim.m @@ -1097,6 +1097,7 @@ gui_mch_get_winpos(int *x, int *y) void gui_mch_getmouse(int *x, int *y) { + //NSLog(@"gui_mch_getmouse()"); } @@ -1248,6 +1249,7 @@ gui_mch_set_winpos(int x, int y) void gui_mch_setmouse(int x, int y) { + //NSLog(@"gui_mch_setmouse(x=%d, y=%d)", x, y); }