SDL: Prefer Wayland when we're in a Wayland session

SDL doesn't reliably pick Wayland on its own - on a machine with a
working Wayland compositor but no XDG_SESSION_TYPE it still chose x11,
putting us on XWayland. Ask for Wayland when WAYLAND_DISPLAY is set,
respect SDL_VIDEO_DRIVER if the user set it, and fall back to letting
SDL choose if Wayland then fails to initialize.

Also log the video driver we ended up with, which should help triage
the Wayland/X11 reports.

Fixes #21080

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01JvJR8oJNSCimCM9KXVLjfq
This commit is contained in:
Henrik RydgårdandClaude Opus 5 committed 2026-09-05 14:09:24 -06:00
1 parent fefdf21db5
commit 463bd7acf9
1 file changed
+32 -2
+32 -2
View File
@@ -1793,6 +1793,17 @@ int main(int argc, char *argv[]) {
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
#endif
// SDL's automatic pick between Wayland and X11 doesn't always land on Wayland even in a
// Wayland session, and going through XWayland instead costs us scaling and input quality.
// So ask for it explicitly when the session looks like Wayland - unless the user has set
// SDL_VIDEO_DRIVER, in which case they've already told us what they want.
// WAYLAND_DISPLAY is only set on Wayland sessions, so this is a no-op elsewhere.
bool preferWayland = false;
if (getenv("WAYLAND_DISPLAY") && !getenv("SDL_VIDEO_DRIVER")) {
SDL_SetHint(SDL_HINT_VIDEO_DRIVER, "wayland");
preferWayland = true;
}
bool vulkanMayBeAvailable = false;
if (VulkanMayBeAvailable()) {
fprintf(stderr, "DEBUG: Vulkan might be available.\n");
@@ -1821,11 +1832,30 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "Failed to initialize SDL with joystick support. Retrying without.\n");
joystick_enabled = false;
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
bool initialized = false;
if (preferWayland) {
// Asking for Wayland may be exactly what failed, so let SDL pick instead.
fprintf(stderr, "Unable to initialize SDL with the Wayland video driver (%s). Letting SDL choose.\n", SDL_GetError());
SDL_SetHint(SDL_HINT_VIDEO_DRIVER, nullptr);
preferWayland = false;
// Retry with joystick support - it was the video driver that failed, not the joysticks.
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | SDL_INIT_AUDIO)) {
joystick_enabled = true;
initialized = true;
} else {
initialized = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
}
}
if (!initialized) {
fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
}
}
}
const char *videoDriver = SDL_GetCurrentVideoDriver();
fprintf(stderr, "Info: SDL video driver: %s\n", videoDriver ? videoDriver : "(none)");
fprintf(stderr, "Info: We compiled against SDL version %d.%d.%d", SDL_VERSIONNUM_MAJOR(compiled), SDL_VERSIONNUM_MINOR(compiled), SDL_VERSIONNUM_MICRO(compiled));
if (compiled != linked) {
fprintf(stderr, ", but we are linking against SDL version %d.%d.%d., be aware that this can lead to unexpected behaviors\n", SDL_VERSIONNUM_MAJOR(linked), SDL_VERSIONNUM_MINOR(linked), SDL_VERSIONNUM_MICRO(linked));