Posted at

Hammerspoon のイベント監視が止まるのはGCのせい

More than 1 year has passed since last update.

Hammerspoon は Mac の OS イベントの割り込み処理を Lua で書けるソフトウェアです。

実は、公式ドキュメントのここ http://www.hammerspoon.org/go/#appevents らへんから始まるサンプルコードには罠があって、ちょっと注意が必要です。

本当のドキュメントはこの issue のほう Eventtap randomly stops intercepting events · Issue #1103 · Hammerspoon/hammerspoon

結果どうするべきかというと、GC に回収されないように注意して Lua を書かないといけないよということ。

こういうのはダメです:

local i = 0

hs.timer.doEvery(1, function()
i = i + 1
print(i)
end):start()

local i = 0

local secTimer = hs.timer.doEvery(1, function()
i = i + 1
print(i)
end)
secTimer:start()

2017-02-02 16:31:41: -- Loading ~/.hammerspoon/init.lua

2017-02-02 16:31:41: -- Loading extension: eventtap
2017-02-02 16:31:41: -- Loading extension: timer
2017-02-02 16:31:41: -- Done.
2017-02-02 16:31:42: 1
2017-02-02 16:31:43: 2
2017-02-02 16:31:44: 3
2017-02-02 16:31:45: 4
2017-02-02 16:31:46: 5
2017-02-02 16:31:47: 6
2017-02-02 16:31:48: 7
2017-02-02 16:31:49: 8
2017-02-02 16:31:50: 9
2017-02-02 16:31:51: 10

> collectgarbage('collect')
0

GC 直後に hs.timer.doEvery():start() が死んでいます。

正解はこう:

local i = 0

-- これをグローバル変数にする
secTimer = hs.timer.doEvery(1, function()
i = i + 1
print(i)
end)
secTimer:start()

2017-02-02 16:32:57: -- Lazy extension loading enabled

2017-02-02 16:32:57: -- Loading ~/.hammerspoon/init.lua
2017-02-02 16:32:57: -- Loading extension: eventtap
2017-02-02 16:32:57: -- Loading extension: timer
2017-02-02 16:32:57: -- Done.
2017-02-02 16:32:58: 1
2017-02-02 16:32:59: 2
2017-02-02 16:33:00: 3
2017-02-02 16:33:01: 4
2017-02-02 16:33:02: 5
2017-02-02 16:33:03: 6
2017-02-02 16:33:04: 7
2017-02-02 16:33:05: 8
2017-02-02 16:33:06: 9
2017-02-02 16:33:07: 10

> collectgarbage('collect')
0
2017-02-02 16:33:08: 11
2017-02-02 16:33:09: 12
2017-02-02 16:33:10: 13
2017-02-02 16:33:11: 14
2017-02-02 16:33:12: 15
2017-02-02 16:33:13: 16
2017-02-02 16:33:14: 17
2017-02-02 16:33:15: 18
2017-02-02 16:33:16: 19
2017-02-02 16:33:17: 20

IntelliJとかJVMのIDE使いでもKarabinerなしでバックスラッシュを片手入力したい

で修正したバグの詳細でした。