Bug 74739 - Table getTopIndex does not return correct value after setTopIndex before shell is opened
Summary: Table getTopIndex does not return correct value after setTopIndex before shel...
Status: CLOSED DUPLICATE of bug 495909
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.0   Edit
Hardware: PC Linux-GTK
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Bogdan Gheorghe CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 202120 295666 (view as bug list)
Depends on:
Blocks: 74559
  Show dependency tree
 
Reported: 2004-09-22 19:39 EDT by Samantha Chan CLA
Modified: 2016-10-18 12:05 EDT (History)
7 users (show)

See Also:


Attachments
Testcase (5.17 KB, text/plain)
2004-09-22 19:40 EDT, Samantha Chan CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Samantha Chan CLA 2004-09-22 19:39:27 EDT
When running on Linux, calling getTopIndex after setting the top index does not 
immediately return the updated index.

In the attached testcase, the table's top index is set at 20.  I call 
getTopIndex right after the call, and the table returns 0.

When getting the top index after the scroll bar event after, the returned value 
is correct.

I ran the same testcase on Windowsl, and the table is able to return the 
correct value immediately.
Comment 1 Samantha Chan CLA 2004-09-22 19:40:56 EDT
Created attachment 14725 [details]
Testcase
Comment 2 Grant Gayed CLA 2004-09-23 09:59:32 EDT
Here's a smaller snippet that shows the difference; can we do anything here?

public static void main(String[] args) {
	Display display = new Display();
	Shell shell = new Shell(display);
	shell.setBounds(10,10,200,200);
	Table table = new Table(shell, SWT.NONE);
	table.setBounds(10,10,100,100);
	for (int i = 0; i < 99; i++) {
		new TableItem(table, SWT.NONE).setText("item " + i);
	}
	table.setTopIndex(20);
	System.out.println("top index before open: " + table.getTopIndex());
	shell.open();
	System.out.println("top index after open: " + table.getTopIndex());
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch()) display.sleep();
	}
	display.dispose();
}
Comment 3 Billy Biggs CLA 2004-09-23 10:09:31 EDT
This is similar to bug 26388 in that GtkTreeView does not perform scrolls
immediately, but queues them to occur in the idle loop.
Comment 4 Samantha Chan CLA 2004-09-28 10:12:50 EDT
Since this bug cannot be easily worked around by the Memory View and breaks 
major function in the view for Linux GTK, I am increasing its severity level.
Comment 5 Samantha Chan CLA 2004-12-08 18:17:14 EST
Hi -

I am just wondering if there is any update on this bug?  Is there a plan to fix 
this for 3.1?  

Thanks
Samantha
Comment 6 Silenio Quarti CLA 2004-12-09 10:37:05 EST
I am not sure there is a fix for this problem. We need to investigate more.
Comment 7 Samantha Chan CLA 2004-12-09 13:24:24 EST
Hi -

Please let me know as soon as possible if there is going to be a fix for it.  

By the way, is it possible to provide me with a work around?  Even if it's 
linux gtk specific?  Is there any event that I can listen to in order to figure 
out that the scrolling has actually happend?

Thanks in advance for your help.

Samantha
Comment 8 Steve Northover CLA 2004-12-13 14:57:42 EST
There is a work around but it is dangerous for application code.  If you do 
a "while (display.readAndDispatch());" right after you set the top index, then 
the value will be right.

Why is this dangerous?  By running an event loop, you dispatch all outstanding 
events.  This means that if the user had clicked on the close box of the shell 
while your program is running and you run an event loop, the shell will be 
disposed when the event loop returns.  This is just one example of how things 
can go wrong.
Comment 9 Samantha Chan CLA 2004-12-13 16:54:49 EST
Hi Steve -

Thanks for the workaround.  I have tried it out but it does not work.  Adding
that while loop right after the setTopIndex did not give me the right value.  In
fact, the table did not set the top table index at all.  The table remained at
row 0 after adding the while loop. 

Thanks
Samantha
Comment 10 Billy Biggs CLA 2004-12-14 00:26:53 EST
This bug is different than what I thought originally.  I believe now it is being
caused by a bug in GTK+.

