Hello. I'm using Fedora 22, with a GTX 760 (with Nvidia proprietary driver), and two monitors. When I run an LWJGL application (tested with LibGDX and Minecraft), the display mode for one of my monitors is set wrong on application exit. Here is my xrandr output:
Screen 0: minimum 8 x 8, current 3200 x 1200, maximum 16384 x 16384
DVI-I-0 disconnected (normal left inverted right x axis y axis)
DVI-I-1 disconnected (normal left inverted right x axis y axis)
HDMI-0 connected primary 1920x1200+0+0 (normal left inverted right x axis y axis) 519mm x 324mm
1920x1200 59.95*+ 59.88
1920x1080 60.00 59.94 50.00 60.05 60.00 50.04
1680x1050 59.95
1600x1200 60.00
1440x900 59.89
1280x1024 75.02 60.02
1280x800 59.81
1280x720 60.00 59.94 50.00
1152x720 60.00
1024x768 75.03 60.00
800x600 75.00 60.32
720x576 50.00
720x480 59.94 60.05
640x480 75.00 59.94 59.93
624x464 59.95
DP-0 disconnected (normal left inverted right x axis y axis)
DVI-D-0 connected 1280x1024+1920+176 (normal left inverted right x axis y axis) 338mm x 270mm
1280x1024 60.02*+
1024x768 60.00
800x600 60.32
640x480 59.94
DP-1 disconnected (normal left inverted right x axis y axis)
On the monitor "HDMI-0", there are two different modes for the highest resolution: 59.95 Hz (default, works) and 59.88 Hz (doesn't work). When the mode for the monitor is set to 59.88 Hz, the screen goes blue (as if there's no signal). When a LWJGL application exits, it sets the mode for HDMI-0 to the one that doesn't work, and to fix it I have to use xrandr to set it back to the default mode.
When I run a LibGDX application with LWJGL debug output on (org.lwjgl.util.Debug), this is the output from the start of the game to the end:
[LWJGL] getPathFromClassLoader: searching for: openal
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.URLClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.security.SecureClassLoader.findLibrary(java.lang.String)
[LWJGL] getPathFromClassLoader: searching for: lwjgl
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.URLClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.security.SecureClassLoader.findLibrary(java.lang.String)
[LWJGL] getPathFromClassLoader: searching for: lwjgl
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.URLClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.security.SecureClassLoader.findLibrary(java.lang.String)
[LWJGL] getPathFromClassLoader: searching for: lwjgl
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.URLClassLoader.findLibrary(java.lang.String)
[LWJGL] Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.security.SecureClassLoader.findLibrary(java.lang.String)
[LWJGL] Found 27 OpenAL paths
[LWJGL] Testing '/tmp/libgdxmax/31ce78a2/libopenal64.so'
[LWJGL] Found OpenAL at '/tmp/libgdxmax/31ce78a2/libopenal64.so'
[LWJGL] MemoryUtil Accessor: AccessorUnsafe
[LWJGL] Xrandr extension version 1.4
[LWJGL] Using Xrandr for display mode switching
[LWJGL] XF86VidMode extension version 2.2
[LWJGL] Initial mode: 1920 x 1200 x 24 @59Hz
[LWJGL] Pixel format info: r = 8, g = 8, b = 8, a = 8, depth = 24, stencil = 0, sample buffers = 0, samples = 0
[the game is running, irrelevant non-LWJGL output is omitted...]
[LWJGL] XF86VidMode extension version 2.2
What's weird is that this just started happening a while ago, and I can't seem to see what caused it, as it worked fine before. I even reinstalled my system and started clean, and the issue is still there.
I get the same thing. What happened is someone did a hotfix and caused this regresssion.
see https://bugs.mojang.com/browse/MC-36746 and https://github.com/LWJGL/lwjgl/issues/64
Hotfix guy here.
Congrats, you have found yet another exotic output of xrandr that breaks the parsing logic. :)
The core problem here is that it is a bad idea to parse xrandr text output in the first place.
Back when I did that hotfix, LWJGL would read the refresh rate from lib(x)randr (which is technically correct).
However, it was read with outdated API calls that deliberately returned wrong frequency values in multi-monitor setups, because other tools/programs break when the same modeline is returned multiple times - which happens if you attach more than one monitor.
Since LWJGL did parse xrandr anyway, I changed the code to use the values from the xrandr output, which are correct.
This fixed many problems with multi-monitor setups, displays with 120Hz, etc.
I didn't knew better at the time, but the real solution would have been to modify the C code and find out how to read the actual values from lib(x)randr.
Since I never found the time to do this, noone else did, and LWJGL 2 is EOL anyway, minecraft and other games still do not work with exotic xrandr outputs.
Short them solution: Patch the code again and use floats, but prepare for funny bug reports - By putting the right things in your xorg.conf, you can basically set that xrandr output to arbitrary strings, and people do this :)
Real solution: Tell @grum and other mojang folks again and again until they switch to LWJGL 3, where everything is awesomeTM
Or just use the workaround wrapper script I just posted on the github bug. :)
It's quite ironic that I can only make this workaround because you call an external binary rather than using libxrandr directly. If you did the latter and messed it up then I would have to make a preload library to dynamically patch the code, like I had to do with flash -> https://github.com/ali1234/fullscreenhack
What I would really like to know is, since I am not using full screen, why is LWJGL touching the screen mode *at all*?
LWJGL2 just always resets the monitor configuration on exit in case anything was changed (resolutions, frequency, bpp, gamma, secondary monitors disabled...)
But yeah, you are right, no need to do most of these things for windowed applications.
I've made an attempt to fix this. Two changes:
- The original frequency is stored as a string, used as is when the screen configuration is restored.
- The screen configuration is not reset on exit, unless there has been a display mode change.
I'm afraid I'm not able to test the patch atm, so please try the next nightly build and let me know how it goes.