Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
saagarjha opened this issue Feb 7, 2024 · 3 comments
Open

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

saagarjha opened this issue Feb 7, 2024 · 3 comments

Comments

@saagarjha
Copy link
Contributor

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:

local path = application.applicationsForBundleID("com.apple.dock")[1]:path() .. "/Contents/Resources"

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
Copy link

Rhys-T commented Feb 7, 2024

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)
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
Copy link
Member

asmagill commented Feb 8, 2024

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
Copy link
Contributor Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants