Search code examples
objective-cmacostrackpad

MacOS Get trackpad pressure globally


I'm trying to get MacBook Pro trackpad pressure with following code:

CGEventRef eventTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef eventRef, void *refcon) {
    NSEvent *event = [NSEvent eventWithCGEvent:eventRef];

    NSLog(@"%lld", (int64_t)CGEventGetIntegerValueField(eventRef, kCGMouseEventPressure)); // returns 0
    NSLog(@"%lld", (int64_t)CGEventGetIntegerValueField(eventRef, kCGTabletEventPointPressure)); // returns 0
    NSLog(@"%lld", (int64_t)CGEventGetIntegerValueField(eventRef, kCGTabletEventTangentialPressure)); // returns 0

    NSLog(@"%f", [event pressure]); // Assertion failure

    return eventRef;
}

Do you have any idea how to do that?


Solution

  • Pressure data is available if the device supports it (i.e. a force touch trackpads). Force touch trackpads have shipped on MacBooks since circa 2015. Force touch is also available on the Magic Trackpad.

    This blog post has a method for detecting force touch devices, although I didn't try it.

    My machine is a 2016 MacBook Pro with a force touch trackpad. I can get the pressure using this code:

    [self.window trackEventsMatchingMask:NSEventMaskPressure 
        timeout:NSEventDurationForever 
        mode:NSEventTrackingRunLoopMode 
        handler:^(NSEvent * _Nonnull event, BOOL * _Nonnull stop) {
            NSLog(@"%f", event.pressure);
        }];
    

    Output:

    2018-02-09 18:16:10.986036-0800 forcetouch[4587:4164200] 0.437820
    2018-02-09 18:16:10.993772-0800 forcetouch[4587:4164200] 0.457504
    2018-02-09 18:16:11.001883-0800 forcetouch[4587:4164200] 0.476486
    2018-02-09 18:16:11.010654-0800 forcetouch[4587:4164200] 0.494812
    2018-02-09 18:16:11.017738-0800 forcetouch[4587:4164200] 0.512497
    2018-02-09 18:16:11.028129-0800 forcetouch[4587:4164200] 0.529556
    2018-02-09 18:16:11.033769-0800 forcetouch[4587:4164200] 0.546021
    2018-02-09 18:16:11.042117-0800 forcetouch[4587:4164200] 0.561905
    2018-02-09 18:16:11.049869-0800 forcetouch[4587:4164200] 0.577240
    

    However, I see you are using an event tap.

    I tried your code, and when I check kCGMouseEventPressure I get 1. When I check event.pressure I also get 1. So I receive a value where you do not - I guess you do not have force touch hardware? But I do not receive the actual pressure value.

    I'm not sure how to get this using an event tap.

    This works for me on a 2016 MacBook Pro. Note that this machine has a force touch trackpad. I'm not sure what this will return on a machine without the force touch trackpad. However hopefully this gives you some more ideas.

    Force touch for developers

    NSEvent - pressure