-
-
Save vv111y/2e74408899d0cdbb87a4d768f8ed23dd to your computer and use it in GitHub Desktop.
Capture double tap of Ctrl in Hammerspoon
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local alert = require("hs.alert") | |
local timer = require("hs.timer") | |
local eventtap = require("hs.eventtap") | |
local events = eventtap.event.types | |
local module = {} | |
-- ** Changed original gist from "ctrl" to "cmd" ** | |
-- Save this in your Hammerspoon configuration directiorn (~/.hammerspoon/) | |
-- You either override timeFrame and action here or after including this file from another, e.g. | |
-- | |
-- cmdDoublePress = require("cmdDoublePress") | |
-- cmdDoublePress.timeFrame = 2 | |
-- cmdDoublePress.action = function() | |
-- do something special | |
-- end | |
-- how quickly must the two single cmd taps occur? | |
module.timeFrame = 1 | |
-- what to do when the double tap of cmd occurs | |
module.action = function() | |
alert("You double tapped cmd!") | |
end | |
-- Synopsis: | |
-- what we're looking for is 4 events within a set time period and no intervening other key events: | |
-- flagsChanged with only cmd = true | |
-- flagsChanged with all = false | |
-- flagsChanged with only cmd = true | |
-- flagsChanged with all = false | |
local timeFirstControl, firstDown, secondDown = 0, false, false | |
-- verify that no keyboard flags are being pressed | |
local noFlags = function(ev) | |
local result = true | |
for k,v in pairs(ev:getFlags()) do | |
if v then | |
result = false | |
break | |
end | |
end | |
return result | |
end | |
-- verify that *only* the cmd key flag is being pressed | |
local onlyCtrl = function(ev) | |
local result = ev:getFlags().cmd | |
for k,v in pairs(ev:getFlags()) do | |
if k ~= "cmd" and v then | |
result = false | |
break | |
end | |
end | |
return result | |
end | |
-- the actual workhorse | |
module.eventWatcher = eventtap.new({events.flagsChanged, events.keyDown}, function(ev) | |
-- if it's been too long; previous state doesn't matter | |
if (timer.secondsSinceEpoch() - timeFirstControl) > module.timeFrame then | |
timeFirstControl, firstDown, secondDown = 0, false, false | |
end | |
if ev:getType() == events.flagsChanged then | |
if noFlags(ev) and firstDown and secondDown then -- cmd up and we've seen two, so do action | |
if module.action then module.action() end | |
timeFirstControl, firstDown, secondDown = 0, false, false | |
elseif onlyCtrl(ev) and not firstDown then -- cmd down and it's a first | |
firstDown = true | |
timeFirstControl = timer.secondsSinceEpoch() | |
elseif onlyCtrl(ev) and firstDown then -- cmd down and it's the second | |
secondDown = true | |
-- modal.alertId = hs.alert.show("Hit CMD twice", 9999) | |
elseif not noFlags(ev) then -- otherwise reset and start over | |
timeFirstControl, firstDown, secondDown = 0, false, false | |
end | |
else -- it was a key press, so not a lone cmd char -- we don't care about it | |
timeFirstControl, firstDown, secondDown = 0, false, false | |
end | |
return false | |
end):start() | |
return module |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment