5

I’m building a status bar app and want to call different actions depending on if the user clicked left or right. Here’s what I have so far:

var statusItem = NSStatusBar.system().statusItem(withLength: -1)
statusItem.action = #selector(AppDelegate.doSomeAction(sender:))

let leftClick = NSEventMask.leftMouseDown
let rightClick = NSEventMask.rightMouseDown

statusItem.button?.sendAction(on: leftClick)
statusItem.button?.sendAction(on: rightClick)

func doSomeAction(sender: NSStatusItem) {
    print("hello world")
}

My function is not called and I couldn’t find our why. I appreciate any help!

ixany
  • 5,433
  • 9
  • 41
  • 65

2 Answers2

16

Have you tried:

button.sendAction(on: [.leftMouseUp, .rightMouseUp])

Then seeing which mouse button was pressed in the doSomeAction() function?

So it will look something like...

let statusItem = NSStatusBar.system().statusItem(withLength: NSSquareStatusItemLength)

func applicationDidFinishLaunching(_ aNotification: Notification) {

    if let button = statusItem.button {
        button.action = #selector(self.doSomeAction(sender:))
        button.sendAction(on: [.leftMouseUp, .rightMouseUp])
    }

}

func doSomeAction(sender: NSStatusItem) {

    let event = NSApp.currentEvent!

    if event.type == NSEvent.EventType.rightMouseUp {
        // Right button click
    } else {
        // Left button click
    }

}

Thanks to @dbrownjave for noticing the change in Swift 4 from NSEventType.rightMouseUp to NSEvent.EventType.rightMouseUp.

https://github.com/craigfrancis/datetime/blob/master/xcode/DateTime/AppDelegate.swift

Craig Francis
  • 1,855
  • 3
  • 22
  • 35
  • this does work indeed, but seems to only like `.rightMouseUp`, not `.rightMouseDown` – joe Apr 26 '17 at 22:38
  • Did you also change the `button.sendAction` line? – Craig Francis Apr 26 '17 at 22:40
  • doh! changed in the `sendAction`, not in the statement! works just fine, thanks x) – joe Apr 26 '17 at 22:44
  • How would I do this with the NSEventMask.scrollWheel? – André Kuhlmann Jul 25 '17 at 14:40
  • How can I open a contextual menu only when I right click the item? I read that `popUpStatusItemMenu` is deprecated, and I could not understand how to do it in Swift 4... – stevereds May 21 '18 at 01:40
  • Make sure to also accept control-click: `if event.type == .rightMouseUp || (event.modifierFlags.contains(.control) && event.type == .leftMouseUp)` – exp Nov 08 '20 at 11:48
  • I don't know how this is working for you guys without setting the target in the button, it only works for me when I do `statusItem.button!.target = self` – bithavoc Sep 13 '21 at 17:20
  • @bithavoc, Does the other answer below work for you, ref Swift 4, which uses `NSEvent.EventType.rightMouseUp`? – Craig Francis Sep 13 '21 at 17:22
  • @CraigFrancis yes it worked, thank you very much. I realized since `self` is not in the responder chain, then I had to set the `button.target` manually. – bithavoc Sep 14 '21 at 01:14
2

Updated: SWIFT 4

I've updated (Craig Francis) answer

func doSomeAction(sender: NSStatusItem) {

    let event = NSApp.currentEvent!

    if event.type == NSEvent.EventType.rightMouseUp{
        // Right button click
    } else {
        // Left button click
    }
dbrownjave
  • 437
  • 1
  • 8
  • 19