haimgel / display-switch

Turn a $30 USB switch into a full-featured multi-monitor KVM switch
https://haim.dev/posts/2020-07-28-dual-monitor-kvm/
MIT License
2.85k stars 112 forks source link

Feature/control other monitor input #20

Closed kcorey closed 3 years ago

kcorey commented 3 years ago

Three changes suggested here: 1) added the lsusb information for Macs to the readme.

2) set things up so that I only have to run this on one Mac. That's important to me because the other Mac is a work Mac, and even if it's not so locked down that I can't do this, I suspect they'd frown upon it.

3) Set the display (both directions) three times. My IIyama PL2779Q doesn't hear if it's only set once. You have to really get its attention, I guess.

haimgel commented 3 years ago

Hi @kcorey, thanks for the PR!

I'd appreciate them small and focused, though... I can merge the documentation update right away, but IMHO the other two features need a bit more work: retry only on failure, for example, the on-removal change needs to be documented, etc.

Could you please send the documentation update as its own PR for now?

kcorey commented 3 years ago

I made this with two commits so that the documentation is already delivered separately. You can cherry-pick the commit with the documentation in it, if you like it.

No idea how to test for failure of video change. I didn't really expect you to merge this verbatim. I've only tried it on one Mac, and one monitor. No idea how this would work (or not) on a Windows system, or the effect on other, more sensitive monitors.

A concern about retry-on-failure is that switching already takes 3-5 seconds on my monitor. Certainly not a show-stopper, and in line with the time it takes for the usb lines to be recognised, etc. Faster than the 15-20 seconds it would take to select a different video input, and swap keyboards/mice.

If you're going to try to switch and then wait to see if it worked or not before repeating, you have to wait some period of time to see if the change has been made successfully and then send the signal again...wash, rinse, repeat. This risks making switching take longer than manually switching over.

Instead perhaps have a 'retry_switching' configuration, defaulted to 1 or 2, that controls how many times that signal is sent blindly?

haimgel commented 3 years ago

Hi @kcorey, could you please share the logs: what does the app say when it tries to switch inputs: e.g. is the first input reported as "success" and still not switched, or does the app get an error from DDC?

kcorey commented 3 years ago

Sure...

No errors are recorded, which is kind of why I was mystified.

5:27:50 [INFO] Display '0' set to 0xf 05:27:50 [INFO] Display '0' set to 0xf 05:27:50 [INFO] Display '0' set to 0xf 05:27:50 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:5411" 05:27:50 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:1006" 05:27:50 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:0221" 05:27:50 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:c52f" 05:27:57 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:0411" 05:27:57 [INFO] Detected device we're looking for "0bda:0411" 05:27:57 [INFO] Display '0' set to 0x11 05:27:57 [INFO] Display '0' set to 0x11 05:27:57 [INFO] Display '0' set to 0x11 05:27:57 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:5411" 05:27:57 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:1006" 05:27:58 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:0221" 05:27:59 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c52f" 05:39:32 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:0411" 05:39:32 [INFO] Detected the device we're looking for "0bda:0411", switching to other input 05:39:33 [INFO] Display '0' set to 0xf 05:39:33 [INFO] Display '0' set to 0xf 05:39:33 [INFO] Display '0' set to 0xf 05:39:33 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:5411" 05:39:33 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:1006" 05:39:33 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:c52f" 05:39:33 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:0221" 05:39:35 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:0411" 05:39:35 [INFO] Detected device we're looking for "0bda:0411" 05:39:35 [INFO] Display '0' set to 0x11 05:39:36 [INFO] Display '0' set to 0x11 05:39:36 [INFO] Display '0' set to 0x11 05:39:36 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:5411" 05:39:36 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:1006" 05:39:36 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:0221" 05:39:37 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c52f" 06:20:08 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:0411" 06:20:08 [INFO] Detected the device we're looking for "0bda:0411", switching to other input 06:20:08 [INFO] Display '0' set to 0xf 06:20:08 [INFO] Display '0' set to 0xf 06:20:08 [INFO] Display '0' set to 0xf 06:20:08 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:5411" 06:20:08 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:1006" 06:20:08 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:0221" 06:20:08 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:c52f" 08:13:08 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:0411" 08:13:08 [INFO] Detected device we're looking for "0bda:0411" 08:13:08 [INFO] Display '0' set to 0x11 08:13:08 [INFO] Display '0' set to 0x11 08:13:08 [INFO] Display '0' set to 0x11 08:13:08 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:5411" 08:13:08 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:1006" 08:13:09 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c52f" 08:13:09 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:0221" 08:13:15 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:0411" 08:13:15 [INFO] Detected the device we're looking for "0bda:0411", switching to other input 08:13:15 [INFO] Display '0' set to 0xf 08:13:15 [INFO] Display '0' set to 0xf 08:13:15 [INFO] Display '0' set to 0xf 08:13:15 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:5411" 08:13:15 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:1006" 08:13:15 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:c52f" 08:13:15 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:0221" 16:06:52 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:0411" 16:06:52 [INFO] Detected device we're looking for "0bda:0411" 16:06:52 [INFO] Display '0' set to 0x11 16:06:52 [INFO] Display '0' set to 0x11 16:06:52 [INFO] Display '0' set to 0x11 16:06:52 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:5411" 16:06:52 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:1006" 16:06:53 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:0221" 16:06:54 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c52f"

kcorey commented 3 years ago

For the record, that's switching back and forth several times. Display 0xf is my work computer, and 0x11 is my personal.

haimgel commented 3 years ago

Thanks @kcorey, this lack of error reporting sucks. Some displays flicker when you switch to the same input even, which is why I'm not too happy to just switch 3 times every time.

Could you please try to switch inputs with https://github.com/kfix/ddcctl ? See if it switches reliably, or is it having the same issue?

kcorey commented 3 years ago

Yes, ddcctl seems to control the input just fine:

└─[0] <git:(master 02dcf6c) > ./ddcctl -d 1 -i 17 D: NSScreen #861504775 (1920x1080 0°) 82.00 DPI I: found 1 external display I: polling display 1's EDID I: got edid.serial: 0 I: got edid.name: PL2779Q D: action: i: 17 D: setting VCP control #96 => 17

And of course the other direction with a value of 15. (./ddcctl -d 1 -I 15)

haimgel commented 3 years ago

This is awesome, thanks for confirming! I'll try figuring out what's the difference in code, or just plain use ddcctl code instead of what I'm using right now on MacOS.

jgauth commented 3 years ago

Just wanted to add on that the program wasn't switching the monitors' input for me. Calling display_control::switch_to several times (instead of just once) fixed the issue. On Mac only. No issues with windows.

haimgel commented 3 years ago

@kcorey I've added "control other monitor input" feature (now in the master branch).

Feel like the need to issue the switch command several times needs to be addressed separately... But I would appreciate you testing it with the current codebase, as the DDC code on MacOS changed quite a bit, and it might be OK for you as is.