Code Monkey home page Code Monkey logo

display-switch's Introduction

Who is Haim Gelfenbeyn?

Iโ€™m a software engineer currently from Ontario, Canada. Iโ€™ve worked with quite a range of different platforms and technologies, from Windows GUI to Web applications, with detours into DevOps, device drivers, and mobile development. Today, I'm building awesome software for TheoremOne clients.

In my spare time, I enjoy woodworking, improving my home automation setup, 3D printing, spending time with my family.

Latest entries on my blog

How to reach me

LinkedIn is a good way to contact me.

display-switch's People

Contributors

adosikas avatar alexvinarskis avatar andornaut avatar autarch avatar benjaminfaal avatar charlietran avatar cocowalla avatar georgehahn avatar haimgel avatar inversion avatar jabl avatar jrr avatar kcorey avatar liqi0816 avatar max-wittig avatar micwoj92 avatar olivierlemoal avatar peamaeq avatar pm215 avatar profile926 avatar svend avatar universal avatar vovazolotoy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

display-switch's Issues

Support bluetooth as well?

I've just discovered this, and it seems really cool.

It seems to me that the same method could also work without the usb hub. Lots of bluetooth keyboards will pair with multiple devices and can switch connections between them. Monitorning for this connection appearing and disappearing could also trigger the same result!

Monitor ids

Heya, been waiting for the multi monitor support and just tried the new release. All my monitors are listed as Generic PnP Monitor in the Windows device manager. Not sure what you mean with monitor id in the readme, but here's the hardware id

e.g.
image

I tried the config like this

usb_device = "046D:082D"

[monitor1]
monitor_id = "sam"
on_usb_disconnect = "0xfe"

[monitor2]
monitor_id = "del"
on_usb_connect = "DisplayPort1"
on_usb_disconnect = "DisplayPort2"

but according to the log "Display 'Generic PnP Monitor' is not configured to switch on USB disconnect", neither my dell or samsung monitor seem to be finding their config

full log https://gist.github.com/phit/b3486d2cd35513445d7bcd9858e17f62

thanks for any advice!

Support for USB-C to HDMI Cables?

Hello again,

I am running this on a MacBook Pro (15-inch, 2018) (Catalina 10.15.7 (19H2)). I have two identical monitors and I made the following config:

usb_device = "2109:2811"

[monitor1]
monitor_id = "DELL U2415 S/N 860704844"
on_usb_connect = "DisplayPort2"

[monitor2]
monitor_id = "DELL U2415 S/N 808931925"
on_usb_connect = "hdmi1"

Monitor 1 uses an mDP Cable to a full sized Display cable, using a Dell Display Cable to USB-C adapter. While the other monitor uses a direct USB C to HDMI display cable.

While monitor 1 seems to switch perfectly, Monitor 2 fails with the following error:

08:17:21 [ERROR] Failed to get current input for display 'DELL U2415 S/N 808931925': Ddc(InvalidChecksum)

at start. And when trying to change the monitor, it outputs:

08:16:38 [DEBUG] (1) display_switch::display_control: Setting display 'DELL U2415 S/N 808931925' to Hdmi1(0x11)
08:16:38 [INFO] Display 'DELL U2415 S/N 808931925' set to Hdmi1(0x11)

But fails to perform any such change. What could be wrong here?

Not switching to different input (same works) due to I2C bus error when using an active DisplayPort-to-HDMI adapter

Reporting to document and for completeness sake as this appears to be an issue with the DP-HDMI adapter.

  • Windows 10, 64 Bit, current on updates.
  • Active DisplayPort to HDMI adapter
    • Accell DP to HDMI Adapter - DisplayPort 1.2 to HDMI 2.0 Active Adapter - 4K UHD @ 60Hz. Model number: B086B-011B).
  • The log shows two displays, which may be due to the adapter:
    • Generic PnP Monitor '#0' - 0x11
    • GM107GL-A/2147881095:Lvds '# 1' - 0x11
  • The adapter is detected as a relay by the NVidia drivers, which also prevents HDCP from working.
  • The name of my monitor (LG Ultra HD) is shown by the display driver and the ControlMyMonitor utility but not in the display-switch logs.

The programmatic display input switch works when the input is still the same. However, after a manual switch to another input switching back no longer works. The I2C signal no longer gets through causing an I2C error which gets logged.

Case 1 - toggling the USB switch while input is already set to HDMI (0x11) (PC), i.e. setting to active input.

16:44:55 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0612"
16:44:55 [INFO] Detected device we're looking for "05e3:0612"
16:44:55 [DEBUG] (1) display_switch::platform::display_control_ddc_hi: Setting display ''Generic PnP Monitor' #0' to 0x11
16:44:55 [INFO] Display 'Generic PnP Monitor' #0 set to 0x11
16:44:55 [DEBUG] (1) display_switch::platform::display_control_ddc_hi: Setting display ''GM107GL-A/2147881095:Lvds' #1' to 0x11
16:44:55 [INFO] Display 'GM107GL-A/2147881095:Lvds' #1 set to 0x11
16:44:56 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
16:46:11 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0000:0000"

Case 2 - toggling USB switch when input is set to DisplayPort (Mac)

16:51:08 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0612"
16:51:08 [INFO] Detected device we're looking for "05e3:0612"
16:51:08 [DEBUG] (1) display_switch::platform::display_control_ddc_hi: Setting display ''Generic PnP Monitor' #0' to 0x11
16:51:08 [ERROR] Failed to set display 'Generic PnP Monitor' #0 to 0x11 (Os { code: -1071241854, kind: Other, message: "An error occurred while transmitting data to the device on the I2C bus." })
16:51:08 [DEBUG] (1) display_switch::platform::display_control_ddc_hi: Setting display ''GM107GL-A/2147881095:Lvds' #1' to 0x11
16:51:08 [ERROR] Failed to set display 'GM107GL-A/2147881095:Lvds' #1 to 0x11 (I2c(Error))
16:51:08 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"

Possible issue with more than 2 HDMI ports on monitor

I've got 2 monitors, and my secondary monitor is successfully switching back and forth on USB switch presses. However, my primary monitor won't switch between computers regardless of whichever Hdmi[1/2] or DisplayPort [1/2] settings I enable in the config.

My completely uneducated guess is that my issue is because my monitor has 3 HDMI ports and 1 DisplayPort and I'm forced to use the HDMI 3 port on the monitor because it's the only port that supports HDMI 2.0 and allows me to use my 1440p monitor at 144Hz. The DisplayPort is connected to the other computer.

Here's my config:

usb_device = "1A40:0101"

[monitor1]
monitor_id = "1"
on_usb_connect = "Hdmi1"
on_usb_disconnect = "DisplayPort1"

[monitor2]
monitor_id = "2"
on_usb_connect = "DisplayPort1"
on_usb_disconnect = "Hdmi1"

And the log that is generated:

