Created
April 18, 2016 03:20
-
-
Save asmagill/c38f75fff9d9ef43d1226329fc1436e4 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 = {} | |
-- Save this in your Hammerspoon configuration directiorn (~/.hammerspoon/) | |
-- You either override timeFrame and action here or after including this file from another, e.g. | |
-- | |
-- ctrlDoublePress = require("ctrlDoublePress") | |
-- ctrlDoublePress.timeFrame = 2 | |
-- ctrlDoublePress.action = function() | |
-- do something special | |
-- end | |
-- how quickly must the two single ctrl taps occur? | |
module.timeFrame = 1 | |
-- what to do when the double tap of ctrl occurs | |
module.action = function() | |
alert("You double tapped ctrl!") | |
end | |
-- Synopsis: | |
-- what we're looking for is 4 events within a set time period and no intervening other key events: | |
-- flagsChanged with only ctrl = true | |
-- flagsChanged with all = false | |
-- flagsChanged with only ctrl = 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 ctrl key flag is being pressed | |
local onlyCtrl = function(ev) | |
local result = ev:getFlags().ctrl | |
for k,v in pairs(ev:getFlags()) do | |
if k ~= "ctrl" 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 -- ctrl 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 -- ctrl down and it's a first | |
firstDown = true | |
timeFirstControl = timer.secondsSinceEpoch() | |
elseif onlyCtrl(ev) and firstDown then -- ctrl down and it's the second | |
secondDown = true | |
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 ctrl 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