Bug 563232 - [GTK] Tree.getTopItem often returns the selected item, not the item at the top
Summary: [GTK] Tree.getTopItem often returns the selected item, not the item at the top
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.15   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-05-15 14:28 EDT by Pascal Muetschard CLA
Modified: 2020-10-15 18:36 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pascal Muetschard CLA 2020-05-15 14:28:08 EDT
This becomes apparent in trying out: https://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet254.java

Steps to reproduce:
1) run the above snippet
2) select the last item visible
3) click the button

Expected Result:
The button should say that 10 items are visible.

Actual Result:
The button says that only 1 item is visible.

This is due to the fact that getTopItem(), which is called when the button is clicked, returns the selected item, instead of the expected top item.

Looking at the code, I see these issues:
1) The first thing done in getTopItem() is comparing the current scroll offset to a cached offset stored in a member variable. This cached offset is only set in setTopItem(). However, since the value is default initialized to 0, if the view is not scrolled, it will match the the current offset, even if setTopItem is never called. The code then incorrectly uses _getCachedTopItem.

2) In _getCachedTopItem, if there is a selected item, it is retrieved and returned. The following code snippet:
if (topItem == treeSelection) {
  return topItem;
} else {
  return treeSelection;
}
Is equivalent to "return treeSelection;" and doesn't make sense. Why does it return the selected item?

3) The assumption that caching the last scroll offset from when setTopItem() was called is invalid: imagine setTopItem is called, the user scrolls up, expands an item above the item from setTopItem before, and scrolls back to a spot with the same offset as was cached. The cached topItem is no longer the top item, but would be returned (if there is no selection, or if 2) gets fixed).

4) Caching the top item from setTopItem is invalid: imagine a tree that is fully visible, calling setTopItem on any but the first item will cache the wrong top item. Since the tree is fully visible, calling setTopItem does not scroll the tree and has no effect, thus does not affect the top item.

The Windows and MacOS versions of the Tree do not have this issue and they all deal correctly with 4).
Comment 1 Andrey Loskutov CLA 2020-05-15 14:52:51 EDT
Pascal, thanks for detailed bug report. Could you provide a Gerrit patch (looks like you have some ideas hot to fix this bug)?
Comment 2 Pascal Muetschard CLA 2020-05-15 16:02:09 EDT
I don't have a setup where I can quickly do this, but I suppose I could try to go through the steps to check-out/modify/build SWT...

However, I also don't have a solution, except for just getting rid of the caching and always rely on GTK to compute the top item. I.e. deleting lines 2042-2060 (https://github.com/eclipse/eclipse.platform.swt/blob/master/bundles/org.eclipse.swt/Eclipse%20SWT/gtk/org/eclipse/swt/widgets/Tree.java#L2042) and then possibly cleaning up the now unused member variables used in the caching. Does that sound reasonable?
Comment 3 Joseph Benken CLA 2020-10-15 18:36:23 EDT
Looks like I can work around the issue by clearing the selection before calling getTopItem()?  I could save the selection and restore it afterwards?