libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
8.72k stars 1.64k forks source link

Better multi-monitor support on Xorg/Linux #4827

Open YellowOnion opened 2 years ago

YellowOnion commented 2 years ago

I'm not really sure this is the correct place to report/ask this, but since SDL2 is used by basically every game, maybe SDL2 can resolve this by providing some better heuristics to fix the abysmal multi monitor support and acting as a template for other game Engines to do it correctly in native Linux games (Wine ironically doesn't seem to have any of these issues)

I currently have two monitors,

My current problem is that most if not all my native Linux games are put on the secondary display because my secondary display is at 0,0 because of my desk placement and ergonomics I cannot put my secondary display to the right.

Dota 2: Launches on the secondary display: in Full-screen mode I can move it to the primary, and but if I minimize it moves back to the secondary. if borderless window the window is stuck on my secondary display gnome refuses to move to primary display, at 1080p on my 1200p monitor, the out of bounds data is rendered as junk. -sdl_displayindex doesn't work, and seems to be specific to the game engine, not "idiot dev" proof.

Factorio provides some useful information:

   0.084 Available displays: 2
   0.084  [0]: DELL P2314H 23" - {[1920,0], 1920x1080, SDL_PIXELFORMAT_RGB888, 60Hz}
   0.084  [1]: Philips 240B 24" - {[0,111], 1920x1200, SDL_PIXELFORMAT_RGB888, 60Hz}

It enumerates it correctly, and even has the monitor I want as primary in index 0, but it still detects my Philips incorrectly as my "primary".

With Unity games: If I move the window to the primary display the game has incorrect mouse clicks, the cursor position seems to have a y offset of 120px either related to the display layout, or the way in which renders to the 1200p monitor and doesn't fix/register the size change.

This also breaks: triple monitor setups where you would want the center monitor as the primary monitor. Setups with the secondary above the primary (i.e. a TV for watching videos)

image

xrandr --current                                                                                                                     ~
Screen 0: minimum 320 x 200, current 3840 x 1200, maximum 16384 x 16384
DisplayPort-0 connected primary 1920x1080+1920+120 (normal left inverted right x axis y axis) 509mm x 286mm
   1920x1080     60.00*+
   1680x1050     60.00  
   1600x900      60.00  
   1280x1024     75.02    60.02  
   1440x900      60.00  
   1280x800      60.00  
   1152x864      75.00  
   1280x720      60.00  
   1024x768      75.03    60.00  
   800x600       75.00    60.32  
   640x480       75.00    59.94  
   720x400       70.08  
DisplayPort-1 disconnected (normal left inverted right x axis y axis)
HDMI-A-0 disconnected (normal left inverted right x axis y axis)
HDMI-A-1 disconnected (normal left inverted right x axis y axis)
DVI-D-0 connected 1920x1200+0+0 (normal left inverted right x axis y axis) 519mm x 324mm
   1920x1200     59.95*+
   1920x1080     59.95  
   1600x1200     60.00  
   1680x1050     59.88  
   1280x1024     75.02  
   1440x900      74.98    59.90  
   1280x960      60.00  
   1280x800      59.95  
   1152x864      75.00  
   1280x720      60.00  
   1024x768      75.03    70.07    60.00  
   832x624       74.55  
   800x600       72.19    75.00    60.32    56.25  
   640x480       75.00    72.81    66.67    59.94  
   720x400       70.08  
slouken commented 2 years ago

I don't have a multi-monitor Linux setup. Do you have a patch that fixes the issues for you?

YellowOnion commented 2 years ago

I don't have a multi-monitor Linux setup. Do you have a patch that fixes the issues for you?

I actually have zero clue who is responsible for putting the game on the primary monitor, is it Xorg, is it Gnome/Mutter? is it SDL2, is it Mesa/OpenGL/Vulkan drivers? is it a combination of all 3 not working correctly together? So I don't have any idea how to even go about fixing it, and I'm no expert in this kind of thing.

substring commented 2 years ago

I have no way to prove what I've noticed when using multiple monitors, but in my experience the monitor order seems based on the X connector name. Your xrandroutput goes in that sense : DisplayPort-0 (1920x1080) is your first monitor, DVI-D-0 (1920x1200) is your second monitor. Their respective position and size reflect your Displays settings panel.

icculus commented 2 years ago

I assume the correct thing to do is fish this information out of Gnome's settings, if possible, and then figure out how to map that to an X11 (and separate from this specific issue, Wayland) display. It likely has no direct X11 mechanism we can query.

Pulling out the setting from Gnome is probably fairly trivial. Mapping to an X11 display may not be. I have to research it, and this is likely going to bump to 2.0.24 before we get it in revision control.

(Also: KDE may or may not have different settings for this.)

icculus commented 2 years ago

This isn't going to make 2.0.22.

icculus commented 1 year ago

Just looking at this quickly as I'm sifting through milestone bugs...so the X11 code already (in the XRandR codepath, at least) has code to determine the primary monitor, which is apparently reported at the X11 level without us having to talk to Gnome, and it makes sure that that monitor is listed as display 0...Factorio's output seems to confirm this.

So it's not that SDL is failing to find the primary monitor, it's that (for whatever reason) we're putting windows on the wrong one. This might be for several reasons, but it's extremely likely that most games are just going to call SDL_CreateWindow() with a position of CENTERED or UNDEFINED, which should put it on the primary display by default...so the bug is likely elsewhere (in SDL's x11 code), but I don't have more information yet.

Perhaps our fullscreen code is assuming the primary monitor's origin is (0, 0)...?

YellowOnion commented 1 year ago

Is there anything I can do to help with this? I know a little C.

Something worth noting is that Wayland doesn't support a "primary display" but does support negative numbers, so you can put 0,0 on a specific monitor, I'm currently using sway so I could check out that.

slouken commented 1 month ago

FYI, It looks like this is fixed in SDL3. At least on my system, if I run test/testwm --info all, I get:

INFO: Number of displays: 2
INFO: Display 1: ASUS PA329CV 32"
INFO: Bounds: 3840x2160 at 3840,329
INFO: Usable bounds: 3840x2133 at 3840,356
INFO: Display 2: ASUS PA329CV 32"
INFO: Bounds: 3840x2160 at 0,0
INFO: Usable bounds: 3840x1804 at 0,356

If I run test/testwm --fullscreen-desktop --display 1, it will go on my primary monitor, and if I run with --display 2, it will go on my left monitor.