Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@blissdev
Forked from nriley/init.lua
Created May 6, 2022 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blissdev/bba381996a5e797a4ad9029bba2a8448 to your computer and use it in GitHub Desktop.
Save blissdev/bba381996a5e797a4ad9029bba2a8448 to your computer and use it in GitHub Desktop.
Hammerspoon script for ensuring Sidecar is active when iPad is plugged in (macOS 10.15)
hs.loadSpoon('SpoonInstall')
spoon.SpoonInstall.use_syncinstall = true
Install = spoon.SpoonInstall
log = hs.logger.new('init', 5)
-- function debugUI(msg, table)
-- log:d(msg)
-- log:d(hs.inspect(table))
-- end
function connectToSidecar(msg, results, count)
local item
sidecarItemFound = (count > 0)
if not sidecarItemFound then
return log:d("Can't get Sidecar connection menu item:", msg)
end
item = results[1]
if item.AXMenuItemMarkChar == nil then
-- log:d("Connecting to Sidecar...")
item:doAXPress()
else
-- log:d("Closing menu - already connected to Sidecar...")
item.AXParent:doAXCancel()
end
end
function stopConnectToSidecarItemSearchTimer()
if connectToSidecarItemSearchTimer then
connectToSidecarItemSearchTimer:stop()
connectToSidecarItemSearchTimer = nil
end
end
function displaysMenu(msg, results, count)
local menu, connectToSneezerItemSearch
if count == 0 then
return log:d("Can't get displays menu:", msg)
end
menu = results[1]
menu:doAXPress()
connectToSneezerItemSearch = hs.axuielement.searchCriteriaFunction({
{attribute = 'AXRole', value = 'AXMenuItem'},
{attribute = 'AXIdentifier', value = '_deviceSelected:'},
{attribute = 'AXTitle', value = 'Sneezer'}})
-- menu:elementSearch(debugUI, connectToSneezer,
-- {objectOnly = false, asTree = true, depth = 2})
-- iPad may not appear immediately in the Displays menu
-- wait up to 3 seconds for it to appear
stopConnectToSidecarItemSearchTimer()
sidecarItemFound = false
connectToSidecarItemSearchTimer = hs.timer.doUntil(
function()
return sidecarItemFound
end,
function()
menu:elementSearch(connectToSidecar, connectToSneezerItemSearch,
{count = 1, depth = 2, noCallback = true})
end,
0.5)
hs.timer.doAfter(3, stopConnectToSidecarItemSearchTimer)
end
function connectSidecar()
local suisApp, suisAX, displayMenuSearch
suisApp = hs.application.find('com.apple.systemuiserver')
suisAX = hs.axuielement.applicationElement(suisApp)
displayMenuSearch = hs.axuielement.searchCriteriaFunction({
{attribute = 'AXRole', value = 'AXMenuBarItem'},
{attribute = 'AXSubrole', value = 'AXMenuExtra'},
{attribute = 'AXDescription', value = '^Displays', pattern = true}
})
-- suisAX:elementSearch(debugUI, displayMenuSearch,
-- {objectOnly = false, asTree = true, depth = 2})
suisAX:elementSearch(displaysMenu, displayMenuSearch,
{count = 1, depth = 2})
end
-- what we actually get when the iPad connects:
-- connect, disconnect, connect
-- so, don't trigger twice within half a second
connectSidecarTimer = hs.timer.delayed.new(0.5, function()
connectSidecar()
end)
function iPadConnected(connected)
-- log:d("iPad connected?", connected)
if connected then
connectSidecarTimer:start()
else
connectSidecarTimer:stop()
end
end
Install:andUse(
"USBDeviceActions",
{
config = {
devices = {
iPad = { fn = iPadConnected }
}
},
start = true
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment