Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 334234 - [Viewers] TableViewer scrolls the leftmost column into view unexpectedly
Summary: [Viewers] TableViewer scrolls the leftmost column into view unexpectedly
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.6.1   Edit
Hardware: PC Windows 7
: P3 normal with 14 votes (vote)
Target Milestone: 4.5.1   Edit
Assignee: Hendrik Peilke CLA
QA Contact: Niraj Modi CLA
URL:
Whiteboard:
Keywords:
: 434399 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-01-13 04:54 EST by Thomas Franken CLA
Modified: 2015-08-04 10:29 EDT (History)
14 users (show)

See Also:
niraj.modi: review+


Attachments
Snippet based on Tom Schindl's Snippet036 to reproduce the problem (5.63 KB, application/octet-stream)
2011-03-11 06:12 EST, Thomas Haskes CLA
no flags Details
Potential patch (932 bytes, patch)
2013-11-07 10:26 EST, Niraj Modi CLA
no flags Details | Diff
patch to the issue (1.45 KB, patch)
2015-05-13 07:02 EDT, Hendrik Peilke CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Franken CLA 2011-01-13 04:54:17 EST
Build Identifier: 20100917-0705

This problem arrises at anytime when a TableViewer is used in combination with a TableViewerEditor and a FocusCellManager. Under certain circumstances described in the following clicking into a viewer cell makes the TableViewer unexceptedly and undesiredly scroll in horizontally the leftmost column after a short delay (maybe due to a runnable in a display.asyncExec). Especially when one wants to edit a cell this problem makes it in this case impossible, since the cell editor is closed and the viewer view scrolls. In the case the cell can be scrolled totally out of view area of the table viewer.

To reproduce the problem one precondition is that the columns of the TableViewer don't fit into visible area. So the horizonzal scrollbar becomes visible. The visible view has been scrolled to the right such that the left border of the visible area does not match with the left border of the first column. Then one has the give one cell the focus, e.g. by clicking into a cell.
Now the described problem arrised when one single or double clicks a horizontal neighbouring cell.

As example one could use the snippet Snippet036FocusBorderCellHighlighter from Tom Schindl and introduce a few additional columns.
 
I could observe the problem with Helios 3.6.1 on Windows 7, but it
seems to be in jface/swt issue for a long time and affects that least
WinXP too.

Thanks in advance for any ideas regarding this issue.


Reproducible: Always

Steps to Reproduce:
1. Run any snippet with a TableViewer (with enough columns) with a TableViewerEditor and a FocusCellManager, e.g. Snippet036FocusBorderCellHighlighter from Tom Schindl
2. Scroll in column horizontal not invisible  
3. Click into a cell and then click into a neighbor cell in the same row
Comment 1 Thomas Franken CLA 2011-01-13 04:55:35 EST
corrected eclipse version to this bug entry
Comment 2 Thomas Haskes CLA 2011-03-11 06:12:48 EST
Created attachment 190971 [details]
Snippet based on Tom Schindl's Snippet036 to reproduce the problem

The snippet reproduces the problem. 
Run the snippet, scroll to the right to get the first columns out of the visible area. Click any cell. Click a neighbouring cell of the currently active in the same row. Wait 1 second. See the scrollbar jumping to the first column again.

Hope that helps identifying the problem. The current behavior is really annoying and a big problem for the usage of tableViewers that configured that way in production.

Greets, Tom
Comment 3 Oleg Besedin CLA 2011-04-12 15:38:46 EDT
This seems to be a result of OS.LVM_ENSUREVISIBLE sent to SWT's Table control,

Table#showItem(int index) {
...
	OS.SendMessage (handle, OS.LVM_ENSUREVISIBLE, index, 0);
}

If I alter Table#callWindowProc() to swallow OS.LVM_ENSUREVISIBLE then the problem goes away.
Comment 4 Thomas Haskes CLA 2012-07-13 03:18:09 EDT
I would like to try proposing a patch for this, but i want the altered code only to be run if the running windows version is higher than XP (my assumption is that the code causing the problem is necessary on XP to let the tableViewer work correctly, but causing problems in higher Windows versions, actually, a comment says that the code is a workaround for a bug in XP, so it seems that MS fixed the problem in higher Windows versions) . Till now I could not figure out how to do that. Can anyone give a hint on this?

What I need would be something like:

if (isWindowsVersionHigherThanXP()) {
// code fixing the problem
}

Thanks
Comment 5 Thomas Franken CLA 2012-07-27 02:39:28 EDT
Hello Thomas,

 since we are speeking about a bug within the Windows specific SWT implementation (org.eclipse.swt.win32.XXX plugin), i think the preferred way to detect a windows operating system would be the following 


  import org.eclipse.swt.internal.win32.OS; 

  ... 

  if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) 
  {
      // this is a post Windows XP operating system,
      // and also not a Windows Embedded CE System
      // operating system with a version >= 6

      // code fixing the problem
  }

 I am not quite sure if the win32 swt plugin supports WinCE Operating Systems at all, so the check !OS.IsWinCE could probably be omitted as well.

Kind Regards
Comment 6 Thomas Haskes CLA 2012-12-05 08:01:08 EST
I dont knoh how to generate a proper patch, so I post my fix directly here. Changing the method Tabe#showItem in the following way fixed the problem (as far as Is can see). Hope that helps other having the same problems. Patching org.eclipse.swt.win32.win32.x86 was quite easy:

void showItem (int index) {
	if (!painted && hooks (SWT.MeasureItem)) {
		hitTestSelection (index, 0, 0);
	}
	/*
	* Bug in Windows.  For some reason, when there is insufficient space
	* to show an item, LVM_ENSUREVISIBLE causes blank lines to be
	* inserted at the top of the widget.  A call to LVM_GETTOPINDEX will
	* return a negative number (this is an impossible result).  The fix
	* is to use LVM_GETCOUNTPERPAGE to detect the case when the number
	* of visible items is zero and use LVM_ENSUREVISIBLE with the
	* fPartialOK flag set to true to scroll the table.
	*/
	if (OS.SendMessage (handle, OS.LVM_GETCOUNTPERPAGE, 0, 0) <= 0) {
		/*
		* Bug in Windows.  For some reason, LVM_ENSUREVISIBLE can
		* scroll one item more or one item less when there is not
		* enough space to show a single table item.  The fix is
		* to detect the case and call LVM_ENSUREVISIBLE again with
		* the same arguments.  It seems that once LVM_ENSUREVISIBLE
		* has scrolled into the general area, it is able to scroll
		* to the exact item.
		*/
		OS.SendMessage (handle, OS.LVM_ENSUREVISIBLE, index, 1);
		if (index != OS.SendMessage (handle, OS.LVM_GETTOPINDEX, 0, 0)) {
			OS.SendMessage (handle, OS.LVM_ENSUREVISIBLE, index, 1);
		}
	} else {
                  // FIX STARTS HERE
		  if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0))
		  {
		      // This is a post Windows XP operating system,
		      // and also not a Windows Embedded CE System
		      // operating system with a version >= 6.

		      // On those systems, the call to OS.LVM_ENSUREVISIBLE
		      // causes the table to scroll to the leftmost column
		      // unexpectedly. Just return here then.
			  return;
		  } else {
                  // END OF FIX
			  OS.SendMessage (handle, OS.LVM_ENSUREVISIBLE, index, 0);
		  }
	}
}
Comment 7 Thomas Haskes CLA 2012-12-05 08:03:42 EST
Sorry for the typos. And thanks to Oleg and Thomas their input on this.

Later,

Tom
Comment 8 Cosmin Ghita CLA 2013-10-26 02:39:28 EDT
This is a very annoying bug and I could not find any workaround.
When it will be fixed?
Thanks!
PS: I have debugged like crazy just to see if I can fix this from my code and so far I did not find any solution. I would really appreciate if this can be fix ASAP as we are  using the cell editor in many places in our RCP application.
Comment 9 Andreas Kozma CLA 2013-10-30 10:53:38 EDT
Dear All, 
this bug is a blocker in our RCP Application. It seems to be rather easy to fix. Why has nobody bothered incorporating the proposed fix?

Thanks for any action taken!
Comment 10 Lakshmi P Shanmugam CLA 2013-10-31 06:09:34 EDT
Niraj, can you please try this?
Comment 11 Niraj Modi CLA 2013-11-07 10:26:48 EST
Created attachment 237281 [details]
Potential patch

Added check for OS versions.
Comment 12 Arun Thondapu CLA 2013-11-08 13:18:15 EST
(In reply to Niraj Modi from comment #11)
> Created attachment 237281 [details]
> Potential patch
> 
> Added check for OS versions.

Niraj, I took a look at the patch, please see my comments below:

1) Use block comment syntax /*...*/ for multi-line comments

2) Typo in comment at OS.LVM_ENSUREVISIBL

3) In general, match code styling according to the style of code being followed in the surrounding code. Specifically, notice that there should be a space between the method name and the parentheses surrounding the parameters here.

4) Please mention whether all JUnit tests passed successfully and also what kind of testing was done to verify the patch (what examples or snippets were used for example).

5) After applying this patch, Table#showItem() would probably not do anything when running on Windows versions post XP. I'm wondering if that might cause problems in some scenarios. Make sure you test with a scenario where showItem() is invoked on a TableItem that is completely hidden from view and then confirm whether the Table scrolls to make the item visible. I suspect that may not happen since Table#showItem() would simply return on Windows 7.

Thanks!
Comment 13 Thomas Haskes CLA 2013-11-13 02:57:01 EST
(In reply to Arun Thondapu from comment #12)
> 5) After applying this patch, Table#showItem() would probably not do
> anything when running on Windows versions post XP. I'm wondering if that
> might cause problems in some scenarios. Make sure you test with a scenario
> where showItem() is invoked on a TableItem that is completely hidden from
> view and then confirm whether the Table scrolls to make the item visible. I
> suspect that may not happen since Table#showItem() would simply return on
> Windows 7.

You are right, this patch does in fact break vertical scrolling if the scrolling is done by keyboard, e.g. using the ARROW_DOWN or ARROW_UP key.

In my use case I managed to get aroung that by letting the CellEditor handle the key events and scroll the table manually using

int topIndex = this.table.getTopIndex();
if (topIndex + getVisibleRows() <= this.table.getSelectionIndex()) {
    this.table.setTopIndex(topIndex + 1);
}

and

private int getVisibleRows() {
    Rectangle clientArea = this.table.getClientArea();
    int itemHeight = this.table.getItemHeight();
    int headerHeight = this.table.getHeaderHeight();
    int visibleCount = (clientArea.height - headerHeight + itemHeight - 1)/     itemHeight;
    // return one row less because when horizontal scroll bar is showing,
    // the row is may be half visible
    return visibleCount - 1;
}

This works in my use case as we have CellEditors that are always active. In other use cases where the CellEditor is not always active, this might be a problem. 
Maybe there is a way to put the code above to some place in the Table class where the ARROW key events are handled. This would make the fix complete.

I could not find out where the right place for that might be so that it fits every scenario. I find the platform specific code really hard to understand.
Comment 14 Arun Thondapu CLA 2014-05-09 11:32:48 EDT
*** Bug 434399 has been marked as a duplicate of this bug. ***
Comment 15 Joerg Buchberger CLA 2015-04-21 10:55:27 EDT
We have this problem, too, in our e4.3 RCP application.

Since, there is no fix in current releases, what are you recommending?
Applying the patch? And rebuilding the swt.win32 bundle ourselves?

We already have a couple of customized eclipse bundles in our target platform due to other problems and limitations and slowly but surely this makes it harder and harder to follow eclipse updates, because of the cost involved to merge and review these changes.
Comment 16 Niraj Modi CLA 2015-04-22 05:42:33 EDT
(In reply to Joerg Buchberger from comment #15)
> We have this problem, too, in our e4.3 RCP application.
> 
> Since, there is no fix in current releases, what are you recommending?
> Applying the patch? And rebuilding the swt.win32 bundle ourselves?
> 
> We already have a couple of customized eclipse bundles in our target
> platform due to other problems and limitations and slowly but surely this
> makes it harder and harder to follow eclipse updates, because of the cost
> involved to merge and review these changes.

Which patch are you referring here.. as the associated(attachment 237281 [details]) patch on this bug is incomplete and has side-effects.
Comment 17 Hendrik Peilke CLA 2015-05-13 07:02:49 EDT
Created attachment 253437 [details]
patch to the issue

This patch solves the described issue by checking if the index given is already visible. This is the case where the problem occurs. If an item is half visible on the bottom, the behavior is correct. If the item is already visible,  LVM_ENSUREVISIBLE is not called. This works perfectly for me and I have not experienced any side effects yet.
Comment 18 Hendrik Peilke CLA 2015-06-26 03:14:40 EDT
Can the target milestone please be moved to 4.5.1?

Thanks, 
Hendrik
Comment 19 Niraj Modi CLA 2015-06-26 03:37:46 EDT
(In reply to Hendrik Peilke from comment #18)
> Can the target milestone please be moved to 4.5.1?
> 
> Thanks, 
> Hendrik

Yes, we will validate & release the fix to 4.6 branch first, followed by back-port to 4.5.1
Comment 20 Niraj Modi CLA 2015-07-16 04:15:45 EDT
(In reply to Hendrik Peilke from comment #17)
> Created attachment 253437 [details]
> patch to the issue
> 
> This patch solves the described issue by checking if the index given is
> already visible. This is the case where the problem occurs. If an item is
> half visible on the bottom, the behavior is correct. If the item is already
> visible,  LVM_ENSUREVISIBLE is not called. This works perfectly for me and I
> have not experienced any side effects yet.

Thanks Hendrik for suggesting the fix.
- added check for Windows OS version to be Vista and above
- modified your patch to be 64/32 bit compatible and updated comments

Tested and pushed final changes to master via below git commit:
http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=9f1b63d2117e81a67ce4d2e6a151482a712673e3
Comment 21 Niraj Modi CLA 2015-07-23 09:40:22 EDT
Hi Arun: For your review, to be back-ported to 4.5.1
Comment 22 Niraj Modi CLA 2015-08-04 10:16:41 EDT
Verified the fix in 4.6 I-build: I20150803-2000
Comment 23 Niraj Modi CLA 2015-08-04 10:29:25 EDT
Back-ported this bug fix to 4.5.1 branch, via below git commit:
http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?h=R4_5_maintenance&id=e93cc9585134967a74c41f976f4fe2ee20bb4c16