views:

446

answers:

2

I am trying to get the on screen location of an NSStatusItem so that I can perform a click on that area via code like below. I am doing this so that my users can press a hotkey to see the menu.

event = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, newLocation, kCGMouseButtonLeft);
CGEventPost(kCGHIDEventTap, event);
CFRelease(event);

Does anyone know of a way to get the location?, I have been trying ideas and searching for days and have found several ideas but none of them seem to work in leopard/snow leopard

The NSStatusItem is using an NSMenu not a custom view.

A: 

Don't do this by simulating a mouse event, that is completely the wrong way to go.

You can use the -popUpStatusItemMenu: method of NSStatusItem to show the menu. You can call this method from a hot key by using a CGEventTap to capture global events that your NSStatusItem can respond to.

On 10.6 you can use the +addGlobalMonitorForEventsMatchingMask:handler: method of NSEvent to capture global events instead of using CGEventTap directly.

Rob Keniger
Thanks for answering, I am using popUpStatusItemMenu: already but the only downside is that it doesn't highlight the nsstatusitem so I was trying to find an alternative. I think I will just have to settle for popUpStatusItemMenu
Craig
`addGlobalMonitorForEventsMatchingMask:handler:` is for monitoring for events, not posting them, which is what he's doing with the event tap in the question's example. Moreover, it's not the easiest way to implement a hotkey; that would be Carbon Event Manager, whose hotkey API is still supported (even in 64-bit).
Peter Hosey
A: 

Thinking out loud you could create your own custom view for the NSStatusItem. Then for example from the AppController:

- (void)awakeFromNib {    
float width = 30.0;
float height = [[NSStatusBar systemStatusBar] thickness];
NSRect viewFrame = NSMakeRect(0, 0, width, height);
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:width] retain];
[statusItem setView:[[[MyCustomView alloc] initWithFrame:viewFrame controller:self] autorelease]];

And to simulate the highlight you'd send a message to your custom view. Then when drawing MyCustomView:

// In MyCustomView.m
- (void)drawRect:(NSRect)rect {
if (clicked) {
    [[NSColor selectedMenuItemColor] set];
    NSRectFill(rect);
}

As well as using -popUpStatusItemMenu:.

Ben Clark-Robinson