0

I have a single Dell monitor with a Mac Studio connected to it using USB-C and a laptop running Ubuntu connected using HDMI. I also have a KVM but I'm only using that for input devices, not video because the KVM is HDMI based and I want to use MonitorControl to control the screen brightness and that requires using DP Alt Mode over USB-C (I believe that's a limitation of the M1 not working well with DDC/CI over HDMI from what I've read). So I want to use DDC/CI to change the display's video input when I switch the KVM.

1 Answer 1

1

After some messing around I found a solution to this so I'm documenting this here in case it helps anyone else:

There appears to be several command line apps for sending DDC/CI commands but the only one I could find that worked on an M1 mac was m1ddc.

To trigger this on the connection of the usb hub of the KVM I used launchd (MacOS's system for launching programs based on certain conditions or events). Unfortunately if you use launchd to trigger a shell script directly that script will be run multiple times when the device is connected because launchd expects the executed program to register that it has consumed the triggering event. To deal with this I used this fantastic little utility, xpc_set_event_stream_handler which provides a simple bootstrapping program which will mark the event as consumed then call whatever program or script you'd like.

xpc_set_event_stream_handler must be compiled (you'll probably need xcode or xcode command line tools installed if not already). I did that with:

cd /tmp
git clone https://github.com/snosrap/xpc_set_event_stream_handler
cd xpc_set_event_stream_handler/xpc_set_event_stream_handler
gcc -framework Foundation -o xpc_set_event_stream_handler main.m
sudo mv xpc_set_event_stream_handler /usr/local/bin/

Then I created a script with my desired m1ddc command for switching displays and saved that in /usr/local/bin/kvm-switch-attached:

#!/bin/bash
/usr/local/bin/m1ddc display 1 set input 27

Then I marked it as executable with chmod +x /usr/local/bin/kvm-switch-attached

Next I created my launchd plist at /Library/LaunchDaemons/com.kvm-switch-attached.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.KVMSwitchAttached</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/xpc_set_event_stream_handler</string>
        <string>/usr/local/bin/kvm-switch-attached</string>
    </array>
    <key>LaunchEvents</key>
    <dict>
        <key>com.apple.iokit.matching</key>
        <dict>
            <key>com.KVMSwitchAttached.Event</key>
            <dict>
                <key>idVendor</key>
                <integer>8523</integer>
                <key>idProduct</key>
                <integer>29264</integer>
                <key>IOProviderClass</key>
                <string>IOUSBDevice</string>
                <key>IOMatchLaunchStream</key>
                <true/>
            </dict>
        </dict>
    </dict>
</dict>
</plist>

I got the idVendor and idProduct values from System Infomation and converted the values from there hex representation to decimal using an online converter.

I registered the launchd plist with sudo launchctl load /Library/LaunchDaemons/com.kvm-switch-attached.plist.

I couldn't find a way a good way to trigger a script disconnect of the KVM's usb hub. So instead I did a similar thing on my Ubuntu laptop and got that to switch inputs when the hub is connected. I used u/MortimerErnest's solution although as you can see in my comment I simplified it a tad.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .