Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Eventtap randomly stops intercepting events #1103
I'm currently playing with eventtap (Hammerspoon 0.9.49 and 0.9.50, MacOS 10.12.1, MBP Retina, 13-inch, Early 2015) and It seems to be working fine for me, but It randomly stops to intercept events. It might be related to the issue cited above.
Currently my config looks this way: https://gist.github.com/eoranged/b05481d2a2646a84a15da88a53304d92
It usually takes ~30-90 minutes to happen, but sometimes everything works fine for couple days. I don't see any pattern here. Callbacks are not executed until I reload config.
As a general recommendation, I would try to avoid having anything in your init.lua be a
(If you've seen any official docs/guides that use locals, please shout at me, and I'll fix them!)
While we're on the subject, @asmagill and @Habbie and I have had some on/off discussions about whether we should implicitly retain references to all of our created objects, so they don't get GC'd, so we may be able to avoid this horrible discovery in future, but it needs a good deal of thought since we'd then be potentially piling up objects for days/weeks/months.
For example: http://www.hammerspoon.org/go/ section "Fancy configuration reloading"
If you put
The same for "Reacting to application events" and I think every other watcher.
Opps! I didn't realise this.
I wrongly interpreted "A quick aside about variable lifecycles" in Getting Started with Hammerspoon to say as long as you "capture them in a variable" in
So basically, what you're saying @cmsj is that the ONLY time you should use
added a commit
Dec 5, 2016
@cmsj & @asmagill - Quick question regarding the whole global vs local discussion. If a module is made global within
As a general rule of thumb, all watchers and timers should be captured in a global variable.
An exception to this requirement is when a local variable is captured within the scope of a function which is captured in a global variable or the Lua registry.
If the last line doesn't make sense, see below, or take the simpler approach of just making sure to capture them in global variables.
To keep from name collisions, I separate most of my stuff into separate files, then create a table that all of the watchers, etc. get added to for that file, then return that table at the end of the file. When I invoke the file with
Optional Explanation of Exception listed above:
Take for example the following code (copy and paste both lines into the console as one, if you want to try it yourself):
local a = 0 increment = function() a = a + 1 ; return a end
In this case,
> a, increment() nil 1 > a, increment() nil 2 > a, increment() nil 3 > a, increment() nil 4 etc.
Similarly when you register a callback function for most of our watchers, etc. the function itself has a reference stored in a special table referred to as the LUA_REGISTRY. The registry is effectively a "global" table available to all C-API functions/methods (or with
s = false -- global local a = 0 local t t = hs.timer.doEvery(1, function() if not s then a = a + 1 ; print(a) else t:stop() end end)
Gives the following output:
1 2 3 > collectgarbage() -- if we hadn't captured `t` in the callback function, this would stop the timer 0 4 5 > s, a, t false nil nil 6 7 > s = true -- this finally stops the timer, since `s` was the only global
It's a topic that I've been planning to add to the wiki documents that I hope to work on this month.
For completeness (when I refer back to this for the wiki doc), the final example really should be more like this:
s = false -- global local a = 0 local t t = hs.timer.doEvery(1, function() if not s then a = a + 1 print(a) else t:stop() t = nil -- without this, the timer can never actually get collected, even though we've stopped it end end)
For a timer, the object is relatively small, so it would take a lot of them to actually cause a noticeable memory leak, but some of the other objects behind the modules are notably larger