fix: clear all notifications shouldn't be clearing progress notis (#896)

This commit is contained in:
LynithDev 2026-09-30 21:20:07 +02:00 • committed by GitHub
parent 9b6f872a8d
commit 0512727c22
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 47 additions and 25 deletions

View file

@ -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()

View file

@ -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(),

View file

@ -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<InboxEntry>, center_open: bool) -> bool {
let next = !center_open;
if next {
let ids: Vec<u64> = 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<InboxEntry>) {
let ids: Vec<u64> = 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<InboxEntry>, 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,
},
);
}

View file

@ -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<i64>,
@ -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