From ce9ebb49adee82f4dfa8c51db22a5d7a503bf480 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 28 Oct 2020 10:45:00 +0100 Subject: [PATCH] Notifications no longer detect duplicates if rapidly firing (fix #109504) --- .../notifications/notificationsToasts.ts | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts b/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts index bbf8896aba5..22f9152317a 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts @@ -29,7 +29,6 @@ interface INotificationToast { list: NotificationsList; container: HTMLElement; toast: HTMLElement; - toDispose: DisposableStore; } enum ToastVisibility { @@ -67,6 +66,8 @@ export class NotificationsToasts extends Themable implements INotificationsToast private isNotificationsCenterVisible: boolean | undefined; private readonly mapNotificationToToast = new Map(); + private readonly mapNotificationToDisposable = new Map(); + private readonly notificationsToastsVisibleContextKey = NotificationsToastsVisibleContext.bindTo(this.contextKeyService); private readonly addedToastsIntervalCounter = new IntervalCounter(NotificationsToasts.SPAM_PROTECTION.interval); @@ -158,6 +159,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast // the toast until the renderer has time to process it. // (see also https://github.com/microsoft/vscode/issues/107935) const itemDisposables = new DisposableStore(); + this.mapNotificationToDisposable.set(item, itemDisposables); itemDisposables.add(scheduleAtNextAnimationFrame(() => this.doAddToast(item, itemDisposables))); } @@ -197,7 +199,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast }); 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); // When disposed, remove as visible @@ -320,6 +322,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast private removeToast(item: INotificationViewItem): void { let focusEditor = false; + // UI const notificationToast = this.mapNotificationToToast.get(item); if (notificationToast) { const toastHasDOMFocus = isAncestor(document.activeElement, notificationToast.container); @@ -327,13 +330,17 @@ export class NotificationsToasts extends Themable implements INotificationsToast focusEditor = !(this.focusNext() || this.focusPrevious()); // focus next if any, otherwise focus editor } - // Listeners - dispose(notificationToast.toDispose); - - // Remove from Map 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 if (this.mapNotificationToToast.size > 0) { this.layout(this.workbenchDimensions); @@ -351,9 +358,14 @@ export class NotificationsToasts extends Themable implements INotificationsToast } private removeToasts(): void { - this.mapNotificationToToast.forEach(toast => dispose(toast.toDispose)); + + // Toast this.mapNotificationToToast.clear(); + // Disposables + this.mapNotificationToDisposable.forEach(disposable => dispose(disposable)); + this.mapNotificationToDisposable.clear(); + this.doHide(); } @@ -465,15 +477,15 @@ export class NotificationsToasts extends Themable implements INotificationsToast } protected updateStyles(): void { - this.mapNotificationToToast.forEach(t => { + this.mapNotificationToToast.forEach(({ toast }) => { const backgroundColor = this.getColor(NOTIFICATIONS_BACKGROUND); - t.toast.style.background = backgroundColor ? backgroundColor : ''; + toast.style.background = backgroundColor ? backgroundColor : ''; 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); - 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 } 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 { -- GitLab