diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java index 14d5748e6aa..ccf30f30387 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java @@ -2543,6 +2543,8 @@ public String toString() { private SourceViewerConfiguration fConfiguration; /** The editor's source viewer. */ private ISourceViewer fSourceViewer; + /** Whether a full re-style of the text presentation is already scheduled. */ + private boolean fInvalidateTextPresentationPending; /** * The editor's selection provider. * @@ -4748,6 +4750,28 @@ protected void disposeDocumentProvider() { fExplicitDocumentProvider = null; } + /** + * Re-styles the whole document once per UI event loop turn, so a burst of + * preference changes costs one re-style instead of one per key. + */ + private void invalidateTextPresentationLater() { + if (fInvalidateTextPresentationPending) { + return; + } + StyledText widget= fSourceViewer.getTextWidget(); + if (widget == null || widget.isDisposed()) { + return; + } + fInvalidateTextPresentationPending= true; + widget.getDisplay().asyncExec(() -> { + fInvalidateTextPresentationPending= false; + ISourceViewer viewer= fSourceViewer; + if (viewer != null && viewer.getTextWidget() != null && !viewer.getTextWidget().isDisposed()) { + viewer.invalidateTextPresentation(); + } + }); + } + /** * Determines whether the given preference change affects the editor's * presentation. This implementation always returns false. May be @@ -4843,7 +4867,7 @@ protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { } if (affectsTextPresentation(event)) { - fSourceViewer.invalidateTextPresentation(); + invalidateTextPresentationLater(); } if (PREFERENCE_HYPERLINKS_ENABLED.equals(property)) { diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/SourceViewerDecorationSupport.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/SourceViewerDecorationSupport.java index f92e26d8958..29ef0f412af 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/SourceViewerDecorationSupport.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/SourceViewerDecorationSupport.java @@ -209,6 +209,8 @@ public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset private MarginPainter fMarginPainter; /** The editor's annotation painter */ private AnnotationPainter fAnnotationPainter; + /** Whether a repaint of the annotation painter is already scheduled. */ + private boolean fAnnotationPainterRepaintPending; /** The editor's peer character painter */ private MatchingCharacterPainter fMatchingCharacterPainter; /** The character painter's pair matcher */ @@ -617,7 +619,7 @@ protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { Color color= getColor(info.getColorPreferenceKey()); if (fAnnotationPainter != null) { fAnnotationPainter.setAnnotationTypeColor(info.getAnnotationType(), color); - fAnnotationPainter.paint(IPainter.CONFIGURATION); + repaintAnnotationPainterLater(); } setAnnotationOverviewColor(info.getAnnotationType(), color); return; @@ -649,11 +651,32 @@ protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { Color color = registry.get(fInlineAnnotationColorKey); fAnnotationPainter.setInlineAnnotationColor(color); fAnnotationPainter.setAnnotationTypeColor(AbstractInlinedAnnotation.TYPE, color); - fAnnotationPainter.paint(IPainter.CONFIGURATION); + repaintAnnotationPainterLater(); } } } + /** + * Repaints the annotation painter once per UI event loop turn, so a burst of + * color changes costs one repaint instead of one per color. + */ + private void repaintAnnotationPainterLater() { + if (fAnnotationPainterRepaintPending) { + return; + } + StyledText widget= fSourceViewer.getTextWidget(); + if (widget == null || widget.isDisposed()) { + return; + } + fAnnotationPainterRepaintPending= true; + widget.getDisplay().asyncExec(() -> { + fAnnotationPainterRepaintPending= false; + if (fAnnotationPainter != null && !widget.isDisposed()) { + fAnnotationPainter.paint(IPainter.CONFIGURATION); + } + }); + } + /** * Returns the shared color for the given key. *