MacOS – way to make the macbook automatically execute a script every time I connect it to an external monitor

command linedisplaymacosscript

I would like to make my macbook automatically connect to a specific wifi and launch Lunar everytime I connect it to my external monitor, and vice versa when I unplug it, but don't know where to start…

I could write a script that keeps checking whether or not an external monitor is connected every, for example, 60 seconds, but I would like to do something like "event driven" that is neither checking nor doing anything at all until an event ("external monitor plugged" or "external monitor unplugged") occurs.

Any hint?

Best Answer

No one answered and I'm still looking for a simpler solution but I've found a workaround creating a little SwiftUI app.

//
//  ContentView.swift
//  HomeSweetHome
//
//  Created by Daniel Falbo on 20/08/2020.
//  Copyright © 2020 Daniel Falbo. All rights reserved.
//

import SwiftUI

struct ContentView: View {
    
    func execute(script: String) {
        let task = Process()
        task.launchPath = "/usr/bin/env"
        task.arguments = ["/Applications/HomeSweetHome.app/Contents/bin/\(script)"]
        task.launch()
    }
    
    var body: some View {
        Text("?")
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .onReceive(NotificationCenter.default.publisher(for: NSApplication.didChangeScreenParametersNotification)) { _ in
                self.execute(script: NSScreen.screens.count > 1 ? "connect" : "disconnect")
        }
    }
    
}

It's basically just a Text object that listens for didChangeScreenParametersNotification. Since the Text object must be alive in order to listen for notifications, an istance of the app must always be opened or minimized (does anyone have any idea on how to avoid this?). Every time it receives a notification, it checks the number of connected displays, if there's only one display connected, it executes my disconnect script, else it executes my connect script.

This is what the scripts look like:

#!/usr/bin/env sh
#
# connect
#
open -a Lunar
networksetup -setairportnetwork en0 $SSID $PASSWORD
#!/usr/bin/env sh
#
# disconnect
#
killall Lunar
networksetup -setairportnetwork en0 $SSID $PASSWORD

And this is what the app looks like ?

HomeSweetHome

This helped me connecting to a wifi programmatically