Hammerspoon / hammerspoon

Staggeringly powerful macOS desktop automation with Lua
http://www.hammerspoon.org
MIT License
11.86k stars 578 forks source link

Is it possible to detect three finger taps on trackpad using hammerspoon? #2057

Open foray1010 opened 5 years ago

foray1010 commented 5 years ago

I am making a spoon that trigger middle click when three finger taps. I looked at all event types, seems only NSEventTypeMagnify response to three finger taps, but from the naming seems it is not I am looking for. Is it possible to do it using hammerspoon? thanks

latenitefilms commented 5 years ago

Maybe have a play with this:

https://github.com/asmagill/hammerspoon_asm.undocumented/tree/390ae06b18edd7604c51187262ede5c7e19944b7/touchdevice

asmagill commented 5 years ago

Eventtap has been a challenge from the beginning and Apple hasn't made it any easier over the years... most of the recent additions to include gestures, etc. were added through the Cocoa (Objective-C) NSEvent class and not to the Quartz CGEvent functions. The important distinction to note is that through NSEvent, you can only capture (and change or suppress) events specifically targeting your own application -- to capture them globally you have to use the Quartz interface and it hasn't been updated as completely (or documented as well, either). Because hs.eventtap was written to override events for your entire system, we've concentrated on the Quartz interface.

We've attempted to integrate the two somewhat, e.g. including the NS* event types in the list of events in hs.eventtap.event.types, but it's only ever partially worked and often changes between OSX updates.

Interestingly, when I do the following:

-- causes eventtap to respond to *all* events that it can, except keyboard stuff
a = hs.eventtap.new({"all", hs.eventtap.event.types.flagsChanged, hs.eventtap.event.types.keyDown, hs.eventtap.event.types.keyUp}, function(e) print(e:getType()) end):start()

It does show a type 29 event when I do a three finger tap (as well as a few 5's intermixed -- 29 is NSEventTypeGesture and 5 is mouseMoved). However, it also issues a 29 for the other gestures as well (pinch/zoom, rotate, etc) so unless someone knows of a way to further identify the specific type of gesture, that's probably a dead end.

rynop commented 4 years ago

This would be sweet to have in Hammerspoon. BetterTouchTool some how has it implemented (maybe they use Obj-C?)

karlhorky commented 3 years ago

I don't know my way around Objective-C very much, but artginzburg/MiddleClick-Catalina worked in for making three-finger clicks on a Magic Mouse into a middle click (in macOS Catalina).

Open source here:

https://github.com/artginzburg/MiddleClick-Catalina/blob/master/MiddleClick/Controller.m

But unfortunately, it stopped working in Big Sur :( https://twitter.com/karlhorky/status/1327192793115193345

Edit: Oh, maybe it's because the MultitouchSupport framework is missing? https://developer.apple.com/forums/thread/653972

Edit 2: Oops, my fault 🤦‍♂️ v2.4.8.1 does work on Big Sur after all! https://github.com/Hammerspoon/hammerspoon/issues/2057#issuecomment-730513165

asmagill commented 3 years ago

@karlhorky MiddleClick-Catalina looked interesting, and I've recently started needing to use XQuartz again, so having three button support is of interest to me, so I took a look at the code and put this together:

https://github.com/asmagill/hammerspoon-config-take2/blob/master/_scratch/threeFingers.lua

It requires https://github.com/asmagill/hs._asm.undocumented.touchdevice to be installed first (the v0.2 build works with the current release of Hammerspoon, or you can download and make it yourself). This does require the MultitouchSupport framework, but while that particular framework bundle does appear to be missing in Big Sur, it compiles and loads fine in Hammerspoon, so I'm guessing that the particular functions we require are supplied by other frameworks now?

Stick the threeFingers.lua file in ~/.hammerspoon and load it with something like tf = require("threeFingers"). It will create a menu like MiddleClick-Catalina, and you can select click or tap from there. You can adjust the number of fingers with tf.fingers(#) where # is an integer > 2. Mode and number of fingers is stored with hs.settings so they persist through a reload/relaunch of Hamemrspoon.

I'm not happy with the tap support, I could only get it to work maybe every fourth or fifth time I tried the tapping, but the click mode seems to work well and thats what I personally prefer anyways... I'll take another look at the tapping code, though -- I compacted some of the logic in MiddleClick-Catalina, so maybe I screwed something up. Note that if you use tap mode and leave it at the default of 3, you'll also need to disable "Look up & data detectors" in System Preferences -> Trackpad.


Re approaching this from the gesture angle as I describe in my earlier comments in this thread, @latenitefilms has put together a pull request for the creation of most of the possible gestures, and I've done some research and may have some answers to better detecting these and have an in progress pull to that effect as well. It is my hope to land these later this week and may have more to say on that angle then.

karlhorky commented 3 years ago

Nice, thanks for exploring @asmagill !

Regarding the private MultitouchSupport framework, it appears that according to https://github.com/EpicGames/UnrealEngine/commit/1d252ee345cdf6c232b20c3b4bf14f13bb569c9d, the new path can be resolved as such:

string SDKROOT = Utils.RunLocalProcessAndReturnStdOut("/usr/bin/xcrun", "--sdk macosx --show-sdk-path");
PublicAdditionalLibraries.Add(SDKROOT + "/System/Library/PrivateFrameworks/MultitouchSupport.framework/Versions/Current/MultitouchSupport.tbd");

...which for me results in a change between the two paths like this:

-/System/Library/PrivateFrameworks/MultitouchSupport.framework/Versions/Current/MultitouchSupport
+/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/PrivateFrameworks/MultitouchSupport.framework/Versions/Current/MultitouchSupport.tbd
karlhorky commented 3 years ago

Oh wait... 🤦‍♂️

I just realized I was using the old Homebrew cask (which was out of date). There is one with the new version v2.4.8.1 that works on Big Sur!! https://github.com/markhughes/MiddleTap/issues/2#issuecomment-730500106

Sorry for the noise.

asmagill commented 3 years ago

Ok, my final version of middleButton is at https://github.com/asmagill/hs._asm.undocumented.touchdevice/blob/master/Examples/middleButton.lua

It can now adjust the tapDelta (see comments around line 256)... I find that 1.2 works pretty well for me rather than the .4 that was in the original code. But I prefer the click mode anyways, so... YMMV.

And if you upgrade to the latest version of https://github.com/asmagill/hs._asm.undocumented.touchdevice, it now supports watchers, so you don't have to worry about rescanning if you have external devices.

Now that that bug is out of my head, I can get back to reviewing pull requests!

khesed commented 1 year ago

Is there any update on this?