On my machine using GTK+ 2.4.13, Table.getTopIndex() always returns the correct
value, but only after the shell is open.  The problem is that before the table
becomes visible, some internal state inside GtkTreeView is not being initialized
enough to give a correct response.  The following patch fixes this.  It is
sufficient to do a size_request on the GtkTreeView in order to work around the
problem.

The following patch successfully works around the problem for me.  It would be
better to figure out what the state is which is being set and see if there is a
more appropriate workaround.

Index: Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
===================================================================
RCS file: /home/eclipse/org.eclipse.swt/Eclipse
SWT/gtk/org/eclipse/swt/widgets/Table.java,v
retrieving revision 1.167
diff -u -r1.167 Table.java
--- Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java  5 Nov 2004 17:52:15
-0000       1.167
+++ Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java  14 Dec 2004 05:12:55 -0000
@@ -2293,6 +2293,8 @@
 public void setTopIndex (int index) {
        checkWidget();
        if (!(0 <= index && index < itemCount)) return;
+       GtkRequisition requisition = new GtkRequisition ();
+       OS.gtk_widget_size_request (handle, requisition);
        // FIXME - For some reason, sometimes the tree scrolls to the wrong place
        int /*long*/ path = OS.gtk_tree_model_get_path (modelHandle, _getItem
(index).handle);
        OS.gtk_tree_view_scroll_to_cell (handle, path, 0, true, 0, 0);
Comment 11 Steve Northover CLA 2004-12-14 11:42:22 EST
Here is the code that WORKSFORME:

public static void main(String[] args) {
	Display display = new Display();
	Shell shell = new Shell(display);
	shell.setBounds(10,10,200,200);
	Table table = new Table(shell, SWT.NONE);
	table.setBounds(10,10,100,100);
	for (int i = 0; i < 99; i++) {
		new TableItem(table, SWT.NONE).setText("item " + i);
	}
	table.setTopIndex(20);
	while (display.readAndDispatch());
	System.out.println("top index before open: " + table.getTopIndex());
	shell.open();
	System.out.println("top index after open: " + table.getTopIndex());
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch()) display.sleep();
	}
	display.dispose();
}

Are you absolutely sure that running an event loop doesn't fix the problem for 
you?  Can you confirm that Billy's patch does fix it?
Comment 12 Samantha Chan CLA 2004-12-14 14:37:04 EST
Hi Steve -

I tried your work around on a different machine and it works.
I have trouble finding source for Table.java.  So, I couldn't try out the patch.
 Please advise which plugin I should get in order to apply the patch.

Although the workaround works for getting top table index before the shell is
opened, I still have trouble getting the correct top index value as I scroll the
table.

In my testcase, I added a scrollbar selection event listener, and printed out
the top table index as I scroll up and down.  The getTopIndex call does not
always return the correct value.  Adding the event loop this time does not work.  

Thanks
Samantha



Here's my testcase:

public static void main(String[] args) {
	Display display = new Display();
	Shell shell = new Shell(display);
	shell.setBounds(10,10,200,200);
	Table table = new Table(shell, SWT.NONE);
	table.setBounds(10,10,100,100);
	for (int i = 0; i < 99; i++) {
		new TableItem(table, SWT.NONE).setText("item " + i);
	}
	table.setTopIndex(20);
	while (display.readAndDispatch());
	System.out.println("top index before open: " + table.getTopIndex());
	shell.open();
	System.out.println("top index after open: " + table.getTopIndex());

	ScrollBar bar = table.getVerticalBar();
	bar.addSelectionListener(new SelectionListener() {

	public void widgetSelected(SelectionEvent e) {
		while(display.readAndDispatch());
		System.out.println("scroll bar selection: " + table.getTopIndex());
	}

	public void widgetDefaultSelected(SelectionEvent e) {
	}});

	while (!shell.isDisposed()) {
		if (!display.readAndDispatch()) display.sleep();
	}
	display.dispose();
}
Comment 13 Billy Biggs CLA 2004-12-14 22:32:41 EST
Samantha, your test case works fine for me, at least, it works as I would expect.

