Adds a way to dismiss workspace notifications (#30015)

Closes https://github.com/zed-industries/zed/issues/10140

* On `menu::Cancel` action (`ESC`), close notifications, one by one, if
`Workspace` gets to handle this action.
More specific, focused items contexts (e.g. `Editor`) take priority.

* Allows to temporarily suppress notifications of this kind either by
clicking a corresponding button in the UI, or using
`workspace::SuppressNotification` action.

This might not work well out of the box for all notifications and might
require further improvement.


https://github.com/user-attachments/assets/0ea49ee6-cd21-464f-ba74-fc40f7a8dedf


Release Notes:

- Added a way to dismiss workspace notifications
This commit is contained in:
Kirill Bulatov 2025-05-06 18:15:26 +03:00 committed by GitHub
parent 7d361ec97e
commit 007fd0586a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 96 additions and 13 deletions

View file

@ -52,7 +52,8 @@ use language::{Buffer, LanguageRegistry, Rope};
pub use modal_layer::*;
use node_runtime::NodeRuntime;
use notifications::{
DetachAndPromptErr, Notifications, simple_message_notification::MessageNotification,
DetachAndPromptErr, Notifications, dismiss_app_notification,
simple_message_notification::MessageNotification,
};
pub use pane::*;
pub use pane_group::*;
@ -179,6 +180,7 @@ actions!(
SaveAs,
SaveWithoutFormat,
ShutdownDebugAdapters,
SuppressNotification,
ToggleBottomDock,
ToggleCenteredLayout,
ToggleLeftDock,
@ -921,6 +923,7 @@ pub struct Workspace {
toast_layer: Entity<ToastLayer>,
titlebar_item: Option<AnyView>,
notifications: Notifications,
suppressed_notifications: HashSet<NotificationId>,
project: Entity<Project>,
follower_states: HashMap<CollaboratorId, FollowerState>,
last_leaders_by_pane: HashMap<WeakEntity<Pane>, CollaboratorId>,
@ -1245,7 +1248,8 @@ impl Workspace {
modal_layer,
toast_layer,
titlebar_item: None,
notifications: Default::default(),
notifications: Notifications::default(),
suppressed_notifications: HashSet::default(),
left_dock,
bottom_dock,
bottom_dock_layout,
@ -5301,12 +5305,20 @@ impl Workspace {
workspace.clear_all_notifications(cx);
},
))
.on_action(cx.listener(
|workspace: &mut Workspace, _: &SuppressNotification, _, cx| {
if let Some((notification_id, _)) = workspace.notifications.pop() {
workspace.suppress_notification(&notification_id, cx);
}
},
))
.on_action(cx.listener(
|workspace: &mut Workspace, _: &ReopenClosedItem, window, cx| {
workspace.reopen_closed_item(window, cx).detach();
},
))
.on_action(cx.listener(Workspace::toggle_centered_layout))
.on_action(cx.listener(Workspace::cancel))
}
#[cfg(any(test, feature = "test-support"))]
@ -5477,6 +5489,15 @@ impl Workspace {
.update(cx, |_, window, _| window.activate_window())
.ok();
}
pub fn cancel(&mut self, _: &menu::Cancel, _: &mut Window, cx: &mut Context<Self>) {
if let Some((notification_id, _)) = self.notifications.pop() {
dismiss_app_notification(&notification_id, cx);
return;
}
cx.propagate();
}
}
fn leader_border_for_pane(