Open windowed after the window system kills the game in fullscreen

When winit's event loop ends with ExitFailure (on Linux, a compositor
dropping the connection after a protocol error) while fullscreen is on,
turn fullscreen off in options.txt before the error goes on, so a
fullscreen the system can't show doesn't crash every launch (#2904).
This commit is contained in:
Kacpherek committed 2026-10-27 19:02:20 +01:00
1 parent 980807b0f5
commit 22cab3eeb3
1 file changed
+26 -2
+26 -2
View File
@@ -271,6 +271,7 @@ use std::{
};
use winit::{
application::ApplicationHandler,
error::EventLoopError,
event::{DeviceEvent, DeviceId, ElementState, MouseButton, MouseScrollDelta, WindowEvent},
event_loop::{ActiveEventLoop, ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
@@ -14767,8 +14768,26 @@ fn write_report(game: &Game<'_>) -> Result<()> {
Ok(())
}
/// The window system ended the event loop with a failure (on Linux, a compositor dropping the
/// connection after a protocol error) while fullscreen was on: the next start opens windowed, so a
/// fullscreen the system can't show doesn't crash every launch (#2904).
fn leave_fullscreen_after(
result: &std::result::Result<(), EventLoopError>,
settings: &mut Settings,
) {
if matches!(result, Err(EventLoopError::ExitFailure(_))) && settings.fullscreen {
settings.fullscreen = false;
settings.save(&Game::options_path());
log::warn!(
"the window system closed the game in fullscreen; the next start opens windowed"
);
}
}
fn run_event_loop(mut game: Game<'_>) -> Result<()> {
EventLoop::new()?.run_app(&mut game)?;
let result = EventLoop::new()?.run_app(&mut game);
leave_fullscreen_after(&result, &mut game.settings);
result?;
horizon_client::discord_presence::stop();
write_report(&game)?;
if let Some(e) = game.error.take() {
@@ -15125,7 +15144,12 @@ fn run_loading(
error: None,
};
let mut app = App::Loading(Box::new(loading));
EventLoop::new()?.run_app(&mut app)?;
let result = EventLoop::new()?.run_app(&mut app);
match &mut app {
App::Ready(game) => leave_fullscreen_after(&result, &mut game.settings),
App::Loading(loading) => leave_fullscreen_after(&result, &mut loading.settings),
}
result?;
horizon_client::discord_presence::stop();
match app {
App::Ready(mut game) => {