diff options
author | Thomas Wolf | 2019-09-25 12:28:06 +0000 |
---|---|---|
committer | Thomas Wolf | 2019-09-26 09:02:37 +0000 |
commit | df1e7b42cac6edfefe6e878270760e0094ca6341 (patch) | |
tree | 2aa23329e681913eebbfd7591ca52f6b4e252c6a | |
parent | e952a5caacf1657d1fafab22e3ee89f32cf3548b (diff) | |
download | eclipse.platform.text-df1e7b42cac6edfefe6e878270760e0094ca6341.tar.gz eclipse.platform.text-df1e7b42cac6edfefe6e878270760e0094ca6341.tar.xz eclipse.platform.text-df1e7b42cac6edfefe6e878270760e0094ca6341.zip |
Bug 551320 - Fix missing line numbers on GTK with static scrollbarsI20191002-0100I20191001-1800I20190930-1800
On GTK with static scrollbars the ruler canvas is higher than the
visual text area (text viewer minus horizontal scrollbar height).
JFaceTextUtil.getVisibleModelLines() sometimes returns a bottom model
line that actually ends above the lower edge of the ruler canvas. When
that occurred, subsequent scrolling down in the text could lead to
missing line numbers.
Account for that by considering only pixels up to the bottom line's
bottom, and clearing the rest of the canvas.
(Note: on Mac with static scroll bars, the ruler canvas ends at the
top of the horizontal scrollbar and thus always has the same height
as the visible text area, and hence this problem doesn't occur.)
Verified manually on OS X and on Linux/GTK with both static and
dynamic scrollbars and found no rendering problems.
Change-Id: Iaf7bd4627594590e9e421b48c6de99578927625a
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r-- | org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java index 5dd81e12323..f7654cd222f 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -389,6 +389,8 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn { private int fLastNumberOfLines; /** Last bottom model line. */ private int fLastBottomModelLine; + /** Last canvas height used. */ + private int fLastHeight= -1; /** * Redraw runnable lock * @since 3.0 @@ -696,25 +698,40 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn { int bufferH= size.y; int numberOfLines= visibleLines.getNumberOfLines(); int dy= topPixel - fLastTopPixel; - if (dy != 0 && bufferStillValid && fLastTopPixel >= 0 && numberOfLines > 1 && numberOfLines == fLastNumberOfLines) { - if (dy > 0 && dy < size.y) { - bufferGC.copyArea(0, dy, size.x, size.y - dy, 0, 0); - bufferY= size.y - dy; - bufferH= size.y - bufferY; - } else if (dy < 0 && -dy < size.y) { - bufferGC.copyArea(0, 0, size.x, size.y + dy, 0, -dy); + int topModelLine= visibleLines.getStartLine(); + int bottomModelLine= topModelLine + numberOfLines - 1; + int bottomWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, bottomModelLine); + boolean atEnd= bottomWidgetLine + 1 >= fCachedTextWidget.getLineCount(); + int height= size.y; + if (dy != 0 && !atEnd && bufferStillValid && fLastTopPixel >= 0 && numberOfLines > 1 && numberOfLines == fLastNumberOfLines) { + int bottomPixel= fCachedTextWidget.getLinePixel(bottomWidgetLine + 1); + if (dy > 0 && bottomPixel < size.y) { + // Can occur on GTK with static scrollbars; see bug 551320. + height= bottomPixel; + } + if (dy > 0 && dy < height) { + int goodPixels= height; + if (goodPixels > fLastHeight) { + // Dont copy empty pixels from last time. + goodPixels= fLastHeight; + } + bufferGC.copyArea(0, dy, size.x, goodPixels - dy, 0, 0); + bufferY= goodPixels - dy; + bufferH= height - bufferY; + } else if (dy < 0 && -dy < height) { + bufferGC.copyArea(0, 0, size.x, height + dy, 0, -dy); bufferY= 0; bufferH= -dy; } else { + height= size.y; dy= 0; } } else { dy= 0; } // dy == 0 means now "draw everything", either because there was no overlap, or we indeed didn't move - // (refresh or other cases), or there was a resize, or it's the first time. - int topModelLine= visibleLines.getStartLine(); - int bottomModelLine= topModelLine + numberOfLines - 1; + // (refresh or other cases), or there was a resize, or it's the first time, or we are showing the very + // last line. if (dy != 0) { // Reduce the line range. if (dy > 0) { @@ -727,21 +744,29 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn { fLastTopModelLine= topModelLine; fLastNumberOfLines= numberOfLines; fLastBottomModelLine= bottomModelLine; + fLastHeight= height; if (dy != 0) { // Some rulers may paint outside the line region. Let them paint in a new image, // the copy the wanted bits. newBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); GC localGC= new GC(newBuffer); try { - initializeGC(localGC, fCanvas.getFont(), 0, bufferY, size.x, bufferH); + initializeGC(localGC, 0, bufferY, size.x, bufferH); doPaint(localGC, visibleLines); } finally { localGC.dispose(); } bufferGC.drawImage(newBuffer, 0, bufferY, size.x, bufferH, 0, bufferY, size.x, bufferH); + if (dy > 0 && bufferY + bufferH < size.y) { + // Scrolled down in the text, but didn't use the full height of the Canvas: clear + // the rest. Occurs on GTK with static scrollbars; the area cleared here is the + // bit next to the horizontal scrollbar. See bug 551320. + bufferGC.setBackground(getBackground(fCanvas.getDisplay())); + bufferGC.fillRectangle(0, bufferY + bufferH, size.x, size.y - bufferY - bufferH + 1); + } } else { // We redraw everything; paint directly into the buffer - initializeGC(bufferGC, fCanvas.getFont(), 0, 0, size.x, size.y); + initializeGC(bufferGC, 0, 0, size.x, size.y); doPaint(bufferGC, visibleLines); } } finally { @@ -753,8 +778,8 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn { dest.drawImage(fBuffer, 0, 0); } - private void initializeGC(GC gc, Font font, int x, int y, int width, int height) { - gc.setFont(font); + private void initializeGC(GC gc, int x, int y, int width, int height) { + gc.setFont(fCanvas.getFont()); if (fForeground != null) { gc.setForeground(fForeground); } |