Skip to content

Commit 5686df7

Browse files
Fix sticky scroll height calculation for variable line heights
When emoji or other content affects line heights, sticky scroll was calculating the total height wrong by assuming all lines were the same. Now it gets the actual height for each line instead. Also fixes the height check for limiting visible lines.
1 parent 1e6a7c9 commit 5686df7

2 files changed

Lines changed: 34 additions & 2 deletions

File tree

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,10 @@ private void calculateAndSetStickyLinesCanvasBounds() {
331331
StyledText textWidget= sourceViewer.getTextWidget();
332332

333333
int numberStickyLines= getNumberStickyLines();
334-
int lineHeight= stickyLineText.getLineHeight() * numberStickyLines;
334+
int lineHeight = 0;
335+
for (int i = 0; i < numberStickyLines; i++) {
336+
lineHeight += stickyLineText.getLineHeight(stickyLineText.getOffsetAtLine(i));
337+
}
335338
int spacingHeight= stickyLineText.getLineSpacing() * (numberStickyLines - 1);
336339
int separatorHeight= bottomSeparator.getBounds().height;
337340

@@ -450,7 +453,8 @@ private boolean areStickyLinesOutDated(StyledText textWidget) {
450453
}
451454

452455
private void limitVisibleStickyLinesToTextWidgetHeight(StyledText textWidget) {
453-
int lineHeight= textWidget.getLineHeight() + textWidget.getLineSpacing();
456+
int topOffset = textWidget.getOffsetAtLine(textWidget.getTopIndex());
457+
int lineHeight = textWidget.getLineHeight(topOffset) + textWidget.getLineSpacing();
454458
int textWidgetHeight= textWidget.getBounds().height;
455459

456460
int visibleLinesInTextWidget= textWidgetHeight / lineHeight;

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import static org.hamcrest.Matchers.greaterThan;
1818
import static org.junit.jupiter.api.Assertions.assertEquals;
1919
import static org.junit.jupiter.api.Assertions.assertFalse;
20+
import static org.junit.jupiter.api.Assertions.assertTrue;
2021
import static org.mockito.Mockito.mock;
2122
import static org.mockito.Mockito.when;
2223

@@ -236,6 +237,33 @@ void testStyling() {
236237
assertEquals(hoverColor, stickyLineText.getForeground());
237238
}
238239

240+
@Test
241+
void testCanvasBoundsHeightAdjustsForVariableLineHeights() {
242+
sourceViewer.getTextWidget().setBounds(0, 0, 200, 200);
243+
244+
// Step 1: Set 2 plain-text sticky lines and record canvas height
245+
List<IStickyLine> plainLines = List.of(new StickyLineStub("line 1", 0), new StickyLineStub("line 2", 1));
246+
stickyScrollingControl.setStickyLines(plainLines);
247+
Canvas stickyControlCanvas = getStickyControlCanvas(shell);
248+
int heightWithPlainText = stickyControlCanvas.getBounds().height;
249+
250+
// Step 2: Replace second sticky line with line requiring space
251+
Font largerFont = new Font(Display.getDefault(),
252+
new FontData(shell.getFont().getFontData()[0].getName(), 40, SWT.NORMAL));
253+
String bigText = "line 2 big"; //$NON-NLS-1$
254+
StyleRange bigFontRange = new StyleRange(0, bigText.length(), null, null);
255+
bigFontRange.font = largerFont;
256+
List<IStickyLine> linesWithLargerFont = List.of(new StickyLineStub("line 1", 0),
257+
new StickyLineStub(bigText, 1, new StyleRange[] { bigFontRange }));
258+
stickyScrollingControl.setStickyLines(linesWithLargerFont);
259+
int heightWithLargerFont = getStickyControlCanvas(shell).getBounds().height;
260+
261+
assertTrue(heightWithLargerFont > heightWithPlainText,
262+
"Canvas height must increase when one sticky line has a larger font"); //$NON-NLS-1$
263+
264+
largerFont.dispose();
265+
}
266+
239267
@Test
240268
void testLayoutStickyLinesCanvasOnResize() {
241269
sourceViewer.getTextWidget().setBounds(0, 0, 200, 200);

0 commit comments

Comments
 (0)