@@ -443,10 +443,19 @@ export class ColorizationState {
443443 }
444444
445445 private refreshInner ( e : vscode . TextEditor ) : void {
446- // Clear inactive regions
447- if ( this . inactiveDecoration ) {
448- e . setDecorations ( this . inactiveDecoration , [ ] ) ;
449- }
446+
447+ // The only way to un-apply decorators is to dispose them.
448+ // If we dispose old decorators before applying new decorators, we see a flicker on Mac,
449+ // likely due to a race with UI updates. Here we set aside the existing decorators to be
450+ // disposed of after the new decorators have been applied, so there is not a gap
451+ // in which decorators are not applied.
452+ let oldInactiveDecoration : vscode . TextEditorDecorationType = this . inactiveDecoration ;
453+ let oldDecorations : vscode . TextEditorDecorationType [ ] = this . decorations ;
454+ this . inactiveDecoration = null ;
455+ this . decorations = new Array < vscode . TextEditorDecorationType > ( TokenKind . Count ) ;
456+
457+ this . createColorizationDecorations ( e . document . languageId === "cpp" ) ;
458+
450459 let settings : CppSettings = new CppSettings ( this . uri ) ;
451460 if ( settings . enhancedColorization === "Enabled" && settings . intelliSenseEngine === "Default" ) {
452461 for ( let i : number = 0 ; i < TokenKind . Count ; i ++ ) {
@@ -465,10 +474,26 @@ export class ColorizationState {
465474 }
466475 }
467476 }
468- // Apply dimming last
477+
478+ // Normally, decorators are honored in the order in which they were created, not the
479+ // order in which they were applied. Decorators with opacity appear to be handled
480+ // differently, in that the opacity is applied to overlapping decorators even if
481+ // created afterwards.
469482 if ( settings . dimInactiveRegions && this . inactiveDecoration && this . inactiveRanges ) {
470483 e . setDecorations ( this . inactiveDecoration , this . inactiveRanges ) ;
471484 }
485+
486+ // Dispose of the old decorators only after the new ones have been applied.
487+ if ( oldInactiveDecoration ) {
488+ oldInactiveDecoration . dispose ( ) ;
489+ }
490+ if ( oldDecorations ) {
491+ for ( let i : number = 0 ; i < TokenKind . Count ; i ++ ) {
492+ if ( oldDecorations [ i ] ) {
493+ oldDecorations [ i ] . dispose ( ) ;
494+ }
495+ }
496+ }
472497 }
473498
474499 public refresh ( e : vscode . TextEditor ) : void {
@@ -647,13 +672,6 @@ export class ColorizationState {
647672 }
648673 }
649674 let f : ( ) => void = async ( ) => {
650- // Dispose of original decorators.
651- // Disposing and recreating is simpler than setting decorators to empty ranges in each editor showing this file
652- this . disposeColorizationDecorations ( ) ;
653-
654- let isCpp : boolean = util . isEditorFileCpp ( uri ) ;
655- this . createColorizationDecorations ( isCpp ) ;
656-
657675 // Apply the decorations to all *visible* text editors
658676 let editors : vscode . TextEditor [ ] = vscode . window . visibleTextEditors . filter ( e => e . document . uri . toString ( ) === uri ) ;
659677 for ( let e of editors ) {
0 commit comments