Dennis
Dennis

Reputation: 3596

Get Current Keyboard Cursor Location

Is there anyway to get coordinates for the current position of the keyboard cursor (caret) globally like you can for the mouse cursor position with mouseLocation?

Upvotes: 2

Views: 761

Answers (3)

aleclarson
aleclarson

Reputation: 19035

You can do this easily in macOS 10.0 and up.

For an NSTextView, override the drawInsertionPointInRect:color:turnedOn: method. To translate the caret position relative to the window, use the convertPoint:toView: method. Finally, you can store the translated position in an instance variable.

@interface MyTextView : NSTextView
@end

@implementation MyTextView
{
  NSPoint _caretPositionInWindow;
}

- (void)drawInsertionPointInRect:(CGRect)rect color:(NSColor *)color turnedOn:(BOOL)flag
{
  [super drawInsertionPointInRect:rect color:color turnedOn:flag];

  _caretPositionInWindow = [self convertPoint:rect.origin toView:nil];
}

@end

Upvotes: 1

Smilin Brian
Smilin Brian

Reputation: 990

The closest you can get would be to use OS X's Accessibility Protocol. This is intended to help disabled users operate the computer, but many applications don't support it, or do not support it very well.

The procedure would be something like:

appRef = AXUIElementCreateApplication(appPID);
focusElemRef = AXUIElementCopyAttributeValue(appRef,kAXFocusedUIElementAttribute, &theValue)
AXUIElementCopyAttributeValue(focusElemRef, kAXSelectedTextRangeAttribute, &selRangeValue);
AXUIElementCopyParameterizedAttributeValue(focusElemRef, kAXBoundsForRangeParameterizedAttribute, adjSelRangeValue, &boundsValue);

Due to the spotty support for the protocol, with many applications you won't get beyond the FocusedUIElementAttribute step, but this does work with some applications.

Upvotes: 1

Ken Aspeslagh
Ken Aspeslagh

Reputation: 11594

No, there is no way to do it globally.

If you want to do it in your own app, like in an NSTextView, you'd do it like this:

NSRange range = [textView selectedRange];
NSRange newRange = [[textView layoutManager] glyphRangeForCharacterRange:range actualCharacterRange:NULL];
NSRect rect = [[textView layoutManager] boundingRectForGlyphRange:newRange inTextContainer:[textView textContainer]];

rect would be the rect of the selected text, or in the case where there is just an insertion point but no selection, rect.origin is the view-relative location of the insertion point.

Upvotes: 3

Related Questions