Hammerspoonが不調の時はLuaのGCを疑うべし
ここ最近 Hammerspoon を触っていて、少しハマったことがあったので共有します。Hammerspoon は設定ファイルをLua で記述しますが、Lua にはGC(Garbage Collection) の機能があって、GC の結果回収してほしくないものまで回収されてしまい、キーバインド等が効かなくなってしまうことがあります。
init.lua でグローバル変数として保持しないとGCされる
事の発端はissue1103 にて確認できます。
また、公式のGetting Started Guideにも記載があります。
「A quick aside about variable lifecycles」の内容のとおりなのですが、init.lua の中で作成したオブジェクトは、グローバル変数(localとつけない変数)に代入しておかないとGC で回収されちゃうよ、ということらしいです。
実例
まずは駄目な例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
hs.eventtap.new({hs.eventtap.event.types.flagsChanged}, function(e) local keyCode = e:getKeyCode() local isCmd = e:getFlags()['cmd'] if isCmd then switchInputMethodPrevKey = keyCode else if switchInputMethodPrevKey == VK_LEFT_COMMAND then hs.eventtap.keyStroke({}, VK_EISUU) elseif switchInputMethodPrevKey == VK_RIGHT_COMMAND then hs.eventtap.keyStroke({}, VK_KANA) end end end ):start() |
上記コードは、左 Command 単発押しで「英数」ボタンがおされたことにする、右コマンド単発押しで「かな」ボタンが押されたことにするというものです。ご存知英かな の動作です。High Sierra で英かなが動かないという情報を耳にしたので、Hammerspoonで代替するコードを書いていました。
hs.eventtap.new で作成されたオブジェクトをグローバル変数に代入せず、そのまま start を呼んで開始しています。このままでもひとまず動きますが、そのうちLua のGC が走って動かなくなります。
正しくは下記
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
switchInputMethod = hs.eventtap.new({hs.eventtap.event.types.flagsChanged}, function(e) local keyCode = e:getKeyCode() local isCmd = e:getFlags()['cmd'] if isCmd then switchInputMethodPrevKey = keyCode else if switchInputMethodPrevKey == VK_LEFT_COMMAND then hs.eventtap.keyStroke({}, VK_EISUU) elseif switchInputMethodPrevKey == VK_RIGHT_COMMAND then hs.eventtap.keyStroke({}, VK_KANA) end end end ) switchInputMethod:start() |
一旦グローバル変数に代入しておきます。これでGCされることはなくなります。全文はGithubにあげてます ので詳細はそちらを確認してください。
GCが起きても問題ないかを確認する方法
LuaのGCが発生するタイミングは予測できないですが、GCを強制的に発生させる方法があります。init.lua を読み込んだ直後にGCを発生させてから動作確認をすることで、GCが起きても問題ない設定になっているかを確認できます。
やり方は Hammerspoon のメニューからコンソールを起動し、入力欄に collectgarbage()
と打ち込むだけです。
最後に
Hammerspoon 楽しいです。とりあえずこれさえ動けばキーバインド系は大体解決できそう。
SlackとSkypeが Enter で改行せずに送信してしまう問題も Hammerspoon で解決できたので、良ければそちらもご覧ください。
最後まで読んでいただきありがとうございます。 このブログを「いいな」と感じていただけましたら、Twiter にてフォローいただけるとうれしいです。ブログ更新情報などもお届けします。
Follow @ryuta461
この記事をシェアする