Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with interactive graphics mode on Linux with multi-monitor setup #140

Closed
abcbcafe opened this issue Jan 19, 2024 · 1 comment
Closed
Labels
bug something isn't working

Comments

@abcbcafe
Copy link

Hi, and thanks for the cool software.

I ran into an issue using the interactive graphics mode with a multi-monitor setup on Linux/X11. When launching a simulation, the fullscreen window launches on my main monitor, but the actual visualization inside the window is off-center. The same off-centeredness is also apparent for where the cursor gets picked up. This seems to be caused by DisplayWidth() and DisplayHeight() returning the total/combined size of all monitors, instead of only the size of the main monitor, causing the calculation of the center to be off. See attached screenshot.

I noticed that direct PRs are not accepted, but I wanted to share a workaround for anyone else facing this issue. If it suits the project, feel free to incorporate this into the codebase. The patch uses Xrandr to obtain the dimensions of the primary monitor, which ensures correct positioning of the simulation and mouse cursor. Note that this fix adds a dependency to Xrandr and could probably benefit from some better error handling.


===================================================================
diff --git a/src/graphics.cpp b/src/graphics.cpp
--- a/src/graphics.cpp	(revision e974c92e281ff58a19eb8ab986b75673ca44b341)
+++ b/src/graphics.cpp	(date 1705694483737)
@@ -560,6 +560,7 @@
 #elif defined(__linux__)||defined(__APPLE__)
 
 #include "X11/include/X11/Xlib.h" // source: libx11-dev
+#include <X11/extensions/Xrandr.h>
 
 Display* x11_display;
 Window x11_window;
@@ -684,12 +685,22 @@
 
 	x11_display = XOpenDisplay(0);
 	if(!x11_display) print_error("No X11 display available.");
-
-	const uint height = (uint)DisplayHeight(x11_display, 0);
-	const uint width = (uint)DisplayWidth(x11_display, 0);
+	Window root = DefaultRootWindow(x11_display);
+	XRRScreenResources *screenResources = XRRGetScreenResources(x11_display, root);
+	
+	RROutput primaryOutput = XRRGetOutputPrimary(x11_display, root);
+	XRROutputInfo *info = XRRGetOutputInfo(x11_display, screenResources, primaryOutput);
+	
+	XRRCrtcInfo *crtcInfo = XRRGetCrtcInfo(x11_display, screenResources, info->crtc);
+	const uint width = crtcInfo->width;
+	const uint height = crtcInfo->height;
 	camera = Camera(width, height, 60u);
 
-	x11_window = XCreateWindow(x11_display, DefaultRootWindow(x11_display), 0, 0, width, height, 0, CopyFromParent, CopyFromParent, CopyFromParent, 0, 0);
+	XRRFreeCrtcInfo(crtcInfo);
+	XRRFreeOutputInfo(info);
+	XRRFreeScreenResources(screenResources);
+
+	x11_window = XCreateWindow(x11_display, root, 0, 0, width, height, 0, CopyFromParent, CopyFromParent, CopyFromParent, 0, 0);
 	XStoreName(x11_display, x11_window, WINDOW_NAME);
 	struct Hints { long flags=2l, functions=0l, decorations=0b0000000l, input_mode=0l, status=0l; } x11_hints; // decorations=maximize|minimize|menu|title|resize|border|all
 	Atom x11_property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", 0);

To build, you'll have to add -lXrandr to the linker flags, e.g.
g++ src/*.cpp -o bin/FluidX3D -std=c++17 -pthread -I./src/OpenCL/include -L./src/OpenCL/lib -lOpenCL -I./src/X11/include -L./src/X11/lib -lXrandr -lX11

I don't think it should matter, but for reference, I'm using:

  • Gnome 45
  • Xorg 21.1.10-1
  • Nvidia RTX 4090 with version 545.29.06 of the proprietary drivers
  • Kernel 6.7.0
  • The resolution of my 3 displays are (xrandr --query | grep " connected"):
    HDMI-0 connected 1920x1080+0+1268 (normal left inverted right x axis y axis) 344mm x 193mm
    DP-2 connected 1440x2560+5360+0 right (normal left inverted right x axis y axis) 597mm x 336mm
    DP-4 connected primary 3440x1440+1920+306 (normal left inverted right x axis y axis) 797mm x 334mm

Cheers, and have a great weekend.

Screenshot from 2024-01-19 21-50-41

@ProjectPhysX ProjectPhysX added the bug something isn't working label Jan 19, 2024
@ProjectPhysX
Copy link
Owner

Hi @abcbcafe,

thank you so much for reporting this bug AND proposing a fix!
I have fixed the multi-monitor issues now:

  • your fixes are the main part, to get the resolution of the primary monitor
  • to place the fullscreen window always on the primary monitor, I had to query the offset coordinates and apply them with XSetNormalHints
  • catch the cursor from anywhere on the multi-monitor area and place it on the primary monitor
  • to make it work on any system without the packages libx11-dev, x11proto-dev, libxrandr-dev and libxrender-dev installed (in case users don't have sudo permissions), I've pulled the additional headers and the additional lib from these packages and included them directly in the FluidX3D repo

Find the commit here.

Kind regards,
Moritz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants