Project: SWT
Bug 294171 Scrolling causes flush of all paint events.
Reported: 2009-11-04 04:24:00 | Status: resolved fixed

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 Build Identifier: I have following problem. Within a resize listener's handleEvent() method, i'm calling twice Canvas.scroll(). The areas scrolled are distincted. So what i would expect is that calling scroll() the second time do not trigger a paint event since there is nothing to be repainted. But that's not the case. The Javadoc of the method says: "In addition, outstanding paint events are flushed before the source area is copied to ensure that the contents of the canvas are drawn correctly. ". This is somewhat misleading since it does not really say that all events are flushed. Even those that does not intersect the area to scroll. I would suggest to precise the javadoc or better only trigger paint events that intersect the area to scroll. Reproducible: Always Steps to Reproduce: import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; public class CanvasScrollReproducer { public static void main(final String[] args) { final Display display = new Display(); final Shell shell = new Shell(display); shell.setLayout(new FillLayout()); shell.setSize(640, 480); final Canvas canvas = new Canvas(shell, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.DOUBLE_BUFFERED); canvas.addListener(SWT.Paint, new Listener() { public void handleEvent(final Event event) { System.out.println(event.gc.getClipping()); final Color color = new Color(display, (int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255)); try { event.gc.setBackground(color); event.gc.fillRectangle(canvas.getClientArea()); } finally { color.dispose(); } } }); canvas.addListener(SWT.Resize, new Listener() { private Rectangle oldArea = null; public void handleEvent(final Event event) { if (this.oldArea != null) { final Rectangle newClientArea = canvas.getClientArea(); final int xDiff = newClientArea.width - this.oldArea.width; final int destX = xDiff; final int x = 0; int width = this.oldArea.width; width = newClientArea.width; int height = this.oldArea.height; height = newClientArea.height; System.out.println("scroll 1"); canvas.scroll(destX, 19, x, 19, width, height - 19, true); System.out.println("scroll 1 done"); System.out.println("scroll 2"); canvas.scroll(destX, 0, x, 0, width, 18, true); System.out.println("scroll 2 done"); } this.oldArea = canvas.getClientArea(); } }); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } }

Files changed in fix:
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java