Add orderly shutdown on window close
This commit is contained in:
+53
-3
@@ -82,6 +82,8 @@ const CHAT_MIN_H: f32 = 110.0;
|
||||
const ABOVE_CHAT_MIN_H: f32 = 300.0;
|
||||
/// Thickness of a draggable divider (px).
|
||||
const DIVIDER_THICKNESS: f32 = 8.0;
|
||||
/// Upper bound for waiting on orderly core shutdown before letting the window exit.
|
||||
const SHUTDOWN_TIMEOUT_SECS: u64 = 5;
|
||||
|
||||
/// Clamp the Participants panel width so neither it nor the Controls panel drops
|
||||
/// below its minimum, given the current window width.
|
||||
@@ -221,6 +223,10 @@ pub enum AppMessage {
|
||||
ToggleScreenShare,
|
||||
/// Watch a peer's screen share, identified by their pixelpass ticket.
|
||||
WatchShare(String),
|
||||
/// Result of asynchronously enqueueing the core shutdown command.
|
||||
ShutdownCommandSent(bool),
|
||||
/// Fallback close if the core does not acknowledge shutdown promptly.
|
||||
ShutdownTimeout,
|
||||
}
|
||||
|
||||
fn core_subscription() -> impl iced::futures::Stream<Item = UiEvent> {
|
||||
@@ -324,6 +330,8 @@ pub struct AppState {
|
||||
friend_add_name: String,
|
||||
/// Inline feedback for the add-friend form (e.g. a bad id), cleared on edit.
|
||||
friend_add_error: Option<String>,
|
||||
/// Window close has been requested and the GUI is waiting for core teardown.
|
||||
closing: bool,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
@@ -441,6 +449,7 @@ impl Default for AppState {
|
||||
friend_add_id: String::new(),
|
||||
friend_add_name: String::new(),
|
||||
friend_add_error: None,
|
||||
closing: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -520,6 +529,20 @@ fn subscription(_state: &AppState) -> Subscription<AppMessage> {
|
||||
Subscription::batch(vec![core_sub, event_sub])
|
||||
}
|
||||
|
||||
fn shutdown_timeout_task() -> Task<AppMessage> {
|
||||
Task::perform(
|
||||
async {
|
||||
let (tx, rx) = iced::futures::channel::oneshot::channel();
|
||||
std::thread::spawn(move || {
|
||||
std::thread::sleep(std::time::Duration::from_secs(SHUTDOWN_TIMEOUT_SECS));
|
||||
let _ = tx.send(());
|
||||
});
|
||||
let _ = rx.await;
|
||||
},
|
||||
|_| AppMessage::ShutdownTimeout,
|
||||
)
|
||||
}
|
||||
|
||||
/// Reconnect-chime edge trigger for `UiEvent::PeerConnecting`. Marks the peer as
|
||||
/// connecting and returns `Some(Sound::ReconnectAttempt)` exactly once per outage:
|
||||
/// only when the peer had a live link before (a genuine reconnect, not a first
|
||||
@@ -865,6 +888,11 @@ fn update(state: &mut AppState, message: AppMessage) -> Task<AppMessage> {
|
||||
state.status_message =
|
||||
"Discoverable timed out — back to Normal".to_string();
|
||||
}
|
||||
UiEvent::ShutdownComplete => {
|
||||
if state.closing {
|
||||
return iced::exit();
|
||||
}
|
||||
}
|
||||
UiEvent::Error(err) => {
|
||||
state.status_message = format!("Error: {}", err);
|
||||
}
|
||||
@@ -1318,13 +1346,35 @@ fn update(state: &mut AppState, message: AppMessage) -> Task<AppMessage> {
|
||||
state.config.window_y = Some(position.y as i32);
|
||||
}
|
||||
AppMessage::EventOccurred(Event::Window(iced::window::Event::CloseRequested)) => {
|
||||
if state.closing {
|
||||
return Task::none();
|
||||
}
|
||||
// We took over the close path (exit_on_close_request:false) so we can
|
||||
// persist the final window size + position before quitting. Both are
|
||||
// already mirrored into config by the Resized/Moved handlers above.
|
||||
// persist the final window size + position and give core a chance to
|
||||
// leave the room/finalize recordings before quitting.
|
||||
state.config.save();
|
||||
return iced::exit();
|
||||
state.closing = true;
|
||||
state.status_message = "Shutting down...".to_string();
|
||||
let tx = state.controller.command_sender();
|
||||
return Task::batch(vec![
|
||||
Task::perform(
|
||||
async move { tx.send(CoreCommand::Shutdown).await.is_ok() },
|
||||
AppMessage::ShutdownCommandSent,
|
||||
),
|
||||
shutdown_timeout_task(),
|
||||
]);
|
||||
}
|
||||
AppMessage::EventOccurred(_) => {}
|
||||
AppMessage::ShutdownCommandSent(sent) => {
|
||||
if !sent {
|
||||
return iced::exit();
|
||||
}
|
||||
}
|
||||
AppMessage::ShutdownTimeout => {
|
||||
if state.closing {
|
||||
return iced::exit();
|
||||
}
|
||||
}
|
||||
AppMessage::NavigateToSettings => {
|
||||
state.current_screen = Screen::Settings;
|
||||
state.layout_picker_open = false;
|
||||
|
||||
Reference in New Issue
Block a user