-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdouble-shift.lua
executable file
·77 lines (64 loc) · 2.66 KB
/
double-shift.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
-----------------------------------------------------------------------------------
-- File: double-shift.lua
-- Author: Joaquín Cuitiño
-- Adapted from: https://github.com/jhkuperus/dotfiles/blob/master/hammerspoon/double-shift.lua
-- License: MIT
-----------------------------------------------------------------------------------
-- Toggles Caps Lock state when double shift is pressed.
local eventtap = require("hs.eventtap")
local timer = require("hs.timer")
local events = eventtap.event.types
local module = {}
-- What is the maximum number of seconds over which the double-press will be considered a double press
module.timeFrame = 0.3
-- Change what this function does to change the behavior under double shift (can be overridden when including this module)
module.action = function()
-- On double-tap of shift, we are sending CMD-Space to the OS to activate Spotlight (or whatever is on that shortcut)
hs.hid.capslock.set(not hs.hid.capslock.get())
end
local timeFirstPress, firstDown, secondDown = 0, false, false
-- Function to check if the event is "clear" event where no modifier is 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
-- Function to check if the event is a shift-press only (no other modifiers down)
local onlyShift = function(ev)
local result = ev:getFlags().shift
for k,v in pairs(ev:getFlags()) do
if k~="shift" and v then
result = false
break
end
end
return result
end
-- The function actually watching events and keeping track of the shift presses
module.eventWatcher = eventtap.new({events.flagsChanged, events.keyDown}, function(ev)
if (timer.secondsSinceEpoch() - timeFirstPress) > module.timeFrame then
timeFirstPress, firstDown, secondDown = 0, false, false
end
if ev:getType() == events.flagsChanged then
if noFlags(ev) and firstDown and secondDown then -- shift up and we've seen two, do action
if module.action then module.action() end
timeFirstPress, firstDown, secondDown = 0, false, false
elseif onlyShift(ev) and not firstDown then -- first shift down, start timer
firstDown = true
timeFirstPress = timer.secondsSinceEpoch()
elseif onlyShift(ev) and firstDown then -- second shift down
secondDown = true
elseif not noFlags(ev) then -- some other key was pressed in between, cancel timer
timeFirstPress, firstDown, secondDown = 0, false, false
end
else -- some other key (other than modifiers) was pressed, cancel timer
timeFirstPress, firstDown, secondDown = 0, false, false
end
return false
end):start()
return module