As of OS X 10.10 most of NSStatusItem has been deprecated in favour of the button
property, which consists of an NSStatusBarButton. It should work like a normal button but unfortunately the cell
and setCell
methods in NSStatusButton have also been deprecated. As a result of this I'm struggling to find a way to keep the button highlighted after it's clicked (Normally the button is highlighted on mouse down, and unhighlighted on mouse up. I want to keep it highlighted after mouse up).
Calling [NSStatusButton setHighlighted:]
in its action doesn't work because it seems to unhighlight itself once the mouse is up. On the other hand, using a delay to call it on the next loop i.e. [self performSelector: withDelay:]
causes the highlight to flash in a rather unsightly way. It works, but doesn't look nice.
Setting the button type to NSToggleButton
removes the highlight entirely and instead highlights the template image which was odd.
Those were the only methods I could think of. Is there anyway to override this NSButtonCell mouseUp behaviour?
Here is one more option. Don't set NSStatusItem
's action
property. Instead add a local event monitor:
[NSEvent addLocalMonitorForEventsMatchingMask:(NSLeftMouseDown | NSRightMouseDown)
handler:^NSEvent *(NSEvent *event) {
if (event.window == self.statusItem.button.window) {
[self itemClicked];
return nil;
}
return event;
}];
Then in -itemClicked
highlight the button using highlight:
method:
- (void)itemClicked {
[self.statusItem.button highlight:YES];
// Do other stuff
}
To unhighlight just call button's highlight:NO
where you need.
Swift 3 version of Manfred Urban's answer. Works on El Capitan.
extension NSStatusBarButton {
public override func mouseDown(_ event: NSEvent) {
if (event.modifierFlags.contains(NSControlKeyMask)) {
self.rightMouseDown(event)
return
}
self.highlight(true)
(self.target as? TrivialTargetClass)?.togglePopover()
}
}
Don't forget to set the buttons highlight property to false again if appropriate.
I added a subview to the status item, and inside that view I added event handlers for mouseDown etc. which called [[statusItem button] highlight:true]. As it turns out setHighlighted: doesn't do the same thing as highlight:.
NSArray *array = [NSArray arrayWithObjects:[statusItem button], [self statusItemView], nil];
[[[statusItem button] superview] setSubviews:array];
//Highlight like so:
[[statusItem button] highlight:true];
EDIT: As of El Capitan this method no longer works, and neither does statusItem.button.highlight = true
either 😀🔫
Struggling with this issue myself, I discovered that overwriting mouseDown:
in a category on NSStatusBarButton
works:
#import "MUTargetClass.h"
@implementation NSStatusBarButton (Additions)
- (void)mouseDown:(NSEvent *)theEvent
{
// Relay CTRL+Click to perform a right click action
if(theEvent.modifierFlags & NSControlKeyMask)
{
[self rightMouseDown:theEvent];
return;
}
// Handle highlighting
[self setHighlighted:YES];
// Perform action on target
[(MUTargetClass *)self.target actionSelector:self];
}
@end
MUTargetClass
could then for example implement:
#import "NSStatusBarButton+Additions.h"
@implementation MUTargetClass
[…]
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
NSStatusBarButton *button = [self.statusItem button];
[button setTarget:self];
[…]
- (void)actionSelector:(id)sender
{
// Whatever behavior a click on the button should invoke
}
[…]
// Reset button's highlighting status when done
[[self.statusItem button] setHighlighted:NO];
[…]
@end
Note that the functionality of CTRL+clicking the button is getting lost in the mouseDown:
-override. As shown above, it can be restored by relaying the event to rightMouseDown:
.
A simpler way of having the action called would be something along the lines of [self.target performSelector:self.action]
in the category and [self.statusItem setAction:@selector(actionSelector:)]
in the target class, however this may cause a leak in ARC projects.
Edit: This works on El Capitan, too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With