Skip to content

Hammerspoon

Created: 2023-09-22 21:06:54 -0700 Modified: 2023-10-03 20:23:11 -0700

  • See this folder
    • I deleted highlight_window.lua only because I didn’t want that functionality anymore, but the script itself should contain some examples

If I ever come back to Hammerspoon, these are definitely the things I’ll want to know:

  • Debug-logging: print(hs.inspect({type, some, vars, here}))
    • The console has a text input at the bottom—use it!
  • Log to the middle of the screen: hs.alert.show(“hello world”)
  • Easiest development flow: in the Hammerspoon preferences, check “Keep Console window on top”, then open the Hammerspoon console from the 🔨 menu and reload your configuration from the dedicated button there.
  • Type information: it’s all in the docs.

This is usually due to the timer being garbage-collected. If this happens to you, try storing the timer in a global variable or reading the reference link.

Repro:

  • Save this as init.lua:
local windowfilter=require'hs.window.filter'
function winFocused()
print("winFocused")
end
wf=windowfilter.copy(windowfilter.default,'my-log', 'debug'):setOverrideFilter{focused=true}
wf:subscribe({[windowfilter.windowFocused]=winFocused})
  • Reload your config
  • Click between two Chrome windows for 5 seconds
  • After 5 seconds, the event will stop firing

The workaround seems to be to switch windows, so I guess it’s not severe.

If I use this script as written, I hit an issue that’s easiest to repro with Godot:

  • Debug → Run Multiple Instances → Run 2 Instances
  • Click ▶️
  • Try to drag one of the windows as soon as they open

It lags a lot. If you comment out this specific line, it’ll turn off the mouse handler, which is apparently enough for it never to lag. I think the real cause is something like this where Godot just isn’t responding to accessibility events quickly enough. If I add this code in:

testTimer = hs.timer.doEvery(1, function () print(hs.inspect(hs.window._timed_allWindows())) end )
testTimer:start()
hs.hotkey.bind({"alt"}, "A", function()
print("Stopping the timer")
testTimer:stop()
end)
print("Press ⌥A to stop the print spam")

…then I get output like this:

2023-10-03 20:06:52: took 0.41s for com.knollsoft.Rectangle

2023-10-03 20:06:52: took 0.34s for org.godotengine.godot

I assume that 0.75s is the lag that I’m feeling, but I can’t figure out a way around it without losing functionality in my script.