From 0512727c22dbd70738e208407de2307529291d33 Mon Sep 17 00:00:00 2001 From: LynithDev <61880709+LynithDev@users.noreply.github.com> Date: Wed, 30 Sep 2026 21:20:07 +0200 Subject: [PATCH] fix: clear all notifications shouldn't be clearing progress notis (#896) --- .../src/components/notifications.rs | 5 +++- packages/oneclient_app/src/hooks/actions.rs | 9 +++--- packages/oneclient_app/src/notifications.rs | 30 +++++++++++++------ packages/oneclient_core/src/game/launch.rs | 28 ++++++++++------- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/packages/oneclient_app/src/components/notifications.rs b/packages/oneclient_app/src/components/notifications.rs index 6c077f5a..86a27cb2 100644 --- a/packages/oneclient_app/src/components/notifications.rs +++ b/packages/oneclient_app/src/components/notifications.rs @@ -489,7 +489,10 @@ struct Footer; impl Component for Footer { fn render(&self) -> impl IntoElement { let dispatch = use_dispatch(); - let is_empty = use_notifications_snapshot().inbox.is_empty(); + let is_empty = !use_notifications_snapshot() + .inbox + .iter() + .any(|e| e.dismissable()); rect() .horizontal() diff --git a/packages/oneclient_app/src/hooks/actions.rs b/packages/oneclient_app/src/hooks/actions.rs index fc85f8a3..f290194b 100644 --- a/packages/oneclient_app/src/hooks/actions.rs +++ b/packages/oneclient_app/src/hooks/actions.rs @@ -713,8 +713,7 @@ impl Actions { pub fn clear_notification_inbox(&self) { self.with_engine(|state| { - state.inbox.clear(); - state.notifications.clear_inbox(); + state.notifications.clear_inbox(&mut state.inbox); }); } @@ -1229,7 +1228,7 @@ impl Actions { icon: Some(IconType::Download01), progress: None, actions: Vec::new(), - toast_only: false, + toast_only: true, }, Err(err) => NotificationSpec { title: "Install failed".to_string(), @@ -1782,7 +1781,7 @@ impl Actions { icon: Some(IconType::DownloadCloud02), progress: None, actions: Vec::new(), - toast_only: false, + toast_only: true, }); self.with_engine(|app| { @@ -1903,7 +1902,7 @@ impl Actions { icon: Some(IconType::DownloadCloud02), progress: None, actions: Vec::new(), - toast_only: false, + toast_only: true, }, Err(err) => NotificationSpec { title: "Update failed".to_string(), diff --git a/packages/oneclient_app/src/notifications.rs b/packages/oneclient_app/src/notifications.rs index 17305df0..6b00310e 100644 --- a/packages/oneclient_app/src/notifications.rs +++ b/packages/oneclient_app/src/notifications.rs @@ -608,21 +608,32 @@ impl NotificationState { (timers, None) } - pub fn toggle_center(&mut self, _inbox: &mut [InboxEntry], center_open: bool) -> bool { + pub fn toggle_center(&mut self, inbox: &mut Vec, center_open: bool) -> bool { let next = !center_open; if next { + let ids: Vec = inbox + .iter() + .filter(|e| e.toast_only && e.dismissable()) + .map(|e| e.id) + .collect(); + for id in ids { + self.forget_entry(inbox, id); + } self.active_toasts.clear(); self.pending_timers.clear(); } next } - pub fn clear_inbox(&mut self) { - self.progress_entries.clear(); - self.grouped_entries.clear(); - self.grouped_tasks.clear(); - self.active_toasts.clear(); - self.pending_timers.clear(); + pub fn clear_inbox(&mut self, inbox: &mut Vec) { + let ids: Vec = inbox + .iter() + .filter(|e| e.dismissable()) + .map(|e| e.id) + .collect(); + for id in ids { + self.forget_entry(inbox, id); + } } pub fn dismiss_toast(&mut self, inbox: &mut Vec, entry_id: u64) { @@ -1003,7 +1014,7 @@ impl NotificationState { icon, progress: _, actions, - toast_only: _, + toast_only, } = spec; match entry_id.and_then(|id| inbox.iter_mut().find(|e| e.id == id)) { @@ -1019,6 +1030,7 @@ impl NotificationState { entry.actions = actions; entry.tasks = Vec::new(); entry.transfer = None; + entry.toast_only = toast_only; // Keeping it in `active_toasts` lets the loop arm a dismiss timer // now that the entry is no longer loading self.ensure_progress_toast(entry.id); @@ -1033,7 +1045,7 @@ impl NotificationState { icon, progress: None, actions, - toast_only: false, + toast_only, }, ); } diff --git a/packages/oneclient_core/src/game/launch.rs b/packages/oneclient_core/src/game/launch.rs index 891d63b8..e9e90056 100644 --- a/packages/oneclient_core/src/game/launch.rs +++ b/packages/oneclient_core/src/game/launch.rs @@ -474,11 +474,11 @@ async fn start( let post_hook = profile.hook_post.clone(); tokio::spawn(async move { let cluster = cluster; - let status = tokio::select! { - status = child.wait() => status, + let (status, stopped) = tokio::select! { + status = child.wait() => (status, false), _ = kill_rx => { let _ = child.start_kill(); - child.wait().await + (child.wait().await, true) } }; @@ -487,7 +487,7 @@ async fn start( let outcome = match status { Ok(status) => Exit::Observed { code: status.code().map(i64::from), - success: status.success(), + success: status.success() || stopped || killed(&status), display: status.to_string(), }, Err(err) => Exit::Failed(err.to_string()), @@ -542,6 +542,19 @@ fn detach(command: &mut Command) { } } +#[cfg(unix)] +fn killed(status: &std::process::ExitStatus) -> bool { + use std::os::unix::process::ExitStatusExt; + const SIGKILL: i32 = 9; + const JVM_SIGTERM_EXIT: i32 = 143; + status.signal() == Some(SIGKILL) || status.code() == Some(JVM_SIGTERM_EXIT) +} + +#[cfg(not(unix))] +fn killed(_status: &std::process::ExitStatus) -> bool { + false +} + pub(crate) enum Exit { Observed { code: Option, @@ -630,12 +643,7 @@ pub(crate) async fn finalize_session( let crashed = !matches!(end.outcome, Exit::Observed { success: true, .. }); match end.outcome { - Exit::Observed { success: true, .. } => state - .services - .events - .notify("Game closed") - .body(format!("{name} exited")) - .send(), + Exit::Observed { success: true, .. } => {} Exit::Observed { display, .. } => state .services .events