Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 333805

Summary: [3.6.2] Inconsistent handling of Tree client area when scrolling under MacOSX Cocoa
Product: [Eclipse Project] Platform Reporter: Scott Kovatch <skovatch>
Component: SWTAssignee: Scott Kovatch <skovatch>
Status: RESOLVED INVALID QA Contact:
Severity: normal    
Priority: P3 CC: nyssen, peter, skovatch
Version: 3.6.1Flags: skovatch: review? (Silenio_Quarti)
Target Milestone: ---   
Hardware: PC   
OS: Mac OS X   
Whiteboard:
Bug Depends on: 333375    
Bug Blocks: 332956    

Description Scott Kovatch CLA 2011-01-08 19:01:43 EST
+++ This bug was initially created as a clone of Bug #333375 +++

Using the following snippet, one can reproduce (by dragging the first tree item downwards to that the tree starts scrolling) that on Windows XP the client area's y coordinate remains unchanged during the scroll operation, while on MacOSX Cocoa, the y coordinate is indeed increased.

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

public class Bug332956 {

	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		final Tree tree = new Tree(shell, SWT.MULTI | SWT.H_SCROLL
				| SWT.V_SCROLL);
		for (int i = 0; i < 20; i++) {
			TreeItem iItem = new TreeItem(tree, 0);
			iItem.setText("TreeItem (0) -" + i);
			for (int j = 0; j < 4; j++) {
				TreeItem jItem = new TreeItem(iItem, 0);
				jItem.setText("TreeItem (1) -" + j);
				for (int k = 0; k < 4; k++) {
					TreeItem kItem = new TreeItem(jItem, 0);
					kItem.setText("TreeItem (2) -" + k);
					for (int l = 0; l < 4; l++) {
						TreeItem lItem = new TreeItem(kItem, 0);
						lItem.setText("TreeItem (3) -" + l);
					}
				}
			}
		}
		DragSource ds = new DragSource(tree, DND.DROP_COPY | DND.DROP_MOVE
				| DND.DROP_LINK);
		ds.setTransfer(new Transfer[] { TextTransfer.getInstance() });
		ds.addDragListener(new DragSourceListener() {

			public void dragStart(DragSourceEvent event) {
				// System.out.println("drag started " + event);
			}

			public void dragSetData(DragSourceEvent event) {
				// System.out.println("drag set data " + event);
				event.data = "Test";
			}

			public void dragFinished(DragSourceEvent event) {
				// System.out.println("drag finished " + event);
			}
		});

		DropTarget dt = new DropTarget(tree, DND.DROP_COPY | DND.DROP_MOVE
				| DND.DROP_LINK);
		dt.setTransfer(new Transfer[] { TextTransfer.getInstance() });
		dt.addDropListener(new DropTargetListener() {
			public void dragEnter(DropTargetEvent event) {
				// System.out.println("drag enter " + event);
			}

			public void dragLeave(DropTargetEvent event) {
				// System.out.println("drag leave " + event);
			}

			public void dragOperationChanged(DropTargetEvent event) {
				// System.out.println("drag operation changed " + event);
			}

			public void dragOver(DropTargetEvent event) {
				// System.out.println("drag over " + event);
				event.feedback = DND.FEEDBACK_SCROLL | DND.FEEDBACK_EXPAND;
				System.out.println("CLIENT AREA: " + tree.getClientArea());
			}

			public void drop(DropTargetEvent event) {
				// System.out.println("drop " + event);
			}

			public void dropAccept(DropTargetEvent event) {
				// System.out.println("drop accept " + event);
			}
		});

		shell.setSize(200, 200);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
}

I assume that the behavior on other platforms is the same as on Windows XP, because GEF bug #332956, which is indirectly caused by this misbehavior on MacOSX Cocoa, does not seem to occur on any other platforms.
Comment 1 Scott Kovatch CLA 2011-01-08 19:04:15 EST
current version of Scrollable#getClienetArea():

public Rectangle getClientArea () {
	checkWidget();
	if (scrollView != null) {
		NSSize size = scrollView.contentSize();
		NSClipView contentView = scrollView.contentView();
		NSRect bounds = contentView.bounds();
		return new Rectangle((int)bounds.x, (int)bounds.y, (int)size.width, (int)size.height);
	} else {
		NSRect rect = view.bounds();
		return new Rectangle(0, 0, (int)rect.width, (int)rect.height);
	}
}

-----------------
New version of Scrollable#getClientArea():

public Rectangle getClientArea () {
	checkWidget();
	if (scrollView != null) {
		NSSize size = scrollView.contentSize();
		return new Rectangle(0, 0, (int)size.width, (int)size.height);
	} else {
		NSRect rect = view.bounds();
		return new Rectangle(0, 0, (int)rect.width, (int)rect.height);
	}
}
Comment 2 Alexander Nyßen CLA 2011-01-10 15:14:04 EST
I assume this one should be reverted as well, right?
Comment 3 Scott Kovatch CLA 2011-01-10 15:16:52 EST
Correct, now that we understand it better.
Comment 4 Alexander Nyßen CLA 2011-01-10 15:38:44 EST
(In reply to comment #3)
> Correct, now that we understand it better.
 
Yes, the fog has somewhat "burned off". And as the GEF problem is finally resolved, the effort was not completely gratuitous in the end. So nevertheless thanks for having supported this.