While investigating this I noticed that this engine calls:
randrLib = os_dll_load("libXrandr.so");
where os_dll_load() is presumably a wrapper around dlopen() on Linux.
This is an understandable thing to try, but in fact it is not correct for two reasons:
The development symlink libXrandr.so is not guaranteed to exist on end-user systems, even if libXrandr is installed. When a library is installed on an end-user system, the only files that normally exist are the version-dependent name of the "real" file (e.g. libXrandr.so.2.2.0 on my Debian 12 system), and a symlink to the "real" file with a name matching the library's SONAME (e.g. libXrandr.so.2 -> libXrandr.so.2.2.0). The libXrandr.so -> libXrandr.so.2 symlink is only intended to be used as part of the implementation of cc -lXrandr, so it normally only exists if you have installed a separate development package, for example libxrandr-dev on Debian/Ubuntu or libXrandr-devel on Fedora/Red Hat.
The SONAME of the library changes whenever there is a non-backward-compatible change to its binary interface (an "ABI break"). If this game engine is expecting the ABI that corresponds to libXrandr.so.2, but it dynamically loads libXrandr.so.1 or libXrandr.so.3 on some user's system, it will not work correctly: a common form of ABI break is that the signature of a function has changed, which means that the engine would push the wrong arguments onto the stack when calling it, causing a crash.
I believe (1.) is the root cause for the unexpected window placement: recent versions of the Steam client run native Linux games in a Steam Linux Runtime container by default, and those containers are similar to an older Debian system with no developer files installed. As a result, libXrandr.so does not exist, so the dlopen() call fails, and the engine presumably falls back to a less clever way to choose which display is primary.
(2.) is probably not a practical problem for War Thunder right now, but it could become a practical problem at any time.
Please use the SONAME of each library that is passed to dlopen(), which would mean making changes similar to this:
And if there are other places in the codebase that call os_dll_load() or other dlopen() wrappers to load an OS/runtime library, please make a similar change there. Otherwise, this game engine will already not work as intended for some Linux users, and could start crashing in future as a result of a routine OS update.
Issue reports at https://github.com/ValveSoftware/steam-runtime/issues/719 and https://community.gaijin.net/issues/p/warthunder/i/NHkOOFjzaY0c say that some War Thunder players on Linux see the game running full-screen on an unexpected display: they have set one of their displays as primary, and they expected War Thunder to draw a full-screen window on that display, but instead it draws a full-screen window on the display that is closest to the top left, coordinate (0,0).
While investigating this I noticed that this engine calls:
where
os_dll_load()
is presumably a wrapper arounddlopen()
on Linux.This is an understandable thing to try, but in fact it is not correct for two reasons:
The development symlink
libXrandr.so
is not guaranteed to exist on end-user systems, even if libXrandr is installed. When a library is installed on an end-user system, the only files that normally exist are the version-dependent name of the "real" file (e.g.libXrandr.so.2.2.0
on my Debian 12 system), and a symlink to the "real" file with a name matching the library's SONAME (e.g.libXrandr.so.2 -> libXrandr.so.2.2.0
). ThelibXrandr.so -> libXrandr.so.2
symlink is only intended to be used as part of the implementation ofcc -lXrandr
, so it normally only exists if you have installed a separate development package, for examplelibxrandr-dev
on Debian/Ubuntu orlibXrandr-devel
on Fedora/Red Hat.The SONAME of the library changes whenever there is a non-backward-compatible change to its binary interface (an "ABI break"). If this game engine is expecting the ABI that corresponds to
libXrandr.so.2
, but it dynamically loadslibXrandr.so.1
orlibXrandr.so.3
on some user's system, it will not work correctly: a common form of ABI break is that the signature of a function has changed, which means that the engine would push the wrong arguments onto the stack when calling it, causing a crash.I believe (1.) is the root cause for the unexpected window placement: recent versions of the Steam client run native Linux games in a Steam Linux Runtime container by default, and those containers are similar to an older Debian system with no developer files installed. As a result,
libXrandr.so
does not exist, so thedlopen()
call fails, and the engine presumably falls back to a less clever way to choose which display is primary.(2.) is probably not a practical problem for War Thunder right now, but it could become a practical problem at any time.
Please use the SONAME of each library that is passed to
dlopen()
, which would mean making changes similar to this:And if there are other places in the codebase that call
os_dll_load()
or otherdlopen()
wrappers to load an OS/runtime library, please make a similar change there. Otherwise, this game engine will already not work as intended for some Linux users, and could start crashing in future as a result of a routine OS update.Thanks, smcv Steam Runtime team