I am searching for a way to detect whenever the NSStatusBarButton
is right-clicked (using Swift) and call an action.
I am currently setting it up this way:
let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-1)
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
if let button = statusItem.button {
button.image = NSImage(named: "myImage")
button.alternateImage = NSImage(named: "myImage")
button.action = Selector("myAction")
}
}
I thought of using the button.rightMouseDown(<#theEvent: NSEvent#>)
(Because there is no such "alternateAction") but unfortunately I did not manage to come up with something due to the fact that I just started programming Mac apps.
Update:
While searching for a way to do this I saw some threads telling to subclass a
NSView
but I don't se how this should work (This could be because I am really new to programming and don't even know how to "subclass"). Still I thought there was some easier way to use this since nearly everystatusBar
App that I know rects on right-clicks.
You can subclass and override the mouseDown
method, but since Mac OS X 10.10 (Yosemite), there has been an easier way: NSGestureRecognizer
and its subclasses:
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
if let button = statusItem.button {
button.image = NSImage(named: "myImage")
button.alternateImage = NSImage(named: "myImage")
button.action = Selector("myAction")
// Add right click functionality
let gesture = NSClickGestureRecognizer()
gesture.buttonMask = 0x2 // right mouse
gesture.target = self
gesture.action = "myRightClickAction:"
button.addGestureRecognizer(gesture)
}
}
func myRightClickAction(sender: NSGestureRecognizer) {
if let button = sender.view as? NSButton {
// Handle your right click event here
}
}
I had the same problem as you with the accepted answer's method: it didn't work for buttonMask 0x2, only buttonMask 0x1. Regular NSButton
s (but not NSStatusBarButtons
) can handle NSClickGestureRecognizer
s, so perhaps that's what the answerer was thinking. Another solution I found suggested was to set the NSStatusItem
's view
to an instance of your own custom subclass of NSView
, but as of OS X v10.10, getting or setting view
is deprecated, so I didn't want to do that.
I solved this by adding a custom subclass of NSView
as a subview of the NSStatusItem
's button. My NSView
implements -rightMouseUp:
to receive the right mouse up event and then just passes that event to a block given to it by my class that wants to handle the right mouse click event.
Here's my custom subclass:
#import <Cocoa/Cocoa.h>
@interface TTRightClickDetector : NSView
@property (copy) void (^onRightMouseClicked)(NSEvent *);
@end
#import "TTRightClickDetector.h"
And the implementation:
@implementation TTRightClickDetector
- (void)rightMouseUp:(NSEvent *)theEvent
{
if(self.onRightMouseClicked)
{
self.onRightMouseClicked(theEvent);
}
}
@end
And here's how I use it:
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
NSStatusBarButton *button = self.statusItem.button;
button.image = [NSImage imageNamed:@"image"];
button.action = @selector(leftMouseClicked:);
TTRightClickDetector *rightClickDetector = [[TTRightClickDetector alloc] initWithFrame:button.frame];
rightClickDetector.onRightMouseClicked = ^(NSEvent *event){
[self rightMouseClicked];
};
[button addSubview:rightClickDetector];
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