Run script when connecting/disconnecting external monitor

I’ve got a quick apple script that I’ve turned into an application that will swap my dock from hidden at the bottom to always visible on the right-side. I run this script every morning when I get to work and plug in to a 2nd monitor and before I leave in the afternoon before I yank the cord. Is there some system event I can watch for with a launch daemon to fire off this script automatically when the system detects a change such as isExternalMonitor = True/False? I’m running Monterey on a M1MBP if that matters.

ps I don’t want to use a timed launchd because my schedule isn’t set enough to M-F@7 just run this thing.
Thanks for any help,~Sauva

You could probably use Hammerspoon to watch for the display change.

https://www.hammerspoon.org/docs/hs.screen.watcher.html

1 Like

Not sure if it’s what you’re after, but I believe Keyboard Maestro also has this as a trigger option.

2 Likes

I’d thought KM could only report and not trigger on monitor connections, but from the docs, it seems trigger support was added back in v9 :slightly_smiling_face:

https://wiki.keyboardmaestro.com/trigger/Display_Layout_Changed

I obviously need to pay more attention to release notes than I was doing.

<3 I’d never heard of hammerspoon, but check it, I made it work!
this is toggle doc.app

tell application "System Events"
	set monitorCount to count of desktops
	if monitorCount is 1 then
		tell dock preferences
			set properties to {screen edge:bottom}
			set autohide to true
		end tell
	else
		tell dock preferences
			set properties to {screen edge:right}
			set autohide to false
		end tell
	end if
end tell

this is my hammerspoon init.lua

--init.lua
--using hammerspoon to automatically run toggledock

-- LOAD VARIABLES
monitorWatcher = nil
initWatcher = nil

--MY FUNCTIONS
--function to reload init.lua when it changes
function reloadConfig(files)
  doReload = false
  for _,file in pairs(files) do
      if file:sub(-4) == ".lua" then
          doReload = true
      end
  end
  if doReload then
      hs.reload()
  end
end
--need a function that calls an applescript
function monitorChangedCallback()
--  hs.alert.show("trying to call toggle dock.app")
  hs.application.launchOrFocus("toggle dock.app")
end

--TOP
--starts the pathwatcher to see if the init.lua changes in ~/.hammerspoon/
initWatcher = hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reloadConfig):start()
hs.alert.show("Config loaded")

--objects will be garbage collcted if they aren't in explicit vars
--Starts the screen watcher, making it so fn is called each time the screen arrangement changes
monitorWatcher = hs.screen.watcher.new(monitorChangedCallback):start()

Thanks a bunch for turning me onto this sylumer
~~Sauva

1 Like

So 13.1 kinda breaks this as any change to the dock (app opening/closing file added to folder stack etc) will trigger hs.screen.watcher.

Has there been any development in shortcuts to bring external monitor status awareness as a potential action trigger?
~~Sauva

In case anyone wants to do something similar, I recently started using HiDock.app. It’s great.