hansschmucker / NVStreamer1080

Utility to automatically detect NVidia GameStream activity and set a fitting resolution or switch to a second screen.
Apache License 2.0
112 stars 8 forks source link

Invert the internal/external monitor when switching #19

Open kayakyakr opened 1 year ago

kayakyakr commented 1 year ago

This should be operational but I'm having a couple of issues with it:

The first is my unfamiliarity with C# maybe? I'm missing something somewhere.

The second may be a "lucky" side effect with standard mode. Otherwise, even when I set resolution before connecting, Moonlight does not actually ever full screen.

I believe this is the "new" API here: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setdisplayconfig. There's a very interesting "mode" this can be used in that allows a temporary (non-persisted) display setting. That means, if your desktop crashes while streaming moonlight, it will restart with the new settings. Could be an upgrade.

kayakyakr commented 1 year ago

Here's someone doing the ChangeDisplay.exe thing using dll's: https://stackoverflow.com/questions/16326932/how-to-set-primary-monitor-for-windows-7-in-c-sharp

kayakyakr commented 1 year ago

OK, so update: this kinda got away from me a little bit. What turned into a small feature became a full redesign. Now, in settings, you select the monitor that you want to stream to and the size you'd like. App will update the topology to have the monitor you want to use as primary and will set the resolution accordingly.

Tested using my fold 4 on:

I found that SetDisplayConfig was a fantastic way to set the topology of monitors. This doesn't have any flash, it just sets the selected monitor on and any others off. The benefit is that this will allow you to have multiple monitors in extend mode and on connect will switch to one of those or even a 3rd disconnected or dummy monitor. On disconnect, it restores whatever it was that you started with. The restoration code needs a bit more love. You would think that parroting the modes they send when you fetch data back would be enough for windows, but nooooo, it really doesn't like it.

I did manage to get it to also change the resolution, but I was desperately requesting it stretch the frame and just couldn't make it happen like the original set resolution functions do. I don't know if it's worth digging into. The benefit of using SetDisplayConfig to change the resolution is that you can do it in a temp mode and one-line reset it on disconnect. It also hardens the app to crashes as on reboot the system will pick back up the old config. Unfortunately, changing topology forces persistence anyway, so it doesn't much matter.

Added an old CCD C# wrapper because it defined all the structs so I didn't have to.

Using this build locally. LMK what you think.