fix(wayland): graceful exit on compositor disconnect
Replace 3 panicking unwrap() in cosmic-app-list/wayland_handler.rs (event loop dispatch + 2 conn.flush in screencopy) with logged errors that break/return None instead. Wrap cosmic-applets/main.rs entry point in panic::catch_unwind to catch panics propagating from libcosmic/iced/winit (which we cannot patch locally without forking) when the COSMIC compositor closes the Wayland connection at logout. This eliminates the cascade of ~12 SIGABRT coredumps observed at session shutdown. Panic strategy is unwind (default), catch_unwind is sound here. Leyoda 2026 – GPLv3
This commit is contained in:
parent
0fa93ba21f
commit
6fe087f4fd
2 changed files with 48 additions and 21 deletions
|
|
@ -388,7 +388,10 @@ impl CaptureData {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.conn.flush().unwrap();
|
if let Err(err) = self.conn.flush() {
|
||||||
|
tracing::error!("Wayland flush failed during screencopy session create: {err}");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let formats = session
|
let formats = session
|
||||||
.wait_while(|data| data.formats.is_none())
|
.wait_while(|data| data.formats.is_none())
|
||||||
|
|
@ -437,7 +440,10 @@ impl CaptureData {
|
||||||
session: capture_session.clone(),
|
session: capture_session.clone(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.conn.flush().unwrap();
|
if let Err(err) = self.conn.flush() {
|
||||||
|
tracing::error!("Wayland flush failed during screencopy capture: {err}");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: wait for server to release buffer?
|
// TODO: wait for server to release buffer?
|
||||||
let res = session
|
let res = session
|
||||||
|
|
@ -709,7 +715,10 @@ pub(crate) fn wayland_handler(
|
||||||
if app_data.exit {
|
if app_data.exit {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
event_loop.dispatch(None, &mut app_data).unwrap();
|
if let Err(err) = event_loop.dispatch(None, &mut app_data) {
|
||||||
|
tracing::error!("Wayland event loop terminated: {err}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,26 +12,44 @@ fn main() -> cosmic::iced::Result {
|
||||||
};
|
};
|
||||||
|
|
||||||
let start = applet.rfind('/').map_or(0, |v| v + 1);
|
let start = applet.rfind('/').map_or(0, |v| v + 1);
|
||||||
let cmd = &applet.as_str()[start..];
|
let cmd = applet.as_str()[start..].to_string();
|
||||||
|
|
||||||
tracing::info!("Starting `{cmd}` with version {VERSION}");
|
tracing::info!("Starting `{cmd}` with version {VERSION}");
|
||||||
|
|
||||||
match cmd {
|
let cmd_for_run = cmd.clone();
|
||||||
"cosmic-app-list" => cosmic_app_list::run(),
|
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(move || {
|
||||||
"cosmic-applet-a11y" => cosmic_applet_a11y::run(),
|
match cmd_for_run.as_str() {
|
||||||
"cosmic-applet-audio" => cosmic_applet_audio::run(),
|
"cosmic-app-list" => cosmic_app_list::run(),
|
||||||
"cosmic-applet-battery" => cosmic_applet_battery::run(),
|
"cosmic-applet-a11y" => cosmic_applet_a11y::run(),
|
||||||
"cosmic-applet-bluetooth" => cosmic_applet_bluetooth::run(),
|
"cosmic-applet-audio" => cosmic_applet_audio::run(),
|
||||||
"cosmic-applet-minimize" => cosmic_applet_minimize::run(),
|
"cosmic-applet-battery" => cosmic_applet_battery::run(),
|
||||||
"cosmic-applet-network" => cosmic_applet_network::run(),
|
"cosmic-applet-bluetooth" => cosmic_applet_bluetooth::run(),
|
||||||
"cosmic-applet-notifications" => cosmic_applet_notifications::run(),
|
"cosmic-applet-minimize" => cosmic_applet_minimize::run(),
|
||||||
"cosmic-applet-power" => cosmic_applet_power::run(),
|
"cosmic-applet-network" => cosmic_applet_network::run(),
|
||||||
"cosmic-applet-status-area" => cosmic_applet_status_area::run(),
|
"cosmic-applet-notifications" => cosmic_applet_notifications::run(),
|
||||||
"cosmic-applet-tiling" => cosmic_applet_tiling::run(),
|
"cosmic-applet-power" => cosmic_applet_power::run(),
|
||||||
"cosmic-applet-time" => cosmic_applet_time::run(),
|
"cosmic-applet-status-area" => cosmic_applet_status_area::run(),
|
||||||
"cosmic-applet-workspaces" => cosmic_applet_workspaces::run(),
|
"cosmic-applet-tiling" => cosmic_applet_tiling::run(),
|
||||||
"cosmic-applet-input-sources" => cosmic_applet_input_sources::run(),
|
"cosmic-applet-time" => cosmic_applet_time::run(),
|
||||||
"cosmic-panel-button" => cosmic_panel_button::run(),
|
"cosmic-applet-workspaces" => cosmic_applet_workspaces::run(),
|
||||||
_ => Ok(()),
|
"cosmic-applet-input-sources" => cosmic_applet_input_sources::run(),
|
||||||
|
"cosmic-panel-button" => cosmic_panel_button::run(),
|
||||||
|
_ => Ok(()),
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(payload) => {
|
||||||
|
let msg = payload
|
||||||
|
.downcast_ref::<&str>()
|
||||||
|
.map(|s| s.to_string())
|
||||||
|
.or_else(|| payload.downcast_ref::<String>().cloned())
|
||||||
|
.unwrap_or_else(|| "<non-string panic>".to_string());
|
||||||
|
tracing::error!(
|
||||||
|
"`{cmd}` panicked (likely compositor disconnect), exiting cleanly: {msg}"
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue