diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index 95f81f8f8..445384e52 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,6 +1,6 @@ # C/C++ for Visual Studio Code Change Log -## Version 0.24.0-insiders: June 13, 2019 +## Version 0.24.0-insiders: June 14, 2019 ### New Features * Syntactic/lexical and semantic colorization [PR #3651](https://github.com/microsoft/vscode-cpptools/pull/3651) [Documentation](https://github.com/microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/colorization.md) * Add `Rescan Workspace` command. [microsoft/vscode-cpptools-api#11](https://github.com/microsoft/vscode-cpptools-api/issues/11) diff --git a/Extension/src/LanguageServer/colorization.ts b/Extension/src/LanguageServer/colorization.ts index 8747b79ea..46d46bd95 100644 --- a/Extension/src/LanguageServer/colorization.ts +++ b/Extension/src/LanguageServer/colorization.ts @@ -443,10 +443,19 @@ export class ColorizationState { } private refreshInner(e: vscode.TextEditor): void { - // Clear inactive regions - if (this.inactiveDecoration) { - e.setDecorations(this.inactiveDecoration, []); - } + + // The only way to un-apply decorators is to dispose them. + // If we dispose old decorators before applying new decorators, we see a flicker on Mac, + // likely due to a race with UI updates. Here we set aside the existing decorators to be + // disposed of after the new decorators have been applied, so there is not a gap + // in which decorators are not applied. + let oldInactiveDecoration: vscode.TextEditorDecorationType = this.inactiveDecoration; + let oldDecorations: vscode.TextEditorDecorationType[] = this.decorations; + this.inactiveDecoration = null; + this.decorations = new Array(TokenKind.Count); + + this.createColorizationDecorations(e.document.languageId === "cpp"); + let settings: CppSettings = new CppSettings(this.uri); if (settings.enhancedColorization === "Enabled" && settings.intelliSenseEngine === "Default") { for (let i: number = 0; i < TokenKind.Count; i++) { @@ -465,10 +474,26 @@ export class ColorizationState { } } } - // Apply dimming last + + // Normally, decorators are honored in the order in which they were created, not the + // order in which they were applied. Decorators with opacity appear to be handled + // differently, in that the opacity is applied to overlapping decorators even if + // created afterwards. if (settings.dimInactiveRegions && this.inactiveDecoration && this.inactiveRanges) { e.setDecorations(this.inactiveDecoration, this.inactiveRanges); } + + // Dispose of the old decorators only after the new ones have been applied. + if (oldInactiveDecoration) { + oldInactiveDecoration.dispose(); + } + if (oldDecorations) { + for (let i: number = 0; i < TokenKind.Count; i++) { + if (oldDecorations[i]) { + oldDecorations[i].dispose(); + } + } + } } public refresh(e: vscode.TextEditor): void { @@ -647,13 +672,6 @@ export class ColorizationState { } } let f: () => void = async () => { - // Dispose of original decorators. - // Disposing and recreating is simpler than setting decorators to empty ranges in each editor showing this file - this.disposeColorizationDecorations(); - - let isCpp: boolean = util.isEditorFileCpp(uri); - this.createColorizationDecorations(isCpp); - // Apply the decorations to all *visible* text editors let editors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => e.document.uri.toString() === uri); for (let e of editors) {