When getTopIndex() does not return the correct value, what does it return?  Does
it return 0, or one less than what you would expect, or something not visible at
all?  The current implementation of getTopIndex() in SWT/GTK+ returns the index
of whatever item is at pixel 1,1 in the table, even if this is only half-visible
or mostly scrolled away.  Maybe this is not what you are expecting?
Comment 14 Samantha Chan CLA 2004-12-14 22:59:57 EST
The behaviour I am getting is not consistent with what I am getting from 
Windows.  I am expecting it to return the index of the top visible table item.  

When I scroll down, it continues to return the previous value.  (As you have 
stated, even if it is half-visible or not visible at all.)  I did not run into 
problems on Windows because Windows always scroll the table row by row.  Table 
items would never be half visible.  On GTK, scrolling the table does not 
necessary scroll up/down an entire row.  As a result, the result to getTopInex 
is not always as I would expect.

So, is this scrolling behaviour with GTK working as designed?  If so, how can I 
correctly determine the top visible item on the table?  Would it be possible to 
make the scrolling behaviour and the getTopIndex results consistent with 
Windows and Linux Motif?  (I am assuming that Motif works the same because my 
table viewer did not get into this problem with Linux Motif.)

Thanks
Samantha
Comment 15 Billy Biggs CLA 2004-12-15 00:18:36 EST
The code to change getTopIndex() to return the index of the first item that is
fully visible or "more than half visible" is not difficult.  I worry that this
would not really fix your problem if you rely on the top row always being aligned.

Not snapping the top row to the top of the table seems to be the native platform
behaviour on GTK+.
Comment 16 Samantha Chan CLA 2005-01-04 15:29:52 EST
I agree.  Returning a row that is half visible as top index will not fix my 
problem.  Is there a way to change the scrolling behaviour in the table?  i.e.  
Always have the table scroll by whole row?  Could there be a new attribute in 
the table, allowing clients to tell how a table should be scrolled?

I tried setting increment using Scrollbar.setIncrement(...).  However, calling 
this really has no effect to the scrolling on the table.
Comment 17 Billy Biggs CLA 2005-01-04 16:50:29 EST
The GTK+ tree and list widget does not support discrete scrolling, and I do not
believe it can be implemented using the GtkAdjustment API.  I opened this
enhancement request upstream:

  http://bugzilla.gnome.org/show_bug.cgi?id=162957
Comment 18 Steve Northover CLA 2005-01-05 09:25:22 EST
BB to determine whether we need to change getTopIndex().  Could Samantha 
use "setTopIndex(getTopIndex())" to ensure that the top index is discrete?
Comment 19 Samantha Chan CLA 2005-01-05 10:31:28 EST
Sorry, what am I supposed to check?  Did you want me to make sure that 
setTopIndex(getTopIndex) sets the top index of the table properly and 
immediately?

One note about the scrolling behaviour in the table.  I understand that you 
need GTK+ tree to fix the fundamental problem.  But, I notice a setIncrement 
method from Scrollbar allowing clients to control how much to scroll when the 
up or down arrow is pressed.  To work around the problem in the meantime, could 
I set this attribute in the scrollbar to force the scrollbar to scroll the 
table row by row?  Also, what am I supposed to put for the argument of the 
setIncrement method?  Is it treating the argument as pixels? or number of rows 
in a table?  I tried playing with the method a little, but setting the 
increment has no effect at all. (both on Linux GTK and Windows)
Comment 20 Kevin Haaland CLA 2005-01-13 14:43:24 EST
SN says "Billy to fix". 
Comment 21 Billy Biggs CLA 2005-01-18 12:32:27 EST
I would like to see the bug in Eclipse.  Can you please tell me how to see it in
action?  I cannot seem to make it do anything.
Comment 22 Samantha Chan CLA 2005-01-18 12:59:30 EST
Hi Billy -

What are you trying to see?  are you trying to see example of the table's top 
index not returning the correct value in Eclipse?  i.e.  you need help trying 
to get the Memory View to work?  or do you need another small testcase?

