简体   繁体   中英

NSClickGestureRecognizer not working on NSStatusItem

Trying to recognize a right click on a NSStatusItem I got a suggestion ( Thanks to Zoff Dino ) to use a NSClickGestureRecognizer for that. But for some bizarre reason it isn't working as it should be. I am able to recognize a left click ( buttonMask = 0x1 ) but not a right-click ( buttonMask = 0x2 ). This is how I would like it to work but it isn't:

func applicationDidFinishLaunching(aNotification: NSNotification) {
    // Insert code here to initialize your application


    if let button = statusItem.button {

        // Add right click functionality
        let gesture = NSClickGestureRecognizer()
        gesture.buttonMask = 0x2 // right mouse
        gesture.target = self
        gesture.action = "rightClickAction:"
        button.addGestureRecognizer(gesture)


    }}

func rightClickAction(sender: NSGestureRecognizer) {
    if let button = sender.view as? NSButton {
        NSLog("rightClick")
    }
}

UPDATE:

I still did not manage to gets to work. Somehow it doesn't react on a right click (but changing the code on a left click) does. I guess some really simple issues are occurring that seem to block it from working. Even stranger is the fact that gesture.buttonMask = 0x1 works on the left click.

An alternative solution rather than NSClickGestureRecognizer is to attach a custom view to the status bar and handle the event from there.

The small disadvantage is you have to take care of the drawing and menu delegate methods.

Here a simple example:

Create a file StatusItemView a subclass of NSView

import Cocoa

class StatusItemView: NSView, NSMenuDelegate {

  //MARK: - Variables

  weak var statusItem : NSStatusItem!
  var menuVisible = false

  var image : NSImage! {
    didSet {
      if image != nil {
        statusItem.length = image.size.width
        needsDisplay = true
      }
    }
  }

  //MARK: - Override functions

  override func mouseDown(theEvent: NSEvent) {
    if let hasMenu = menu {
      hasMenu.delegate = self
      statusItem.popUpStatusItemMenu(hasMenu)
      needsDisplay = true
    }
  }

  override func rightMouseDown(theEvent: NSEvent) {
    Swift.print(theEvent)
  }

  //MARK: - NSMenuDelegate

  func menuWillOpen(menu: NSMenu) {
    menuVisible = true
    needsDisplay = true
  }

  func menuDidClose(menu: NSMenu) {
    menuVisible = false
    menu.delegate = nil
    needsDisplay = true
  }

  //MARK: - DrawRect

  override func drawRect(dirtyRect: NSRect) {
    statusItem.drawStatusBarBackgroundInRect(bounds, withHighlight:menuVisible)
    let origin = NSMakePoint(2.0, 3.0) // adjust origin if necessary
    image?.drawAtPoint(origin, fromRect: dirtyRect, operation: .CompositeSourceOver, fraction: 1.0)
  }
}

In AppDelegate you need a reference to the custom menu and an instance variable for the NSStatusItem instance

 @IBOutlet weak var menu : NSMenu!
 var statusItem : NSStatusItem!

In applicationDidFinishLaunching create the view and attach it to the status item. Be aware to set the image of the view after attaching it to make sure the width is considered.

  func applicationDidFinishLaunching(aNotification: NSNotification) {
    statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-1) // NSVariableStatusItemLength)
    let statusItemView = StatusItemView(frame: NSRect(x: 0.0, y: 0.0, width: statusItem.length, height: 22.0))
    statusItemView.statusItem = statusItem;
    statusItemView.menu = menu
    statusItem.view = statusItemView
    statusItemView.image = NSImage(named: NSImageNameStatusAvailable)
  }

The special case control-click to trigger the right-click function is not implemented.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM