Community
Participate
Working Groups
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.
Created attachment 14725 [details] Testcase
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(); }
This is similar to bug 26388 in that GtkTreeView does not perform scrolls immediately, but queues them to occur in the idle loop.
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.
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
I am not sure there is a fix for this problem. We need to investigate more.
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
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.
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
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);
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?
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(); }
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?
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
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+.
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.
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
BB to determine whether we need to change getTopIndex(). Could Samantha use "setTopIndex(getTopIndex())" to ensure that the top index is discrete?
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)
SN says "Billy to fix".
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.
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
I would like to see an example of the memory view and how it does scrolling. How do I get it to display something?
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.
A debug adapter would probably be easier for me, I do not have CDT set up here.
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).
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
*** Bug 295666 has been marked as a duplicate of this bug. ***
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.
*** Bug 202120 has been marked as a duplicate of this bug. ***
This issue has been fixed in bug 495909. *** This bug has been marked as a duplicate of bug 495909 ***