Thanks
Samantha
Comment 23 Billy Biggs CLA 2005-01-18 13:45:41 EST
I would like to see an example of the memory view and how it does scrolling. 
How do I get it to display something?
Comment 24 Samantha Chan CLA 2005-01-18 14:29:28 EST
Do you have CDT set up?  I think CDT supports the new Memory View.  Otherwise, 
I will have to try to get you a debug adapter for you to test the Memory View.
Comment 25 Billy Biggs CLA 2005-01-19 16:35:38 EST
A debug adapter would probably be easier for me, I do not have CDT set up here.
Comment 26 Billy Biggs CLA 2005-01-20 15:03:48 EST
This bug is getting confusing.

I opened bug 83335 about discrete scrolling in Table on Linux-GTK.  The original
snippet on this bug shows a problem with scrolling before the Table is visible.
 As there is a workaround available for this problem, I am lowering its
priority.  This bug will track the problem of getTopIndex not being valid until
after the Table is visible.

After playing with the Memory View, I cannot see exactly what problem this is
causing.  I am not sure that fixing this specific bug will help very much.  Feel
free though to file new bugs and describe how they are affecting this view's
behaviour (give steps to reproduce).
Comment 27 Samantha Chan CLA 2005-03-11 17:18:07 EST
Hi Billy -

As discussed in Eclipse Con.  The Memory View tries to load more data into the
table as the user scrolls up / down the view.  The view tries to maintain the
range of memory to display by getting the top index of the table.  From the top
index, the view figures out the top visible address from the memory block and
reloads the table accordingly.

On Linux GTK, when getTopIndex is called, the information always lags behind. 
The table will return its previous top index value even after the user has
scrolled away.  Consequently, the Memory View cannot determine the correct range
of memory to load into the view and the user will see the content of the view
jumping around.

As discussed with you, the work-around that you have provided is very risky. 
Running the event loop causes events to be fired unexpectedly.  You suggested
that I remove the work around from the view.  I have tried removing the work
around and again the table cannot return me a correct top index.

So, to clarify things, this bug should be about being able to get a correct top
index value from the table.  

Since I cannot use the work around, could you please increase the priority of
this bug and provide me with a less risky work-around?  

Thanks
Samantha
Comment 28 Praveen CLA 2010-02-11 10:53:36 EST
*** Bug 295666 has been marked as a duplicate of this bug. ***
Comment 29 Martin Domig CLA 2011-10-14 08:29:31 EDT
I have a very similar problem - but on Windows XP and Eclipse 3.7.

The following code triggers the bug:


void processUpdates() {
	Table table = (Table) viewer.getControl();
	int topIndex = table.getTopIndex();

	//table.setRedraw(false); // <-- without this it happens less often

	try {
		for (Runnable r : updateQueue) {
			r.run();
		}
	} finally {
		updateQueue.clear();
		table.setTopIndex(topIndex);
		//table.setRedraw(true);

		// this does not help either
		while (Display.getCurrent().readAndDispatch()) {
			;
		}

		int i = table.getTopIndex();
		if (i != topIndex) {
			System.err.println("have " + i + ", expected " + topIndex);
		}
	}
}


Update queue contains a list of runnables that add, replace or remove elements on the table viewer. The table contains the same amount of elements after the queue finished processing.

I would like to add that the second getTopIndex() returns the value that is actually correct in respect to what is visible in the UI. That is: 
1. Table has 40 elements, 5 are visible in the table. getTopIndex is 0 (correct)
2. I scroll down to the 20th element. getTopIndex is 20 (correct)
3. The update queue executes, removing all elements and re-adding them to the table viewer so that it again contains 40 elements
4. I call setTopIndex(20) - but the table viewer actually scrolls to some arbitrary position between 0 and 20.
5. getTopIndex() returns that arbitrary value, which is what is really visible in the table - but not what I set before.
Comment 30 Eric Williams CLA 2016-10-18 12:00:36 EDT
*** Bug 202120 has been marked as a duplicate of this bug. ***
Comment 31 Eric Williams CLA 2016-10-18 12:05:18 EDT
This issue has been fixed in bug 495909.

*** This bug has been marked as a duplicate of bug 495909 ***