Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift on OS X. How to handle global mouse events?

I am new to Swift and Xcode and I have next problem:

I have simple Cocoa Swift Application with one counter (Label). enter image description here

How to handle all mouse clicks in my Mac (in all applications) and display it in my Label?

I use Xcode 7.3.1.

UPDATE 1. What I have already found it's Monitoring Events and addGlobalMonitorForEventsMatchingMask:handler: function in Cocoa, but I'm not sure that I'm on the right way.

like image 746
semanser Avatar asked Jul 21 '16 18:07

semanser


1 Answers

You are correct about using addGlobalMonitorForEventsMatchingMask:handler:

A simple example might look something like this:

AppDelegate.swift

class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!
    @IBOutlet var textLabel : NSTextField!
    var eventHandler : GlobalEventMonitor?
    var gecount : Int = 0

    func applicationDidFinishLaunching(aNotification: NSNotification) {

        eventHandler = GlobalEventMonitor(mask: .LeftMouseDownMask, handler: { (mouseEvent: NSEvent?) in
        self.gecount += 1
        self.textLabel.stringValue = "global event monitor: \(self.gecount)"
    })
    eventHandler?.start()
  }
}

GlobalEventMonitor.swift

public class GlobalEventMonitor {

    private var monitor: AnyObject?
    private let mask: NSEventMask
    private let handler: NSEvent? -> ()

    public init(mask: NSEventMask, handler: NSEvent? -> ()) {
        self.mask = mask
        self.handler = handler
    }

    deinit {
        stop()
    }

    public func start() {
        monitor = NSEvent.addGlobalMonitorForEventsMatchingMask(mask, handler: handler)
    }

    public func stop() {
        if monitor != nil {
            NSEvent.removeMonitor(monitor!)
            monitor = nil
        }
    }
}

Events are delivered asynchronously to your app and you can only observe the event; you cannot modify or otherwise prevent the event from being delivered to its original target application. Key-related events may only be monitored if accessibility is enabled or if your application is trusted for accessibility access (see AXIsProcessTrusted).

Note that your handler will not be called for events that are sent to your own application.

In order to capture events within your app your can either use the addLocalMonitorForEventsMatchingMask:handler: or the NSClickGestureRecognizer object.

If you wanted to combine the global event monitor with the gesture recognizer object it's simply a matter of implementing both objects into your class.

like image 193
l'L'l Avatar answered Oct 15 '22 06:10

l'L'l