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.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Cloudream
  • 631
  • 6
  • 14

4 Answers4

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.

zoul
  • 102,279
  • 44
  • 260
  • 354
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.

apaderno
  • 28,547
  • 16
  • 75
  • 90
  • 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. – Peter Hosey Nov 20 '11 at 00:52
  • Thank you, searched several times but Google never told me there is a NSCursor class. – Cloudream Nov 20 '11 at 12:34
  • 1
    But I get system cursor with `NSCursor *sysCursor = [NSCursor currentSystemCursor]` and compare with every possible value, no type is equaled, codes added in question. – Cloudream Nov 20 '11 at 12:35
0

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

Nick Moore
  • 15,547
  • 6
  • 61
  • 83
-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.

Sylter
  • 1,622
  • 13
  • 26
  • In fact I run this code in `applicationDidFinishLaunching` when testing. My app is windowless (only an icon in status bar), so `currentCursor` returns nil. – Cloudream Nov 20 '11 at 14:00
  • 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*/ } – Sylter Nov 20 '11 at 14:18
  • 1
    `currentCursor` refers to your application's current cursor, not the current cursor in the active application. – Peter Hosey Nov 20 '11 at 21:07
  • 1
    `NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(checkCursor) userInfo:nil repeats:NO];` still not working. (Always a "not") Does it work on your machine? – Cloudream Nov 21 '11 at 11:57