Is there a way to make my macbook automatically execute a script every time I connect it to an external monitor?

Solution 1:

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