14:47:49 [INFO] Configuration loaded ("C:\\Users\\ankit\\AppData\\Roaming\\display-switch\\display-switch.ini"): Configuration { usb_device: "1a40:0101", input_sources: InputSources { on_usb_connect: None, on_usb_disconnect: None }, monitor1: Some(PerMonitorConfiguration { monitor_id: "1", input_sources: InputSources { on_usb_connect: Some(Hdmi1(0x11)), on_usb_disconnect: Some(DisplayPort1(0xf)) } }), monitor2: Some(PerMonitorConfiguration { monitor_id: "2", input_sources: InputSources { on_usb_connect: Some(DisplayPort1(0xf)), on_usb_disconnect: Some(Hdmi1(0x11)) } }), monitor3: None, monitor4: None, monitor5: None, monitor6: None }
14:47:49 [INFO] Display 'Generic PnP Monitor' is currently set to Hdmi1(0x11)
14:47:50 [INFO] Display 'Generic PnP Monitor' is currently set to DisplayPort1(0xf)
14:47:50 [ERROR] Failed to get current input for display 'GP104-A/2147881090:SVideo': Ddc(InvalidChecksum)
14:47:50 [INFO] Display 'GP104-A/2147881089:Lvds' is currently set to DisplayPort1(0xf)
14:47:54 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05e3:0610"
14:47:54 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "04d9:a293"
14:47:54 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:c53f"
14:47:54 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0d8c:0014"
14:47:54 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "1a40:0101"
14:47:54 [INFO] Monitored device is ("1a40:0101") is disconnected
14:47:54 [INFO] Display 'Generic PnP Monitor' is not configured to switch on USB disconnect
14:47:54 [INFO] Display 'Generic PnP Monitor' is not configured to switch on USB disconnect
14:47:54 [DEBUG] (1) display_switch::display_control: Setting display 'GP104-A/2147881090:SVideo' to DisplayPort1(0xf)
14:47:54 [INFO] Display 'GP104-A/2147881090:SVideo' set to DisplayPort1(0xf)
14:47:54 [DEBUG] (1) display_switch::display_control: Setting display 'GP104-A/2147881089:Lvds' to DisplayPort1(0xf)
14:47:54 [INFO] Display 'GP104-A/2147881089:Lvds' set to DisplayPort1(0xf)
14:48:04 [DEBUG] (1) display_switch::app: Detected device change. Added device: "1a40:0101"
14:48:04 [INFO] Monitored device ("1a40:0101") is connected
14:48:04 [INFO] Display 'Generic PnP Monitor' is not configured to switch on USB connect
14:48:04 [INFO] Display 'Generic PnP Monitor' is not configured to switch on USB connect
14:48:04 [DEBUG] (1) display_switch::display_control: Setting display 'GP104-A/2147881090:SVideo' to Hdmi1(0x11)
14:48:04 [INFO] Display 'GP104-A/2147881090:SVideo' set to Hdmi1(0x11)
14:48:04 [DEBUG] (1) display_switch::display_control: Setting display 'GP104-A/2147881089:Lvds' to Hdmi1(0x11)
14:48:04 [INFO] Display 'GP104-A/2147881089:Lvds' set to Hdmi1(0x11)
14:48:07 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0000:0000"
14:48:07 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
14:48:08 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c53f"
14:48:08 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0d8c:0014"

I'm not sure why I'm getting the 14:47:50 [ERROR] Failed to get current input for display 'GP104-A/2147881090:SVideo': Ddc(InvalidChecksum) error either but my second uneducated guess is that it's the reason display-switch can't switch monitor state correctly on the primary monitor.

Any help would be greatly appreciated, I'd love to make display-switch my daily driver!

running external program on windows with spaces and parameter does not work

Hi,

I'm trying to run an external program called voicemeeter on usb_connect, I have put the following line in the configuration file:
on_usb_connect_execute = "C:\Program Files (x86)\VB\Voicemeeter\voicemeeter8.exe -R"

I've already tried different combinations of the string with double backslashes because the logfile was not showing backslahes with also adding a single or double backslash on the white space between "Program Files" and "(x86)" without success I always get in the log something like:
08:53:44 [ERROR] Error executing external command 'C:\Program Files (x86)\VB\Voicemeeter\voicemeeter8.exe -R': Das System kann die angegebene Datei nicht finden. (os error 2)

Which means "file not found", maybe I also have to separate the parameter "-R" from the program but how would the configuration file look then?

In the end I guess it's just a matter of putting correct string(s) to make it work, but even as a software developer with windows and linux knowledge I coudln't figure out the correct values.

Please provide the correct version here and maybe also update the readme.md so other don't have to try around and open an issue.

Thank you very much

Error on detected switch

tail ~/.local/share/display-switch/display-switch.log
13:10:05 [DEBUG] (1) display_switch::display_control: Setting display 'ACI ROG PG279Q #ASPdawSVcBzd' to Hdmi1(0x11)
13:10:05 [ERROR] Failed to set display 'ACI ROG PG279Q #ASPdawSVcBzd' to Hdmi1(0x11) (I2c(Os { code: 5, kind: Other, message: "Input/output error" }))
13:10:05 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0c45:7638"
13:10:18 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c087"
13:10:18 [INFO] Monitored device ("046d:c087") is connected
13:10:18 [DEBUG] (1) display_switch::display_control: Setting display 'AOC 2379H AFYG49A001301' to DisplayPort1(0xf)
13:10:18 [INFO] Display 'AOC 2379H AFYG49A001301' set to DisplayPort1(0xf)
13:10:18 [DEBUG] (1) display_switch::display_control: Setting display 'ACI ROG PG279Q #ASPdawSVcBzd' to DisplayPort1(0xf)
13:10:18 [ERROR] Failed to set display 'ACI ROG PG279Q #ASPdawSVcBzd' to DisplayPort1(0xf) (I2c(Os { code: 5, kind: Other, message: "Input/output error" }))
13:10:18 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0c45:7638"

My AOC monitor doesn't have a displayport connection and "succeeds" (maybe?)
My PG279Q does have DP/HDMI, however it gets an error on each switch. Can I provide any more info than the above?

Issues on macOS - Maybe M1 is to blame?

