提交 ce9ebb49 编写于 作者: B Benjamin Pasero

Notifications no longer detect duplicates if rapidly firing (fix #109504)

上级 3e97229e
...@@ -29,7 +29,6 @@ interface INotificationToast { ...@@ -29,7 +29,6 @@ interface INotificationToast {
list: NotificationsList; list: NotificationsList;
container: HTMLElement; container: HTMLElement;
toast: HTMLElement; toast: HTMLElement;
toDispose: DisposableStore;
} }
enum ToastVisibility { enum ToastVisibility {
...@@ -67,6 +66,8 @@ export class NotificationsToasts extends Themable implements INotificationsToast ...@@ -67,6 +66,8 @@ export class NotificationsToasts extends Themable implements INotificationsToast
private isNotificationsCenterVisible: boolean | undefined; private isNotificationsCenterVisible: boolean | undefined;
private readonly mapNotificationToToast = new Map<INotificationViewItem, INotificationToast>(); private readonly mapNotificationToToast = new Map<INotificationViewItem, INotificationToast>();
private readonly mapNotificationToDisposable = new Map<INotificationViewItem, IDisposable>();
private readonly notificationsToastsVisibleContextKey = NotificationsToastsVisibleContext.bindTo(this.contextKeyService); private readonly notificationsToastsVisibleContextKey = NotificationsToastsVisibleContext.bindTo(this.contextKeyService);
private readonly addedToastsIntervalCounter = new IntervalCounter(NotificationsToasts.SPAM_PROTECTION.interval); private readonly addedToastsIntervalCounter = new IntervalCounter(NotificationsToasts.SPAM_PROTECTION.interval);
...@@ -158,6 +159,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast ...@@ -158,6 +159,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast
// the toast until the renderer has time to process it. // the toast until the renderer has time to process it.
// (see also https://github.com/microsoft/vscode/issues/107935) // (see also https://github.com/microsoft/vscode/issues/107935)
const itemDisposables = new DisposableStore(); const itemDisposables = new DisposableStore();
this.mapNotificationToDisposable.set(item, itemDisposables);
itemDisposables.add(scheduleAtNextAnimationFrame(() => this.doAddToast(item, itemDisposables))); itemDisposables.add(scheduleAtNextAnimationFrame(() => this.doAddToast(item, itemDisposables)));
} }
...@@ -197,7 +199,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast ...@@ -197,7 +199,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast
}); });
itemDisposables.add(notificationList); itemDisposables.add(notificationList);
const toast: INotificationToast = { item, list: notificationList, container: notificationToastContainer, toast: notificationToast, toDispose: itemDisposables }; const toast: INotificationToast = { item, list: notificationList, container: notificationToastContainer, toast: notificationToast };
this.mapNotificationToToast.set(item, toast); this.mapNotificationToToast.set(item, toast);
// When disposed, remove as visible // When disposed, remove as visible
...@@ -320,6 +322,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast ...@@ -320,6 +322,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast
private removeToast(item: INotificationViewItem): void { private removeToast(item: INotificationViewItem): void {
let focusEditor = false; let focusEditor = false;
// UI
const notificationToast = this.mapNotificationToToast.get(item); const notificationToast = this.mapNotificationToToast.get(item);
if (notificationToast) { if (notificationToast) {
const toastHasDOMFocus = isAncestor(document.activeElement, notificationToast.container); const toastHasDOMFocus = isAncestor(document.activeElement, notificationToast.container);
...@@ -327,13 +330,17 @@ export class NotificationsToasts extends Themable implements INotificationsToast ...@@ -327,13 +330,17 @@ export class NotificationsToasts extends Themable implements INotificationsToast
focusEditor = !(this.focusNext() || this.focusPrevious()); // focus next if any, otherwise focus editor focusEditor = !(this.focusNext() || this.focusPrevious()); // focus next if any, otherwise focus editor
} }
// Listeners
dispose(notificationToast.toDispose);
// Remove from Map
this.mapNotificationToToast.delete(item); this.mapNotificationToToast.delete(item);
} }
// Disposables
const notificationDisposables = this.mapNotificationToDisposable.get(item);
if (notificationDisposables) {
dispose(notificationDisposables);
this.mapNotificationToDisposable.delete(item);
}
// Layout if we still have toasts // Layout if we still have toasts
if (this.mapNotificationToToast.size > 0) { if (this.mapNotificationToToast.size > 0) {
this.layout(this.workbenchDimensions); this.layout(this.workbenchDimensions);
...@@ -351,9 +358,14 @@ export class NotificationsToasts extends Themable implements INotificationsToast ...@@ -351,9 +358,14 @@ export class NotificationsToasts extends Themable implements INotificationsToast
} }
private removeToasts(): void { private removeToasts(): void {
this.mapNotificationToToast.forEach(toast => dispose(toast.toDispose));
// Toast
this.mapNotificationToToast.clear(); this.mapNotificationToToast.clear();
// Disposables
this.mapNotificationToDisposable.forEach(disposable => dispose(disposable));
this.mapNotificationToDisposable.clear();
this.doHide(); this.doHide();
} }
...@@ -465,15 +477,15 @@ export class NotificationsToasts extends Themable implements INotificationsToast ...@@ -465,15 +477,15 @@ export class NotificationsToasts extends Themable implements INotificationsToast
} }
protected updateStyles(): void { protected updateStyles(): void {
this.mapNotificationToToast.forEach(t => { this.mapNotificationToToast.forEach(({ toast }) => {
const backgroundColor = this.getColor(NOTIFICATIONS_BACKGROUND); const backgroundColor = this.getColor(NOTIFICATIONS_BACKGROUND);
t.toast.style.background = backgroundColor ? backgroundColor : ''; toast.style.background = backgroundColor ? backgroundColor : '';
const widgetShadowColor = this.getColor(widgetShadow); const widgetShadowColor = this.getColor(widgetShadow);
t.toast.style.boxShadow = widgetShadowColor ? `0 0px 8px ${widgetShadowColor}` : ''; toast.style.boxShadow = widgetShadowColor ? `0 0px 8px ${widgetShadowColor}` : '';
const borderColor = this.getColor(NOTIFICATIONS_TOAST_BORDER); const borderColor = this.getColor(NOTIFICATIONS_TOAST_BORDER);
t.toast.style.border = borderColor ? `1px solid ${borderColor}` : ''; toast.style.border = borderColor ? `1px solid ${borderColor}` : '';
}); });
} }
...@@ -548,7 +560,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast ...@@ -548,7 +560,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast
} }
private layoutLists(width: number): void { private layoutLists(width: number): void {
this.mapNotificationToToast.forEach(toast => toast.list.layout(width)); this.mapNotificationToToast.forEach(({ list }) => list.layout(width));
} }
private layoutContainer(heightToGive: number): void { private layoutContainer(heightToGive: number): void {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册