Skip to content

Commit bc6e3ec

Browse files
Christopher-Hermannmickaelistria
authored andcommitted
[Sticky Scrolling] Throttle sticky scrolling calculation
The calculation of the sticky-scrolling lines is now throttled, executing only every 100 ms, to prevent potential performance bottlenecks. Follow up to #1894
1 parent 5179e72 commit bc6e3ec

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandler.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919
import static org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants.EDITOR_STICKY_SCROLLING_MAXIMUM_COUNT;
2020
import static org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH;
2121

22+
import java.time.Duration;
2223
import java.util.List;
2324

2425
import org.eclipse.swt.graphics.Color;
2526

2627
import org.eclipse.jface.preference.IPreferenceStore;
2728
import org.eclipse.jface.preference.PreferenceConverter;
2829
import org.eclipse.jface.util.IPropertyChangeListener;
30+
import org.eclipse.jface.util.Throttler;
2931

3032
import org.eclipse.jface.text.IViewportListener;
3133
import org.eclipse.jface.text.source.ISourceViewer;
@@ -37,6 +39,8 @@
3739
*/
3840
public class StickyScrollingHandler implements IViewportListener {
3941

42+
private final static int THROTTLER_DELAY= 100;
43+
4044
private ISourceViewer sourceViewer;
4145

4246
private StickyScrollingControl stickyScrollingControl;
@@ -49,6 +53,10 @@ public class StickyScrollingHandler implements IViewportListener {
4953

5054
private StickyLinesProvider stickyLinesProvider;
5155

56+
private Throttler throttler;
57+
58+
private int verticalOffset;
59+
5260
/**
5361
* Creates a StickyScrollingHandlerIndentation that will be linked to the given source viewer.
5462
* The sticky scrolling will be computed by the default {@link StickyLinesProvider}.
@@ -73,6 +81,7 @@ public StickyScrollingHandler(ISourceViewer sourceViewer, IVerticalRuler vertica
7381
StickyLinesProvider stickyLinesProvider) {
7482
this.sourceViewer= sourceViewer;
7583

84+
throttler= new Throttler(sourceViewer.getTextWidget().getDisplay(), Duration.ofMillis(THROTTLER_DELAY), this::calculateAndShowStickyLines);
7685
this.stickyLinesProvider= stickyLinesProvider;
7786

7887
StickyScrollingControlSettings settings= loadAndListenForProperties(preferenceStore);
@@ -117,7 +126,15 @@ private StickyScrollingControlSettings loadSettings(IPreferenceStore store) {
117126
}
118127

119128
@Override
120-
public void viewportChanged(int verticalOffset) {
129+
public void viewportChanged(int newVerticalOffset) {
130+
if (this.verticalOffset == newVerticalOffset) {
131+
return;
132+
}
133+
verticalOffset= newVerticalOffset;
134+
throttler.throttledExec();
135+
}
136+
137+
private void calculateAndShowStickyLines() {
121138
List<StickyLine> stickyLines= stickyLinesProvider.get(verticalOffset, sourceViewer);
122139
stickyScrollingControl.setStickyLines(stickyLines);
123140
}
@@ -130,6 +147,7 @@ public void uninstall() {
130147
this.sourceViewer.removeViewportListener(this);
131148
preferenceStore.removePropertyChangeListener(propertyChangeListener);
132149
preferenceStore= null;
150+
throttler= null;
133151

134152
stickyScrollingControl.dispose();
135153
}

tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandlerTest.java

+28
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import static org.junit.Assert.assertEquals;
2222
import static org.junit.Assert.assertTrue;
2323
import static org.mockito.Mockito.mock;
24+
import static org.mockito.Mockito.times;
25+
import static org.mockito.Mockito.verify;
2426
import static org.mockito.Mockito.when;
2527

2628
import java.util.List;
@@ -121,6 +123,32 @@ public void testPreferencesUpdated() {
121123
assertEquals(expStickyLineText, stickyLineText.getText());
122124
}
123125

126+
@Test
127+
public void testThrottledExecution() throws InterruptedException {
128+
when(linesProvider.get(100, sourceViewer)).thenReturn(List.of(new StickyLine("line 10", 9)));
129+
130+
stickyScrollingHandler.viewportChanged(100);
131+
stickyScrollingHandler.viewportChanged(200);
132+
stickyScrollingHandler.viewportChanged(300);
133+
stickyScrollingHandler.viewportChanged(400);
134+
135+
waitInUi(200);
136+
137+
// Call to lines provider should be throttled
138+
verify(linesProvider, times(1)).get(100, sourceViewer);
139+
verify(linesProvider, times(0)).get(200, sourceViewer);
140+
verify(linesProvider, times(0)).get(300, sourceViewer);
141+
verify(linesProvider, times(1)).get(400, sourceViewer);
142+
}
143+
144+
private void waitInUi(int ms) throws InterruptedException {
145+
while (shell.getDisplay().readAndDispatch()) {
146+
}
147+
Thread.sleep(ms);
148+
while (shell.getDisplay().readAndDispatch()) {
149+
}
150+
}
151+
124152
private IPreferenceStore createPreferenceStore() {
125153
store = new PreferenceStore();
126154
store.setValue(EDITOR_TAB_WIDTH, 4);

0 commit comments

Comments
 (0)