Hammerspoon / hammerspoon

Staggeringly powerful macOS desktop automation with Lua
http://www.hammerspoon.org
MIT License
11.99k stars 582 forks source link

spaces.lua's search for Dock does not succeed on early startup #3598

Open saagarjha opened 8 months ago

saagarjha commented 8 months ago

Not sure when I started seeing this, perhaps in the first beta of 14.4? But this line of code fails for me when Hammerspoon opens on startup: https://github.com/Hammerspoon/hammerspoon/blob/56b5835dc1bf7bb430dfea3f1662379cccec0c82/extensions/spaces/spaces.lua#L57

Here's the error:

2024-02-07 01:20:17: *** ERROR: ...merspoon.app/Contents/Resources/extensions/hs/spaces.lua:57: attempt to index a nil value (field 'integer index')
stack traceback:
    ...merspoon.app/Contents/Resources/extensions/hs/spaces.lua:57: in local 'getDockExitTemplates'
    ...merspoon.app/Contents/Resources/extensions/hs/spaces.lua:77: in main chunk
    [C]: in function 'rawrequire'
    ...poon.app/Contents/Resources/extensions/hs/_coresetup.lua:662: in function 'require'
    ...n.app/Contents/Resources/extensions/hs/window_filter.lua:1530: in main chunk
    [C]: in function 'rawrequire'
    ...poon.app/Contents/Resources/extensions/hs/_coresetup.lua:662: in function 'require'
    (...tail calls...)
    [C]: in function 'rawrequire'
    ...poon.app/Contents/Resources/extensions/hs/_coresetup.lua:662: in function 'require'
    ...merspoon.app/Contents/Resources/extensions/hs/window.lua:1027: in function <...merspoon.app/Contents/Resources/extensions/hs/window.lua:1025>
    (...tail calls...)
    /Users/saagarjha/.hammerspoon/shared.lua:1: in main chunk
    [C]: in function 'rawrequire'
    ...poon.app/Contents/Resources/extensions/hs/_coresetup.lua:662: in function 'require'
    /Users/saagarjha/.hammerspoon/init.lua:21: in main chunk
    [C]: in function 'xpcall'
    ...poon.app/Contents/Resources/extensions/hs/_coresetup.lua:723: in function 'hs._coresetup.setup'
    (...tail calls...)

If I reload the config it works as expected, so I assume whenever this runs is too early for this to return any results?

Rhys-T commented 8 months ago

Yeah, it's looking for a running instance of the Dock, so it will fail if Hammerspoon somehow manages to start before the Dock. But all it's actually doing with it at that point is trying to find the Dock app on disk, so I think it could probably be changed to:

    local path   = application.pathForBundleID("com.apple.dock") .. "/Contents/Resources"

(It does try to actually talk to the running Dock later on, to interact with Mission Control/Spaces - but the Dock is likely to be running by the time you're using any of those functions.)


If you want to try out that change, you can copy spaces.lua from Hammerspoon into ~/.hammerspoon/hs/spaces.lua and edit the line above into that copy. Or if you want to dynamically patch it, so that you still get any other updates to spaces.lua in new Hammerspoon versions, you can create ~/.hammerspoon/hs/spaces.lua with this code in it:

~/.hammerspoon/hs/spaces.lua (patching version) ```lua local myName, myPath = ... local pathToAbsolute = require 'hs.fs'.pathToAbsolute local myAbsPath = pathToAbsolute(myPath) for entry in package.path:gmatch '[^;]*' do local realPath = package.searchpath(myName, entry) if not realPath or pathToAbsolute(realPath) == myAbsPath then goto continue end local fn = load(coroutine.wrap(function() local yield = coroutine.yield local findStr = [[application.applicationsForBundleID("com.apple.dock")[1]:path()]] local replaceStr = [[application.pathForBundleID("com.apple.dock")]] local findPattern = findStr:gsub('%W', '%%%0') local replacePattern = replaceStr:gsub('%%', '%%%%') local didPatch = false for line in io.lines(realPath, 'L') do local fixedLine, nMatches = line:gsub(findPattern, replacePattern) yield(fixedLine) if nMatches > 0 then didPatch = true end end if not didPatch then print "Warning: couldn't patch spaces.lua!" end end), '@'..realPath, 't') do return fn(myName, realPath) end ::continue:: end ```
asmagill commented 8 months ago

I've never run into a timing issue this tight, but pathForBundleID should work. At load time, it's looking for the specific verbiage that pages will be using in the Mission Control accessibility objects, so it's the location on disk that matters, not the running Dock itself.

As noted, the running Dock is important when you trigger it, but not at load time.

saagarjha commented 8 months ago

Would I run into issues if I just edited the app itself for testing?

cmsj commented 2 months ago

@saagarjha nope, editing .lua files inside Hammerspoon.app is fine, they're ignored by Gatekeeper.