I'm on a MacBook Pro 14" (M1 Pro) so maybe these just aren't supported yet? I haven't been able to run it yet and I've encountered the following issues

  1. The pre-compiled binary was not executable so I had to make it executable manually with chmod (ie I couldn't just "right click and Open" as I was expecting)
  2. When running it from the terminal it can't seem to find the lsusb library.
    /usr/local/opt/libusb/lib/libusb-1.0.0.dylib Referenced from: /Users/robpneu/Downloads/display_switch Reason: tried: '/usr/local/opt/libusb/lib/libusb-1.0.0.dylib' (no such file), '/usr/local/lib/libusb-1.0.0.dylib' (no such file), '/usr/lib/libusb-1.0.0.dylib' (no such file)

Any ideas? I installed lsusb and libusb from brew, but no luck so far.

Complete Freeze on macOS 10.15.7 when monitors connected

Hi, when running display-switch 0.3.0 on macOS 10.15.7 and i have monitors connected via HDMI, my mac goes into a complete freeze and won't wake up anymore. Only unplugging the monitors and hard-rebooting it, solves the issue.

The logs have this to say:

05:56:08 [INFO] Configuration loaded ("/Users/chris/Library/Preferences/display-switch.ini"): Configuration { usb_device: "046d:c539", input_sources: InputSources { on_usb_connect: Some(Hdmi1(0x11)), on_usb_disconnect: None }, monitor1: None, monitor2: None, monitor3: None, monitor4: None, monitor5: None, monitor6: None }
05:56:08 [ERROR] Did not detect any DDC-compatible displays!
05:57:03 [DEBUG] (1) display_switch::app: Detected device change. Added device: "2109:0813"
05:57:04 [DEBUG] (1) display_switch::app: Detected device change. Added device: "2109:2813"
05:57:04 [DEBUG] (1) display_switch::app: Detected device change. Added device: "1a40:0101"
05:57:05 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
05:57:05 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
05:57:05 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
05:57:06 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c541"
05:57:06 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:1393"
05:57:06 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c539"
05:57:06 [INFO] Monitored device ("046d:c539") is connected
05:57:06 [DEBUG] (1) display_switch::display_control: Setting display 'ROG XG279Q' to Hdmi1(0x11)
05:57:06 [ERROR] Failed to set display 'ROG XG279Q' to Hdmi1(0x11) (Io(-1))
05:57:06 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:0892"
05:57:07 [DEBUG] (1) display_switch::app: Detected device change. Added device: "2109:d101"
05:57:09 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0b05:1919"
06:02:20 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05e3:0610"
06:02:20 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0b05:1919"
06:02:20 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:0892"
06:02:22 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
06:02:23 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:0892"
06:02:56 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0b05:1919"
06:04:44 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05e3:0610"
06:04:44 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0b05:1919"
06:04:44 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:0892"
06:04:45 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
06:04:46 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:0892"
06:04:59 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05e3:0610"
06:04:59 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:0892"
06:05:07 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
06:05:08 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0b05:1919"
06:05:08 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:0892"
06:05:24 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05e3:0610"
06:05:24 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0b05:1919"
06:05:24 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:0892"
06:05:25 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
06:05:25 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:0892"
06:05:43 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0b05:1919"
06:06:41 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05e3:0610"
06:06:41 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0b05:1919"
06:06:41 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:0892"
06:07:12 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
06:07:12 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0b05:1919"
06:07:13 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:0892"
06:07:30 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05e3:0610"
06:07:30 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0b05:1919"
06:07:30 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:0892"
06:07:30 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
06:07:31 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:0892"
06:07:34 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0b05:1919"
06:08:19 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05e3:0610"
06:08:19 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:0892"
06:08:19 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0b05:1919"
06:08:21 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
06:08:22 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:0892"
06:08:45 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0b05:1919"
06:09:12 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05e3:0610"
06:09:12 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0b05:1919"
06:09:12 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:0892"
06:09:13 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
06:09:14 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:0892"
06:09:29 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0b05:1919"
06:10:03 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05e3:0610"
06:10:03 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:0892"
06:10:03 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0b05:1919"
06:10:04 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05e3:0610"
06:10:05 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:0892"
06:10:06 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0b05:1919"

Struggling to configure

Hi everyone,

It feels like this is the perfect tool to help me manage my set up (one desktop, one laptop and two screens), but I'm struggling to get this configured correctly. I'll set the scene with the configuration.

Desktop: Connected to a 32" AOC monitor (DP) and a 24" Dell monitor (HDMI)
Laptop: Connected - via a USB-C dock - to the same monitors. The 32" is connected via HDMI and the 24" via DP.

What I'm trying to do is to check if 7844:6868 is connected (my mouse), then connect both monitors to the respective PCs, but getting to a bit of an impasse.

Here are my config files:
Laptop:

usb_device = "7844:6868"

[monitor1]
monitor_id = 
on_usb_connect = 0x12

[monitor2]
monitor_id = 
on_usb_connect = 0xf0f

When checking the log, I see the following output:

12:34:32 [INFO] Configuration loaded ("C:\\Users\\LHA8713\\AppData\\Roaming\\display-switch\\display-switch.ini"): Configuration { usb_device: "7844:6868", input_sources: InputSources { on_usb_connect: None, on_usb_disconnect: None }, monitor1: Some(PerMonitorConfiguration { monitor_id: "", input_sources: InputSources { on_usb_connect: Some(Hdmi1(0x11)), on_usb_disconnect: None } }), monitor2: Some(PerMonitorConfiguration { monitor_id: "", input_sources: InputSources { on_usb_connect: Some(DisplayPort1(0xf)), on_usb_disconnect: None } }), monitor3: None, monitor4: None, monitor5: None, monitor6: None }
12:34:32 [INFO] Display 'Generic PnP Monitor' is currently set to Hdmi2(0x12)
12:34:32 [INFO] Display 'Generic PnP Monitor' is currently set to Custom(0xf0f)

I've updated the config to use the raw values per the documentation - so 0x12 is the HDMI output, and 0xf0f is the Custom input (i.e. DisplayPort is what I think is safe to assume).

Switching looks OK too in the log too, although I'm not seeing a reference to 0xf0f (the 2nd monitor) - first oddity.

12:45:50 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:082d"
12:45:50 [DEBUG] (1) display_switch::app: Detected device change. Added device: "7844:6868"
12:45:50 [INFO] Monitored device ("7844:6868") is connected
12:45:50 [DEBUG] (1) display_switch::display_control: Setting display 'Generic PnP Monitor' to Hdmi2(0x12)
12:45:50 [INFO] Display 'Generic PnP Monitor' set to Hdmi2(0x12)
12:45:50 [DEBUG] (1) display_switch::display_control: Setting display 'Generic PnP Monitor' to Hdmi2(0x12)
12:45:50 [INFO] Display 'Generic PnP Monitor' set to Hdmi2(0x12)

Switching again (away) gives me this output:

12:47:55 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:c07d"
12:47:55 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:082d"
12:47:55 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "7844:6868"
12:47:55 [INFO] Monitored device is ("7844:6868") is disconnected
12:47:55 [INFO] Display 'Generic PnP Monitor' is not configured to switch on USB disconnect
12:47:55 [INFO] Display 'Generic PnP Monitor' is not configured to switch on USB disconnect
12:47:55 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:5411"

The desktop config is somewhat more problematic, I think.

The config looks like this:

usb_device = "7844:6868"

[monitor1]
monitor_id = 
on_usb_connect = 0xf

[monitor2]
monitor_id =
on_usb_connect = 0x110f

Initial output - which is a little concerning - looks like this:

12:40:39 [INFO] Configuration loaded ("C:\\Users\\user\\AppData\\Roaming\\display-switch\\display-switch.ini"): Configuration { usb_device: "7844:6868", input_sources: InputSources { on_usb_connect: None, on_usb_disconnect: None }, monitor1: Some(PerMonitorConfiguration { monitor_id: "", input_sources: InputSources { on_usb_connect: Some(DisplayPort1(0xf)), on_usb_disconnect: None } }), monitor2: Some(PerMonitorConfiguration { monitor_id: "", input_sources: InputSources { on_usb_connect: Some(Custom(0x110f)), on_usb_disconnect: None } }), monitor3: None, monitor4: None, monitor5: None, monitor6: None }
12:40:39 [INFO] Display 'Generic PnP Monitor' is currently set to DisplayPort1(0xf)
12:40:39 [INFO] Display 'Generic PnP Monitor' is currently set to Custom(0x1111)
12:40:39 [ERROR] Failed to get current input for display 'GP102-A/2147881091:SVideo': Ddc(InvalidChecksum)
12:40:39 [INFO] Display 'GP102-A/2147881094:Lvds' is currently set to DisplayPort1(0xf)

Finally, this is what happens when I switch to the desktop:

12:47:52 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:0411"
12:47:52 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:5411"
12:47:53 [DEBUG] (1) display_switch::app: Detected device change. Added device: "7844:6868"
12:47:53 [INFO] Monitored device ("7844:6868") is connected
12:47:53 [DEBUG] (1) display_switch::display_control: Setting display 'Generic PnP Monitor' to DisplayPort1(0xf)
12:47:53 [INFO] Display 'Generic PnP Monitor' set to DisplayPort1(0xf)
12:47:53 [DEBUG] (1) display_switch::display_control: Setting display 'Generic PnP Monitor' to DisplayPort1(0xf)
12:47:53 [INFO] Display 'Generic PnP Monitor' set to DisplayPort1(0xf)
12:47:53 [DEBUG] (1) display_switch::display_control: Setting display 'GP102-A/2147881091:SVideo' to DisplayPort1(0xf)
12:47:53 [INFO] Display 'GP102-A/2147881091:SVideo' set to DisplayPort1(0xf)
12:47:53 [DEBUG] (1) display_switch::display_control: Setting display 'GP102-A/2147881094:Lvds' to DisplayPort1(0xf)
12:47:53 [INFO] Display 'GP102-A/2147881094:Lvds' set to DisplayPort1(0xf)
12:47:53 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:082d"
12:47:53 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c07d"

And when I switch away from the desktop:

12:48:19 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0000:0000"
12:48:19 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:c07d"
12:48:19 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:5411"
12:48:19 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "7844:6868"
12:48:19 [INFO] Monitored device is ("7844:6868") is disconnected
12:48:19 [INFO] Display 'Generic PnP Monitor' is not configured to switch on USB disconnect
12:48:19 [INFO] Display 'Generic PnP Monitor' is not configured to switch on USB disconnect
12:48:19 [INFO] Display 'GP102-A/2147881091:SVideo' is not configured to switch on USB disconnect
12:48:19 [INFO] Display 'GP102-A/2147881094:Lvds' is not configured to switch on USB disconnect
12:48:19 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:0411"
12:48:19 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:082d" 

Now the real weird part is that the monitors alternate.

For example, if I switch my input to the desktop, then the 32" shows my desktop, while the 24" shows my laptop's second screen. If I switch inputs to the laptop - the 32" shows my laptop's main screen, while the 24" shows my desktop's second screen.

I can't work out why, but I suspect it's somehow related to the error on the desktop (failing to get the checksum for the display). I'm at my wits end - any input would be highly appreciated.

I'm using 0.3.0.

Any advice on Thunderbolt equipped display?

Any advice on connecting two (Thunderbolt USB-C connector equipped) computers (HP 830 G5 and 2020 Mac Mini) to a single display with two thunderbolt ports (LG 24MD4KL-B)?

Here's what I did but did not succeed with the instructions in README:

  1. Installed pyusb with python3 -m pip install pyusb

  2. With a mouse connected to the UGREEN hub's central port, I ran the following script to get vendor ID and product IDs

    #!/usr/bin/python
    import sys
    import usb.core
    # find USB devices
    dev = usb.core.find(find_all=True)
    # loop through devices, printing vendor and product ids in decimal and hex
    for cfg in dev:
      sys.stdout.write('Decimal VendorID=' + str(cfg.idVendor) + ' & ProductID=' + str(cfg.idProduct) + '\n')
      sys.stdout.write('Hexadecimal VendorID=' + hex(cfg.idVendor) + ' & ProductID=' + hex(cfg.idProduct) + '\n\n')

    For this, I got the following output for my barebones Logitech M90 mouse:

     Decimal VendorID=1133 & ProductID=49271
     Hexadecimal VendorID=0x46d & ProductID=0xc077
    
  3. Followed the rest of the process described in the README.

Support monitor selection

I have a setup with 3 monitors, and i want to be able to only switch 1 monitors input using this tool. It seems to me this could be a vaild use case for others too, and therefor it would be nice if you could for example whitelilst the specfic monitors to switch in the configuration file.

Unable to start service on Linux (Ubuntu 20.04)

I'm working on getting this to run between Windows 10 and Ubuntu 20.04 but I can't get the service to start and I can't seem to figure out why. when I run "sudo systemctl status display-switch.service" and I have the display-switch.ini in the proper directory with Hdmi is my Ubuntu and DisplayPort is Windows. What part am I missing or doing wrong?

usb_device = "1A40:0101"
on_usb_connect = "Hdmi1"
on_usb_disconnect = "DisplayPort1"
โ— display-switch.service - Display switch via USB switch
     Loaded: loaded (/etc/systemd/system/display-switch.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Mon 2021-03-15 01:26:44 EDT; 1s ago
    Process: 4777 ExecStart=/usr/local/bin/display_switch (code=exited, status=1/FAILURE)
   Main PID: 4777 (code=exited, status=1/FAILURE)

Mar 15 01:26:44 Blade systemd[1]: display-switch.service: Scheduled restart job, restart counter is at 5.
Mar 15 01:26:44 Blade systemd[1]: Stopped Display switch via USB switch.
Mar 15 01:26:44 Blade systemd[1]: display-switch.service: Start request repeated too quickly.
Mar 15 01:26:44 Blade systemd[1]: display-switch.service: Failed with result 'exit-code'.
Mar 15 01:26:44 Blade systemd[1]: Failed to start Display switch via USB switch.

cannot find Windows binary

Hi,

I'm not able to find the Windows binary anymore. It looks like the artifacts of the last build have expired, so the (Windows) binary is no longer available. Or am I looking in the wrong place?

image

Support for raw InputSource values

Currently the values supported are:

   DisplayPort1 = 0x0f,
   DisplayPort2 = 0x10,
   Hdmi1 = 0x11,
   Hdmi2 = 0x12,

My monitor seems to have HDMI1 as 0x05. Adding support for raw values would probably do the trick.

ParseIntError InvalidDigit

Hi,

Thanks for building this tool, it is exactly what I've been looking for!

I am running this on a MacBook Pro (15-inch, 2018) (Catalina 10.15.7 (19H2)). I have two identical monitors and I made the following config:

usb_device = "2341:0036"
  
[monitor1]
monitor_id = "dell u2415 s/n 0KVDN9C33MPL"
on_usb_connect = "mDisplayPort1"
on_usb_disconnect = "Hdmi2"

[monitor2]
monitor_id = "dell u2415 s/b 0KVDN01I07RU"
on_usb_connect = "hdmi1"
on_usb_disconnect = "hdmi2"

Bus 020 Device 044: ID 2341:0036 2341 Arduino Leonardo is the ID of the keyboard I am connecting. Could someone help me debug why I'm getting the following error:


Error: failed to load configuration

Caused by:
    ParseIntError { kind: InvalidDigit }

Linux support?

This is an awesome project! Do you have any plans for Linux support?

windows USBView for device detection

Might be worth to add USBView for Windows to the possible tools to find your USB device.
Helped me to view the USB hierarchy and find out that the (authors) USB Switch itself disconnects on switch. Thus I can just detect the switch itself instead of my mouse.

Confusing error on invalid `on_usb_connect` setting

Thanks for this tool, works nicely! One minor thing I encountered while setting it up: if on_usb_connect = "Hdmi1" is set to an invalid value (e.g in my case I guessed "Dp1" before noticing it should be "DisplayPort1"), the error is unhelpful in working out what the cause is:

$ cargo run --
[...]
Error: failed to load configuration

Caused by:
    ParseIntError { kind: InvalidDigit }

This should at least mention the configuration option at fault, and ideally maybe give a list of the available options?

Run a custom external command on input switch

First off - thank you for this amazing tool! I use it everyday to switch between my work and personal computers and it's such a clever and practical solution.

One enhancement I'd like to propose is to add the ability to run a custom external command after the input switches to or away from the current device. In my particular use case, I'd use it to reconfigure mouse and keyboard sharing via Barrier. But I can imagine other use cases like locking the screen, putting the computer to sleep, etc.

Maybe something like

on_usb_connect = "Hdmi1"
on_usb_connect_run_command = "echo 'Connected!'"

Thanks!

Please provide binaries

Thanks so much for this amazing software. Would it be an enormous hassle to provide binaries, I wonder?

lexical-core >=0.7.5 required to build on Alpine Linux

I'm running into the issue described here when trying to build display-switch on Alpine: Alexhuszagh/rust-lexical#55

error[E0277]: cannot subtract `usize` from `u32`
    --> /home/clayton/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:2065:25
     |
2065 |     let rs = Limb::BITS - s;
     |                         ^ no implementation for `u32 - usize`

The fix for this is apparently in lexical-core 0.7.5, tested locally and was able to build display-switch after setting lexical-core to 0.7.5 in Cargo.lock. Could you bump the version used in this project?

Ack! No DDC/CI support on Odyssey G9!

Oh, I am sad.

It's unfair reporting this as an 'issue' with display-switch...

I got an early Christmas present: a LC29G95TSSUXEN monitor. It's great...with one exception: it doesn't seem to support DDC/CI.

From my MacBook, using ddcctl, I get this sort of thing:
$ ./ddcctl -d 1 -i 18
D: NSScreen #190590103 (5120x1440 0ยฐ) 109.00 DPI
I: found 1 external display
I: polling display 1's EDID
I: got edid.name: LC49G95T
I: got edid.serial: H4ZN901744
D: action: i: 18
D: setting VCP control #96 => 18

And then nothing happens (This happens with the display number (the -ii parm) from 1..18.)

In display_switch, I get:
15:30:53 [ERROR] Failed to get current input for display '0'
15:31:03 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:5411"
15:31:03 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:1006"
15:31:03 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:0221"
15:31:03 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:c52f"
15:31:03 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:0411"
15:31:05 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:0411"
15:31:05 [INFO] Detected device we're looking for "0bda:0411"
15:31:05 [INFO] Display '0' set to 0xf
15:31:05 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:5411"
15:31:06 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:1006"
15:31:06 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c52f"
15:31:07 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:0221"
15:31:12 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:5411"
15:31:12 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:1006"
15:31:12 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "046d:c52f"
15:31:12 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "05ac:0221"
15:31:12 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:0411"
15:31:14 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:0411"
15:31:14 [INFO] Detected device we're looking for "0bda:0411"
15:31:14 [INFO] Display '0' set to 0xf
15:31:14 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:5411"
15:31:14 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:1006"
15:31:15 [DEBUG] (1) display_switch::app: Detected device change. Added device: "046d:c52f"
15:31:15 [DEBUG] (1) display_switch::app: Detected device change. Added device: "05ac:0221"

So you can see me switching 4 times here.

That's me fairly well out of the switching game, I'm afraid, unless someone can come up with a way to shake this monitor into submission, or have an alternative control scheme.

So sad.

Support DPMS as alternative to DDC/CI

My display doesn't accept DDC/CI requests from inactive inputs:

$ # Input is active:
$ ddcutil --bus=7 getvcp 60
VCP code 0x60 (Input Source                  ): DVI-1 (sl=0x03)

$ # input is inactive:
$ ddcutil --bus=7 getvcp 60
DDC communication failed for monitor on I2C bus /dev/i2c-7

This means that display-switch can change to a different input, but it can't change back.

I found a reference suggesting that this could be a common limitation.

I wrote a script that instead uses DPMS to control display standby. If a system on one input enables standby, and another disables it, the display switches to the only active input.

display-switch could implement this DPMS approach to support monitors that limit DDC/CI to active inputs.

Failed to get current input

Monitor: Dell U2415 connected to my Macbook Pro 15 2017 via a mini display port -> usb-c adapter

When I launch display-switch, it immediately prints the following lines:

18:02:42 [ERROR] Failed to get current input for display '0'
18:02:42 [ERROR] Failed to get current input for display '1'

See Update Below It's also not clear to me which monitor_input value I should use for mini display port (I've tried them all, but none of them work, I get 18:02:46 [ERROR] Failed to set display '1' to 0xf), but I don't think it currently matters since it can't seem to talk to my monitor. I know this monitor supports DDC/CI because I created some shortcuts in windows using dell display manager and can switch the inputs from there, so maybe it's the dongle getting in the way?

I have a mini-dp to display port adapter coming soon that I'm going to plug into the dock I have connected to the mbp, so I'll give it a shot once that gets here and see how I fare, but if you have any advice I'd appreciate it! Love the idea!

Update: I was able to use ddcctl to verify that that works (and I will use DisplayPort2 to switch to mini display port). So not sure why display-switch can't read the current monitor input, maybe because of the dongle?

Update 2: Removing the dongle and going from my dock to the monitor via DisplayPort didn't solve the problem either :(

More robust input switching

To achieve more robust switching, and to not flicker the monitor uselessly, the app should do something like this, when input switch if required:

  • Get the current inputs (with several retries).
  • If already on the desired input, do nothing.
  • If not on the desired input, or if the current state cannot be determined, do the input change.
  • Try to read the current input, and re-try #3 if we are still not on the right input (but not retry if the read command failed in general, because some monitors could be set to a new input but could not report the input back).

Unfortunately, the DDC implementation varies between different monitors and is often buggy. The write command also does not have meaningful feedback (we don't know if it succeeded or not), and for some monitors, we do need to retry to reliably switch the inputs.

Support different inputs on different monitors

I have two different monitors, and my computers uses different inputs on each. Would it be possible to somehow map the monitor to the desired input in the config file? Something like:

acer123_monitor_input="DisplayPort1"
dell567_monitor_input="Hdmi1"

Application crashes on switch button press

The application crashes when pressing the button on my usb switch
Is there any way to run in foreground, to maybe get a reason for the crash? Windows eventlog is not very helpful.

Did not detect any DDC-compatible displays

First of all, I want to say how great this project is, and I'm really excited just at the idea of getting it working!

Steps to reproduce:

  • running Ubuntu 20.10 with NVidia 3070 (but also happened with an AMD 5700XT), plugged in to a Dell s3220dgf and an Acer XF270HU using DisplayPort cables. Using the Amazon recommended, generic USB 3.0 KVM. Second machine is an HP laptop connected by HDMI, but the issues looks to happen well before that becomes involved.
  • write config file to ~/.config/display-switch/display-switch.ini:
usb_device = "0bda:5411"


[monitor1]
monitor_id = "27"
on_usb_connect = "DisplayPort2"
on_usb_disconnect = "Hdmi1"

[monitor2]
monitor_id = "3220"
on_usb_connect = "DisplayPort2"
on_usb_disconnect = "Hdmi1"
  • build the program per the instructions; run it from the terminal

Expected outcome: pressing the button on the KVM switch when the monitors are set to the laptop causes the Ubuntu machine to detect the USB device change and switch from the HDMI input to the DisplayPort input

Actual outcome: the log (~/.local/share/display-switch/display-switch.log) seems to say that it gets the config, but that the monitors aren't DDC-compatible. The research I did online seemed to say that these monitors support DDC, but I also saw that sometimes monitors only do it over certain ports.

21:11:34 [INFO] Configuration loaded...
21:11:34 [ERROR] Did not detect any DDC-compatible displays!
...
21:12:28 [INFO] Monitored device is ("0bda:5411") is disconnected
21:12:28 [ERROR] Did not detect any DDC-compatible displays!
...
21:13:00 [INFO] Monitored device ("0bda:5411") is connected
21:13:00 [ERROR] Did not detect any DDC-compatible displays!

Provide pre-built binaries/installers

Hi, first of all, great project! Thanks a lot for creating it, really makes lives easier ๐Ÿ˜€

I have just "installed" the app on one of my Windows machines, and I was very surprised to see that it's actually required to build it from source to make it work. OK then, so shall be done. However, it seems that getting rust to work, at least on Windows, is not such a trivial task...
I failed on my first try to build the app because supposedly I was missing MSVC build tools. I had Visual Studio installed already, so I went to install the 2019 C++ build tools for x86/64 from the VS Installer, just to find out that I was still failing the build, even after a restart to Windows. Further exploration on the internet has discovered that there's no other option but to install both the build tools and the entire Win SDK, as well as some additional components. All of that sums up closely to ~5GB of packages, which I surely don't need, only to be able to build this app from source. Ah, and did I mention that it took an entire hour? โ˜น

One characteristic of good software is that it's easily deployable. Unfortunately, I can't say that about this one.
I think it'd be really nice to upload pre-built binaries for all platforms (although I guess Windows users would benefit the most) as part of a release, possibly automated entirely by a CI/CD pipeline.
I don't know how Rust works regarding runtime, i.e. whether it matters what toolchain the app has been built with, but if that's a problem, an array of all possible binaries seems like an option to me.
With that being said, running the app might not be possible without an already-installed VC runtime, and that's where an installer/bundler comes in.

I'm no expert in this field myself so I can't promise anything about implementing it, I'm just opening this issue as a feature request for now, open for discussion before anything is actually done.

Device ID must be lowercase hex

I just tried this on Windows and wondered why it wasn't working, even though I could see in the logs it was detecting removal/add of the correct USB device. Then I happened to notice that the device ID was reported in lowercase in the logs - I updated my .ini file, and... great success!

I think Windows Device Manager always reports device IDs in uppercase hex, so it would be great if display-switch wasn't fussy about the case.

Log file created, but is empty.

Hello,
This looks like a great tool to switch between my work computer and PC, while saving some money. However, I'm having some trouble with setup.

I am on windows on both systems, with 2 monitors and a USB switch as my "USB device".
Given a 2-monitor setup and USB hub as my device, I have created the following config file (all the way at bottom).
When I run the display_switch.ex (copied to AppData/roaming), a log file is created. However, this file is empty. Since I have no feedback, it's hard to know exactly where I am messing up.

Any advice? Thanks so much!

display-switch.ini:

usb_device = "1A40:0101"

[monitor1]
monitor_id = "GSM7706"
on_usb_connect = "Hdmi1"

[monitor2]
monitor_id = "LEN61E6"
on_usb_connect = "DisplayPort1"

Instructions on finding USB device ID

It will not be obvious to some how to find the USB device ID, so it would be great to add a section to the readme for this. Would you accept a PR for this? (I can do it for Windows, not MacOS tho)

Support multiple configuration file locations

The app should support multiple configuration file locations:

Linux

  • Per-user config file ~/.config/display-switch/display-switch.ini
  • Global config file /etc/display-switch.ini

MacOS

  • Per user config file ~/Library/Preferences/display-switch.ini
  • Global config file /Library/Preferences/display-switch.ini

Windows

  • Per user config file same-as-now
  • Global config file TBD

Should try to load per-user config file, and fall back to a global config file.

Kernel panic when switching USB on 2015 MBP

Environment

Item Value
display-switch version 0.3.0
OS macOS Big Sur Version 11.0.1 (20B29)
Hardware MacBook Pro (Retina, 15-inch, Mid 2015)

display-switch configuration file:

usb_device = "04xx:xx2b"
on_usb_connect = "DisplayPort2"
on_usb_disconnect = "DisplayPort1"

Note: the MBP is connected to one external display with the lid closed.

Steps to reproduce

  1. Start display-switch.
  2. Click the USB switch button.

Logs

App log is not recorded since the screen is frozen. The only line is detected USB change.

Kernel dump

panic(cpu 4 caller 0xffffff8017553a13): userspace watchdog timeout: no successful checkins from com.apple.WindowServer in 120 seconds
service: com.apple.logd, total successful checkins since load (2340 seconds ago): 235, last successful checkin: 0 seconds ago
service: com.apple.WindowServer, total successful checkins since load (2310 seconds ago): 219, last successful checkin: 120 seconds ago

Backtrace (CPU 4), Frame : Return Address
0xffffffb0b29bb670 : 0xffffff80142bc66d 
0xffffffb0b29bb6c0 : 0xffffff80143ff073 
0xffffffb0b29bb700 : 0xffffff80143ef6aa 
0xffffffb0b29bb750 : 0xffffff8014261a2f 
0xffffffb0b29bb770 : 0xffffff80142bbf0d 
0xffffffb0b29bb890 : 0xffffff80142bc1f8 
0xffffffb0b29bb900 : 0xffffff8014abee84 
0xffffffb0b29bb970 : 0xffffff8017553a13 
0xffffffb0b29bb980 : 0xffffff80175536ba 
0xffffffb0b29bb9a0 : 0xffffff8014a460ee 
0xffffffb0b29bb9f0 : 0xffffff8017552b0a 
0xffffffb0b29bbb20 : 0xffffff8014a502bb 
0xffffffb0b29bbc80 : 0xffffff80143aaa61 
0xffffffb0b29bbd90 : 0xffffff80142c1d77 
0xffffffb0b29bbe00 : 0xffffff80142985d5 
0xffffffb0b29bbe60 : 0xffffff80142afb82 
0xffffffb0b29bbef0 : 0xffffff80143d3823 
0xffffffb0b29bbfa0 : 0xffffff8014262216 
      Kernel Extensions in backtrace:
         com.apple.driver.watchdog(1.0)[7948A279-A8B8-3650-AFBF-B1E3EB68942A]@0xffffff8017552000->0xffffff8017553fff

Process name corresponding to current thread: watchdogd

Mac OS version:
20B29

Kernel version:
Darwin Kernel Version 20.1.0: Sat Oct 31 00:07:11 PDT 2020; root:xnu-7195.50.7~2/RELEASE_X86_64
Kernel UUID: 84C6DC45-6B02-335F-9439-5D2A9BC385A4
KernelCache slide: 0x0000000014000000
KernelCache base:  0xffffff8014200000
Kernel slide:      0x0000000014010000
Kernel text base:  0xffffff8014210000
__HIB  text base: 0xffffff8014100000
System model name: MacBookPro11,4 (Mac-06F11FD93F0323C5)
System shutdown begun: NO
Panic diags file available: YES (0x0)
Hibernation exit count: 0

System uptime in nanoseconds: 2352507391524
Last Sleep:           absolute           base_tsc          base_nano
  Uptime  : 0x00000223bc5e13f8
  Sleep   : 0x0000000000000000 0x0000000000000000 0x0000000000000000
  Wake    : 0x0000000000000000 0x00000007240220b8 0x0000000000000000
last started kext at 2219987301911: >usb.cdc	5.0.0 (addr 0xffffff80159d8000, size 8192)
last stopped kext at 2285283821487: >usb.cdc	5.0.0 (addr 0xffffff80159d8000, size 8192)
loaded kexts:
@filesystems.smbfs	3.4.1
>AudioAUUC	1.70
>AGPM	119
>!APlatformEnabler	2.7.0d0
>X86PlatformShim	1.0.0
@filesystems.autofs	3.0
@fileutil	20.036.15
>!AGraphicsDevicePolicy	6.1.27
>!AHDA	283.15
@AGDCPluginDisplayMetrics	6.1.27
>!AUpstreamUserClient	3.6.8
>pmtelemetry	1
>LuaHardwareAccess	1.0.16
|IOUserEthernet	1.0.1
|IO!BSerialManager	8.0.1f5
@Dont_Steal_Mac_OS_X	7.0.0
>!AHV	1
>!ADiskImages2	1
>!AThunderboltIP	4.0.3
>!A!ISlowAdaptiveClocking	4.0.0
>!A!IHD5000Graphics	16.0.0
|Broadcom!B20703USBTransport	8.0.1f5
>!ABacklight	180.3
>eficheck	1
>!ASMCLMU	212
>!ALPC	3.1
>!AMCCSControl	1.14
>!A!IFramebufferAzul	16.0.0
>!ACameraInterface	7.6.0
>!ATopCaseHIDEventDriver	4000.27
>!UTopCaseDriver	4000.27
>!UCardReader	511.40.9
@filesystems.apfs	1677.50.1
>AirPort.BrcmNIC	1400.1.1
>!AAHCIPort	346
@filesystems.tmpfs	1
@filesystems.hfs.kext	556.41.1
@BootCache	40
@!AFSCompression.!AFSCompressionTypeZlib	1.0.0
@!AFSCompression.!AFSCompressionTypeDataless	1.0.0d1
@private.KextAudit	1.0
>!ASmartBatteryManager	161.0.0
>!AACPIButtons	6.1
>!ARTC	2.0
>!AHPET	1.8
>!ASMBIOS	2.1
>!AACPIEC	6.1
>!AAPIC	1.7
@!ASystemPolicy	2.0.0
@nke.applicationfirewall	310
|IOKitRegistryCompatibility	1
|EndpointSecurity	1
@kext.triggers	1.0
>DspFuncLib	283.15
@kext.OSvKernDSPLib	529
|IOSerial!F	11
|IOAVB!F	900.12
@plugin.IOgPTPPlugin	900.11
|IOEthernetAVB!C	1.1.0
@!AGPUWrangler	6.1.27
>!AGraphicsControl	6.1.27
|IOSlowAdaptiveClocking!F	1.0.0
|Broadcom!BHost!CUSBTransport	8.0.1f5
|IO!BHost!CUSBTransport	8.0.1f5
|IO!BHost!CTransport	8.0.1f5
>!ABacklightExpert	1.1.0
|IONDRVSupport	585
>!AHDA!C	283.15
|IOHDA!F	283.15
>!ASMBus!C	1.0.18d1
|IOAccelerator!F2	439.35.4
@!AGraphicsDeviceControl	6.1.27
|IOGraphics!F	585
>!UAudio	401.4
|IOAudio!F	300.6.1
@vecLib.kext	1.2.0
>X86PlatformPlugin	1.0.0
>IOPlatformPlugin!F	6.0.0d8
>!AHS!BDriver	4000.27
>IO!BHIDDriver	8.0.1f5
>!AActuatorDriver	4400.28
>!AMultitouchDriver	4400.28
>!AInputDeviceSupport	4400.35
>!AHIDKeyboard	222
>usb.IOUSBHostHIDDevice	1.2
>usb.!UHub	1.2
>usb.networking	5.0.0
>usb.!UHostCompositeDevice	1.2
>!AThunderboltDPInAdapter	8.1.4
>!AThunderboltDPAdapter!F	8.1.4
>!AThunderboltPCIDownAdapter	4.1.1
|IOAHCIBlock!S	332
>!AThunderboltNHI	7.2.8
|IOThunderbolt!F	9.3.2
|IO80211!F	1200.12.2b1
>corecapture	1.0.4
|IOAHCI!F	294
>usb.!UXHCIPCI	1.2
>usb.!UXHCI	1.2
>!ABSDKextStarter	3
|IOSurface	289.3
|IOSkywalk!F	1
>mDNSOffloadUserClient	1.0.1b8
@filesystems.hfs.encodings.kext	1
|IOUSB!F	900.4.2
>!AEFINVRAM	2.1
>!AEFIRuntime	2.1
|IOSMBus!F	1.1
|IOHID!F	2.0.0
$!AImage4	3.0.0
|IOTimeSync!F	900.11
|IONetworking!F	3.4
>DiskImages	493.0.0
|IO!B!F	8.0.1f5
|IOReport!F	47
|IO!BPacketLogger	8.0.1f5
$quarantine	4
$sandbox	300.0
@kext.!AMatch	1.0.0d1
|CoreAnalytics!F	1
>!ASSE	1.0
>!AKeyStore	2
>!UTDM	511.40.9
|IOUSBMass!SDriver	184.40.6
|IOSCSIBlockCommandsDevice	436.40.6
|IO!S!F	2.1
|IOSCSIArchitectureModel!F	436.40.6
>!AMobileFileIntegrity	1.0.5
@kext.CoreTrust	1
>!AFDEKeyStore	28.30
>!AEffaceable!S	1.0
>!ACredentialManager	1.0
>KernelRelayHost	1
|IOUSBHost!F	1.2
>!UHostMergeProperties	1.2
>usb.!UCommon	1.0
>!ABusPower!C	1.0
>!ASEPManager	1.0.1
>IOSlaveProcessor	1
>!AACPIPlatform	6.1
>!ASMC	3.1.9
|IOPCI!F	2.9
|IOACPI!F	1.4
>watchdog	1
@kec.pthread	1
@kec.corecrypto	1.0
@kec.Libm	1

Identify USB Devices Beyond Vendor/Product IDs

Before I endeavor on potentially coding this myself (because I kind of want an excuse to learn Rust), I want to sanity check the following enhancement request.

In the non-Windows source, I noticed that the USB device matching ultimately uses rusb::DeviceDescriptor insteadofrusb::Device. Thus, fields like Device.bus_numberandDevice.addresscannot be matched upon. The callback receivesrusb::Device, so I wonder if display_switchmatching criteria could be expanded to also match uponrusb::Devicelike bus/address/port. This would enable thedisplay_switch` instance on my Ubuntu host to detect a constant set of USB peripherals hooked into a single USB switch relocating from the "Ubuntu host" USB port to another, the "Windows 10 VM host" port.

I haven't deeply checked whether or not the Windows-specific display_switch implementation can support additional matching criteria. (A quick read of the Windows code tells me that the code compares a set of vendor/product strings before and after a WM_DEVICECHANGE event, so I'm guessing my enhancement might have to be libusb specific.) Such functionality would still be awesome for libusb-supported hosts.

Troubleshooting help

Hi there!

When I came across your blog post I was happily surprised to find that I already had the exact usb switch you are using. After you added the CI build artifacts I decided to give this a go, but am running into some issues on MacOS.

For one, I don't see anything in the directory you mention where the logs should be. I even manually created the log directory, just in case. I do see display_switch in activity monitor and everything suggests it is in fact running when I log in.

The second issue is that when I run the program manually in order to see the output, it clearly shows my keyboard (the device on which to switch) being connected. I double checked the address and that looks good too. It shows that it tries to change monitors to the correct input... but nothing happens. I tried various input sources just to make sure, but none of them have any effect on the monitor itself. What could be the cause of this?

The only thing I could think of was some sort of compatibility issue. I'm on an Apple MBPr, with USB-C. I have a USB-C "dongle" that has classic USB ports as well as a hdmi port. Connected to that dongle are both the usb switch and the screens.

I understand you probably don't have the time to really help me debug this, but any directions you can think of would be much appreciated.

Thanks!

"Generic PnP Monitor" Failing Input Switching on Windows 10 VM

I use a 4-port USB hub ("25a7:fa70") with the following setup:

  • USB-HUB-1: Ubuntu Host on GPU-0 on Monitor1 Hdmi1
    • Motherboard USB is NOT passed through.
  • USB-HUB-2: Windows 10 VM on GPU-1 on Monitor1 DisplayPort1
    • GPU-1 is passed through from Ubuntu host.
    • USB PCIe Card is also passed through from Ubuntu host.

display-switch running on Ubuntu successfully detects Monitor1 and switches to Hdmi1 when USB device "25a7:fa70" connects. display-switch running on Windows 10 VM also detects "25a7:fa70" connecting but fails to switch to DisplayPort1. As a workaround, I'm using on_usb_disconnect on my Ubuntu host to switch the display between host and VM but this has obvious limitations for connecting my USB hub ports to other computers sharing Monitor1.

On Windows 10, Monitor1 is detected as two devices: Generic PnP Monitor and GA102-A/2147881091:Lvds (Googling for "GA102" suggests a relationship to my Nvidia GPU-1), but display-switch cannot switch Monitor1's input via either detected device. I tried the following display-switch.ini:

usb_device = "25a7:fa70"
on_usb_connect = "DisplayPort1"

[monitor1]
monitor_id = "GA102"
on_usb_connect = "DisplayPort1"

[monitor2]
monitor_id = "Generic"
on_usb_connect = "DisplayPort1"

I can switch using DDC/DI using winddcutil, so that makes me think that changing display-switch could be adjusted.

Windows 10 display-switch logs: https://gist.github.com/sl33nyc/f21f96e5d02d5831b908f48c8866bc49

Failed to set display 'Generic PnP Monitor' to Hdmi1(0x11)

Let me start by just saying how great this project is, I'm really eager to get it up and running!

Setup:

  • Running Windows 10 PC with Nvidia GTX 1080 plugged into a Dell S2716DG Display Port. Using USB 3.0 KVM made by IOGEAR. The second machine is an HP laptop connected by HDMI (I'm currently only running the display_switch.exe on my PC).
  • The contents of my config file C:\Users\avery\AppData\display-switch\display-switch.ini
usb_device = "1B1C:1B3E"
on_usb_connect = "DisplayPort1"
on_usb_disconnect = "Hdmi1"
  • Built the program as specified in the README; run it from the cmd line.

Expected outcome: pressing the KVM button toggles the monitor input between PC and laptop display.

Actual outcome: There is output in the log (C:\Users\avery\AppData\Local\display-switch\display-switch.log)

01:42:55 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "1b1c:1b3e"
01:42:55 [INFO] Monitored device is ("1b1c:1b3e") is disconnected
01:42:55 [DEBUG] (1) display_switch::display_control: Setting display 'Generic PnP Monitor' to Hdmi1(0x11)
01:42:55 [ERROR] Failed to set display 'Generic PnP Monitor' to Hdmi1(0x11) (Os { code: -1071241854, kind: Other, message: "An error occurred while transmitting data to the device on the I2C bus." })
01:42:55 [DEBUG] (1) display_switch::display_control: Setting display 'GP104-A/2147881088:Lvds' to Hdmi1(0x11)
01:42:55 [ERROR] Failed to set display 'GP104-A/2147881088:Lvds' to Hdmi1(0x11) (I2c(Error))
01:42:55 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "1b1c:1b13"
01:42:55 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0bda:5411"
01:42:58 [DEBUG] (1) display_switch::app: Detected device change. Removed device: "0000:0000"
01:43:05 [DEBUG] (1) display_switch::app: Detected device change. Added device: "0bda:5411"
01:43:06 [DEBUG] (1) display_switch::app: Detected device change. Added device: "1b1c:1b13"
01:43:06 [DEBUG] (1) display_switch::app: Detected device change. Added device: "1b1c:1b3e"
01:43:06 [INFO] Monitored device ("1b1c:1b3e") is connected
01:43:06 [DEBUG] (1) display_switch::display_control: Setting display 'Generic PnP Monitor' to DisplayPort1(0xf)
01:43:06 [ERROR] Failed to set display 'Generic PnP Monitor' to DisplayPort1(0xf) (Os { code: -1071241854, kind: Other, message: "An error occurred while transmitting data to the device on the I2C bus." })
01:43:06 [DEBUG] (1) display_switch::display_control: Setting display 'GP104-A/2147881088:Lvds' to DisplayPort1(0xf)
01:43:06 [ERROR] Failed to set display 'GP104-A/2147881088:Lvds' to DisplayPort1(0xf) (I2c(Error))

readme could describe how to find out monitor IDs

The readme documents how to support multiple monitors by adding config file sections with 'monitor_id' specifications to distinguish the different monitors. However, it doesn't describe how to find out what your monitor's monitor ID is so that you can set the config value appropriately.

If this is easy to do with existing command line tools, the readme could just say how to do that, as it does for USB IDs. If it's difficult, maybe display_switch could have a command line option for "don't do anything, just print all the IDs for all connected monitors" (since it seems to already have the code for "enumerate all the connected displays and find their ID string").

failed to load configuration

Hello, thanks for putting the time into this project, it is the simplest setup I've seen for this purpose.

I'm having issues starting the service: even if I have theese config files set up:
$cat ~/.config/display-switch/display-switch.ini

usb_device = "04d9:a0cd"
monitor_id = "ViewSonic"
on_usb_connect = "DisplayPort1"
on_usb_disconnect ="Hdmi1"
on_usb_connect_execute = "echo connected"
on_usb_disconnect_execute = "echo disconnected"

$ cat /etc/display-switch.ini

usb_device = "04d9:a0cd"
monitor_id = "ViewSonic"
on_usb_connect = "DisplayPort1"
on_usb_disconnect ="Hdmi1"
on_usb_connect_execute = "echo connected"
on_usb_disconnect_execute = "echo disconnected"

I get this error:

Dec 13 18:35:43 Hoggrs-endevour display_switch[94911]: Error: failed to load configuration
Dec 13 18:35:43 Hoggrs-endevour display_switch[94911]: Caused by:
Dec 13 18:35:43 Hoggrs-endevour display_switch[94911]:     missing field `usb_device`
Dec 13 18:35:43 Hoggrs-endevour systemd[1]: display_switch.service: Main process exited, code=exited, status=1/FAILURE
Dec 13 18:35:43 Hoggrs-endevour systemd[1]: display_switch.service: Failed with result 'exit-code'.

Retry if a display is not found

I use display-switch to workaround an issue where MacOS sometimes does not wake-up its external display when switching between a Macbook and Linux desktop via a KVM.

Macbook (closed lid) -
                       \
                         -->  KVM  -->  External display on DisplayPort1
                       /
Linux desktop --------

I have configured display-switch on my Macbook to monitor a USB device that is connected to the KVM and to send a DDC input-switch command to my monitor whenever the USB device is connected. Although, the monitor is always connected to DisplayPort1 (no other video cables are connected), the input-switch command (or perhaps a wake-up command is also sent?) has the side-effect of waking the monitor up, which solves the wake-up flakiness issue I was experiencing.

This usually works:

19:27:26 [INFO] Monitored device ("14b0:011e") is connected
19:27:28 [DEBUG] (1) display_switch::display_control: Setting display 'DELL U3417W' to DisplayPort1(0xf)

But sometimes, due I think to timing of the USB detection and KVM port switching, the monitor is not detected:

15:00:26 [INFO] Monitored device ("14b0:011e") is connected
15:00:27 [ERROR] Did not detect any DDC-compatible displays!

I believe that this issue could be worked around by introducing a retry mechanism. Perhaps something with a slight delay - even a fixed 2 second sleep before retrying would probably be sufficient.

Failed to get current input for display (Support for DVI monitors)

I'm trying to get this working with a Dell T2414H monitor hooked up by way of DP and DVI. I attempted to add DVI as a supported enum values, plus the raw value for DVI (0x03). In both cases, I get the following error.

19:25:10 [INFO] Display 'Generic PnP Monitor' #0 is currently set to 0x3
19:25:11 [INFO] Display 'Generic PnP Monitor' #1 is currently set to 0x3
19:25:11 [ERROR] Failed to get current input for display 'GP104-A/2147881091:Hdmi' #2: Ddc(InvalidChecksum)
19:25:11 [ERROR] Failed to get current input for display 'GP104-A/2147881092:Lvds' #3: Ddc(InvalidChecksum)

I'm not sure if this is an issue in display-switch or elsewhere.

Note - I can use other DDC based programs, so I don't think it's a hardware/supportability issue.

Crash on Startup: Cannot initialize InputSource from invalid String

Reproduce/Error

โžœ  bin pwd
/usr/local/bin
โžœ  bin ./display_switch
2020-09-07 13:23:21.912 Initializing
Fatal error: Error raised at top level: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "monitorInput", intValue: nil)], debugDescription: "Cannot initialize InputSource from invalid String value DisplayPort-1", underlyingError: nil)): file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/public/core/ErrorType.swift, line 200
[1]    22694 illegal hardware instruction  ./display_switch

.ini file

โžœ  bin cat ~/Library/Preferences/display-switch.ini
usb_device = "8086:a36d"
monitor_input = "DisplayPort-1"

Steps taken:

  1. I have right click > Open'ed to ensure Mac will allow it to run.
  2. Loaded, and unloaded the LaunchAgent
  3. Checked Console/Syslogs. No logs there, likely due to crash on startup.

Run as Windows Service

Firstly, thanks for this - it works great with my cheap USB switch!

Similarly to #5, I don't want to have display-switch.exe visible in the task bar all the time, taking up space. I understand you prefer not to clutter the tray bar (altho IMO that would be preferable to cluttering the task bar ๐Ÿ˜„) - could display-switch run as a Windows Service instead?

I know absolutely nothing about DDC/CI, so I don't know if perhaps display-switch needs access to the desktop session, or if there might be other barriers.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.