How to get current type of mouse cursor in Mac OS X?
Asked Answered
T

4

7

How can I get the current type of mouse cursor on screen? (Not only on my app window, globally.) Or is it at least possible to detect whether the default cursor is currently displayed? Either Carbon or Cocoa is OK – or even other working APIs, preferably the official ones.

This is what I have tried:

NSCursor *sysCursor = [NSCursor currentSystemCursor];

if (sysCursor == nil) {
    NSLog(@"nil");
}

if ([sysCursor isEqual: [NSCursor arrowCursor]] || 
    [sysCursor isEqual: [NSCursor contextualMenuCursor]] || 
    [sysCursor isEqual: [NSCursor closedHandCursor]] || 
    [sysCursor isEqual: [NSCursor crosshairCursor]] || 
    [sysCursor isEqual: [NSCursor disappearingItemCursor]] || 
    [sysCursor isEqual: [NSCursor dragCopyCursor]] || 
    [sysCursor isEqual: [NSCursor dragLinkCursor]] || 
    [sysCursor isEqual: [NSCursor IBeamCursor]] || 
    [sysCursor isEqual: [NSCursor openHandCursor]] || 
    [sysCursor isEqual: [NSCursor operationNotAllowedCursor]] || 
    [sysCursor isEqual: [NSCursor pointingHandCursor]] || 
    [sysCursor isEqual: [NSCursor resizeDownCursor]] || 
    [sysCursor isEqual: [NSCursor resizeLeftCursor]] || 
    [sysCursor isEqual: [NSCursor resizeLeftRightCursor]] || 
    [sysCursor isEqual: [NSCursor resizeRightCursor]] || 
    [sysCursor isEqual: [NSCursor resizeUpCursor]] || 
    [sysCursor isEqual: [NSCursor resizeUpDownCursor]] || 
    [sysCursor isEqual: [NSCursor IBeamCursorForVerticalLayout]]
    ) {
    NSLog(@"equal");
} else {
    NSLog(@"not");
}

The cursor is not nil, but at the same time it’s not equal to any of the others. It’s not even equal to itself:

NSLog(@"%i", [[NSCursor currentSystemCursor]
    isEqual:[NSCursor currentSystemCursor]]); // 0

Ideas? This is a LSUIElement-type app, if that matters.

Twelve answered 20/11, 2011 at 0:6 Comment(1)
This code works for me whether or not the app is an LSUIElement agent app.Tackling
A
2

This is quite a hack, but it looks like it’s possible to tell at least some cursors apart using the hotSpot property:

NSLog(@"%@", NSStringFromPoint([[NSCursor currentSystemCursor] hotSpot]));

This returns {5, 5} for the default pointer cursor. I have no idea if this value changes for the default cursor under some circumstances (like higher DPI or whatever else). I have ended up with this category on NSCursor:

- (BOOL) isDefaultCursor
{
    NSPoint defaultCursorHotspot = [[NSCursor arrowCursor] hotSpot];
    return NSEqualPoints(defaultCursorHotspot, [self hotSpot]);
}

Other than that, there’s a _flags.cursorType instance variable, but that’s protected. And, as you already mentioned, the current system cursor does not have to be even -isEqual: with itself.

Apologete answered 17/9, 2013 at 12:43 Comment(0)
L
1

You can check the cursor type currently set using code similar to the following one:

if ([[NSCursor currentSystemCursor] isEqual: [NSCursor pointingHandCursor]]) {
  // … 
}

The other values you can use, instead of [NSCursor pointingHandCursor] are listed in Retrieving cursor instances.

Littleton answered 20/11, 2011 at 0:19 Comment(3)
And if you just want to capture the current cursor, without comparing it to any specific cursor, then you can ask the current system cursor for its image.Imaimage
Thank you, searched several times but Google never told me there is a NSCursor class.Twelve
But I get system cursor with NSCursor *sysCursor = [NSCursor currentSystemCursor] and compare with every possible value, no type is equaled, codes added in question.Twelve
A
0

You can compare the cursor images. isEqual won't work for this, you have to get the bitmap image data and compare them.

Amortize answered 11/4, 2018 at 7:57 Comment(0)
K
-2

You should use currentCursor instead of currentSystemCursor, so your sysCursor declaration should be something like this:

NSCursor *sysCursor = [NSCursor currentCursor];

In addition, you should check the type of cursor after a user click and not, e.g. in applicationDidFinishLaunching or similar.

Kerbela answered 20/11, 2011 at 13:44 Comment(4)
In fact I run this code in applicationDidFinishLaunching when testing. My app is windowless (only an icon in status bar), so currentCursor returns nil.Twelve
You can check the cursor after the applicationDidFinishLaunching: using a NSTimer and calling a specific method after, for instance, a second (or after a less amount of time, you can try different solutions). [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkCursor) userInfo:nil repeats:NO]; The method would be similar to this one: - (void)checkCursor { /*Check the cursor*/ }Kerbela
currentCursor refers to your application's current cursor, not the current cursor in the active application.Imaimage
NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(checkCursor) userInfo:nil repeats:NO]; still not working. (Always a "not") Does it work on your machine?Twelve

© 2022 - 2024 — McMap. All rights reserved.