Community
Participate
Working Groups
Please place an option in the preferences for Code Assist which allows the developer to choose whether or not to have the content assist pop-up table use the SWT.VIRTUAL style. This is really a great feature to have on higher end machines: It makes the pop-up come up very quickly. However, on low end machines (like the one I'm working on), it causes a very long time lag in moving to a different set of completions. A good test example is with an instance of JFrame and trying to find a code assist option on one of the setters. On my Windows XP SP 2 machine, it takes between 5 and 10 seconds from when I enter the 's' character after the period until it actually finishes repopulating the code assist. I've been using Eclipse for a while, and I preferred the longer startup delay to a longer repopulation delay. If you could add a preference option to change this, it would be appreciated.
Please provide more details. - build id - more details about your machine - eventually more detailed steps to repdocue the problem see also: http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-text-home/development/bug-incomplete.htm
Eclipse 3.1 RC1 Win32. Windows XP SP 2 with all current updates Duel Processor 500 Mhtz 512 MB RAM 2 15 GB HD JDK1.5 (possibly .1? not sure. I know that sounds stupid but I'm really unsure about that) As for reproducing the error, it happens at every startup, all the time since M7
>JDK1.5 (possibly .1? not sure. I know that sounds stupid but I'm really unsure >about that) The link in comment 1 tells how to find out: - VM information - if not sure start eclipse using -vmargs -showversion >As for reproducing the error, it happens at every startup, all the time since M7 I don't see this. A step by step example that starts with a fresh workspace could help.
Definately 1.5 I tried to get you a step by step example with a fresh workspace but it seems that I can't reproduce the bug in a new workspace. I'm sorry to take up your time like this, but do you have any idea why my primary workspace would have this problem, and a new workspace wouldn't?
I think it's not new vs. existing but about how you've setup your existing workspace, build path, number of depending plug-ins etc.
Could you elaborate please? I'm not quite sure what I changed which could have effected CTabItem.
Did I mention CTabItem? I only said that what's in your workspace and how's it setup (build path) will affect performance and hence the steps how we could reproduce.
You know what, I'm terribly sorry. I got this bug report confused with another one I filed. :-) Whoops. Once again... 1) I start up Eclipse with a clean workspace 2) Switch to Java Perspective 3) Create new Java project "Test" (changed project compliance settings to 5.0) 4) Create new class file "Test.java" in the default package 5) Add javax.swing.* import 6) In the main method, add the code JFrame frame = new JFrame(); 7) type in frame.s (waiting for the content assist before typing 's') It took eight seconds for the content assist to rebuild itself for the 's' character. To be honest, I've never had that problem on Linux or on Mac. Actually, I've never had it on Windows either before RC1. Any thoughts?
Is it just the first time? We now do much mor stuff lazy and hence the Java model first needs to do some work. The SWT.VIRTUAL flag does not have that impact.
No actually, it happens every time the content assist comes up. BTW, I used JFrame just because it has a complex class hierarchy with numberous methods and fields. Thus, it takes longer to parse and it just shows the error better. Because of the slow speed of my machine though, I can see the error every time I get the content assist.
OK, I still don't see the 5 to 10 seconds but I see what you mean.
Scenario on comment 8 works like a charm for me. My machine (Linux-GTK) is a little faster, of course, but I do not see any flicker at all - it is much smoother and faster than without using SWT.VIRTUAL for sure! Must be a win32-only thing.
1. have (JFrame imported): JFrame f; f.<caret> 2. Ctrl+Space and wait for the list 3. type 's' ==> on Mac and GTK its fast (sometimes very small flickering) while on WindowsXP the list first clears (all white) for a second and then gets filled again. Another test case, which is slow on the Mac, is to have S<caret> and then type 'A'. SWT.VIRTUAL is not causing this. We remove the filtered proposals (due to typing a character) using Table.remove(int,int) which seems to be terribly slow. Before we used setRedraw(false/true) and always replaced the whole content. Tom, please check with SWT what we should do here. This is a must fix for 3.1.
Steve, we currently try to 'optimize' the case where the list of items is reduced. We compute the ranges of filtered items and use Table.remove(int,int). Since the items are semi-sorted, we typically remove at most two or three ranges when filtering. The rationale is that if the top n items are not filtered, they are left untouched. In the 'unoptimized' case, we simply set the table's item count and trigger the virtual table to refill using Table.clearAll(). This seems to be acceptably fast and smooth on GTK and Windows, even though all items are cleared. Should we forget our optimization and just always use clearAll(), or might there be a problem with the Table on Windows that is fixable for 3.1? -- Code is in org.eclipse.jface.text.contentassist.CompletionProposalPopup.setProposals()
Dirk, this is a must fix. Do you approve as well? Note: it's not yet clear whether we have to fix it on our side or whether SWT can do something here.
(In reply to comment #13) > Another test case, which is slow on the Mac, is to have S<caret> and then type > 'A'. MacOSX seems to be different alltogether - no matter whether we use VIRTUAL or not, range removal or clearAll, this case takes about 1-1.5 seconds on a G4 powerbook. Just checked on Tobias' Windows box and the first scenario in comment 13 is acceptably fast - while some scrollbar animations are noticable (probably due to our multiple calls to remove(int,int)), it is nowhere near to the delay noticable with Dani's machine.
Ok, I'll look into it with Billy. Stand by.
Any update on this one?
Didn't get time to look at it today. Please make sure that the 'unoptimized' case is tested and ready to go on all platforms in case we don't get to it. From memory, when you delete items, whether the Windows table is virtual or not, it redraws right away to show the change. You can see this in the Windows Explorer when you delete files. Is this what you are seeing? If so, you could try doing a setRedraw(false)/setRedraw(true) around ALL of the range deletions. If you try the setRedraw() code and it works for you, please let us try it out on the various platforms. Let me know how you get on.
The setRedraw() will guarantee that the whole table redraws but the user is expecting this when he types, no? Whatever fix you decide, Billy and I will test it for you remotely.
>the user is expecting this when he types, no? Mostly but lets say you see just 4 items in the list and the second one goes away because you type some more characters it would look better if only that item is removed instead of a full redraw of the table. We have an 'unoptimized' version ready and tested on all Platforms using redraw(true/false) - it basically feels like the 3.0 version plus the SWT.VIRTUAL improvements. It makes the 1-2s white table go away on my WindowsXP machine. Mac still flickers sometimes but that's not worse than before. We would like to decide today and if possible have it in I20050616-1200 or I20050616-1600.
+1 for RC3 (signed Dirk Baeumer). Reviewed code on Tom's machine that is now executed instead.
This one went into I20050616-1200.
Exactly which code went in? The "hide flashing with setRedraw()"? The "don't call Table.remove(int, int)"? It'd help us to know what the code is doing when we are testing.
>The "hide flashing with setRedraw()"? The "don't >call Table.remove(int, int)"? Both ;-) The code is in project org.eclipse.jface.text: org.eclipse.jface.text.contentassist.CompletionProposalPopup
OLD code: private void setProposals(ICompletionProposal[] proposals, boolean isFilteredSubset) { if (Helper.okToUse(fProposalTable)) { ICompletionProposal oldProposal= getSelectedProposal(); if (oldProposal instanceof ICompletionProposalExtension2 && fViewer != null) ((ICompletionProposalExtension2) oldProposal).unselected(fViewer); ICompletionProposal[] oldProposals= fFilteredProposals; fFilteredProposals= proposals; final int newLen= proposals.length; if (isFilteredSubset && oldProposals != null && fProposalTable.getItemCount() == oldProposals.length) { final int oldLen= oldProposals.length; final int removedLen= oldLen - newLen; Assert.isTrue(removedLen >= 0 && newLen > 0); if (removedLen > 0) { int maxRanges= Math.min(oldLen / 2 + 1, removedLen); int[][] ranges= new int[maxRanges][2]; int rangeIdx= 0; int[] range= null; ICompletionProposal next= proposals[0]; int nextIdx= 0; for (int oldIdx= 0; oldIdx < oldLen; oldIdx++) { if (oldProposals[oldIdx] != next) { if (range == null || range[1] != oldIdx - 1) ranges[rangeIdx++]= range= new int[] { oldIdx, oldIdx }; else range[1]= oldIdx; } else if (++nextIdx < newLen) { next= proposals[nextIdx]; } else { if (oldIdx < oldLen - 1) ranges[rangeIdx++]= new int[] {oldIdx + 1, oldLen - 1}; break; } } while (--rangeIdx >= 0) { range= ranges[rangeIdx]; fProposalTable.remove(range[0], range[1]); } } } else { if (USE_VIRTUAL) { fProposalTable.setItemCount(newLen); fProposalTable.clearAll(); } else { fProposalTable.setRedraw(false); fProposalTable.setItemCount(newLen); TableItem[] items= fProposalTable.getItems(); for (int i= 0; i < items.length; i++) { TableItem item= items[i]; ICompletionProposal proposal= proposals[i]; item.setText(proposal.getDisplayString()); item.setImage(proposal.getImage()); item.setData(proposal); } fProposalTable.setRedraw(true); } } Point currentLocation= fProposalShell.getLocation(); Point newLocation= getLocation(); if ((newLocation.x < currentLocation.x && newLocation.y == currentLocation.y) || newLocation.y < currentLocation.y) fProposalShell.setLocation(newLocation); selectProposal(0, false); } }
NEW (released) CODE: private void setProposals(ICompletionProposal[] proposals, boolean isFilteredSubset) { if (Helper.okToUse(fProposalTable)) { ICompletionProposal oldProposal= getSelectedProposal(); if (oldProposal instanceof ICompletionProposalExtension2 && fViewer != null) ((ICompletionProposalExtension2) oldProposal).unselected(fViewer); fFilteredProposals= proposals; final int newLen= proposals.length; if (USE_VIRTUAL) { fProposalTable.setItemCount(newLen); fProposalTable.clearAll(); } else { fProposalTable.setRedraw(false); fProposalTable.setItemCount(newLen); TableItem[] items= fProposalTable.getItems(); for (int i= 0; i < items.length; i++) { TableItem item= items[i]; ICompletionProposal proposal= proposals[i]; item.setText(proposal.getDisplayString()); item.setImage(proposal.getImage()); item.setData(proposal); } fProposalTable.setRedraw(true); } Point currentLocation= fProposalShell.getLocation(); Point newLocation= getLocation(); if ((newLocation.x < currentLocation.x && newLocation.y == currentLocation.y) || newLocation.y < currentLocation.y) fProposalShell.setLocation(newLocation); selectProposal(0, false); } }
Verified on WindowsXP. Tom, please verify on Linux-GTK. Could someone from SWT team verify on the MAC? Should we file a different bug to investigate the remove(int,int) Table.performance problem?
Seems good to me on the Mac using I20050616-1228.
Addition to comment 28: I also used I20050616-1228 to verify.
Yes, you could enter a bug about remove(int, int). BB did you test Mochief?
Motif flashes a little worse with the new code, although I don't know if it's bad enough to pull out the fix. GG, any ideas on what's causing it?
>Motif flashes a little worse with the new code, although I don't know if it's >bad enough to pull out the fix. GG, any ideas on what's causing it? Compared to which build? If it's with 3.0 then SWT.VIRTUAL might also cause it. If it's with a recent build then it's strange because we now almost use the 3.0 code again (except for SWT.VIRTUAL).
(In reply to comment #28) > Verified on WindowsXP. > Tom, please verify on Linux-GTK. Verified that there is no perceivable difference with I20050617-0010 on linux-gtk.
On I20050617-0010-linux-motif, the flickering is stronger. SWT.VIRTUAL does not seem to play well for motif - even setRedraw(on/off) does not help here. The removal of the optimization also hurts a little since we didn't flicker if the top-n proposals stayed the same. Note that other operations than filtering do flicker either way on motif, as we don't optimize there. The only thing we could do is not use VIRTUAL on motif, trading pop-up speed against flickering.
After discussion with Dani: not acceptable to have so much flickering on motif.
Created attachment 23429 [details] CompletionProposalPopup.diff patch against CompletionProposalPopup.java Disables use of the VIRTUAL table on motif.
Verified on I20050616-1228-macosx that the (In reply to comment #31) > Yes, you could enter a bug about remove(int, int). filed bug 100552 to track this.
As Tom said we have to fix the Motif case. SWT: is it the right way for 3.1 to add platform dependent code to disable virtual table on Motif or do you suggest a different alternative?
This is happening as a result of bug 90321. Any time a horizontal or vertical scrollbar is hidden or shown there's a flash. In the content assist case, since Table.itemCount() and Table.clearAll() are invoked on each keystroke, the scrollbar(s) are hidden and then reshown (when the SetData-->setText() dance is done) each time. You'll notice that if you have a code assist window that does not need either scrollbar that the bad flash doesn't happen. The only way for swt to fix this is to fix bug 90321, which was investigated in the M6 timeframe and could not be resolved. It definitely won't be fixed for the 1200 build today. So changing the content assist to not use VIRTUAL on motif seems like the thing to do here.
OK, that's what we'll do for today. We can live with that for 3.1 unless you tell us you have fix / better solution.
I don't know about Platform.WS_MOTIF.equals(Platform.getWS()). The SWT way to do it would be "motif".equals(SWT.getPlatform()). It probably ends up being the same thing. Pascal?
Tested using I20050617-1227 on Linux Motif, admittedly on a fast machine (2.8 GHz w/ hyper-threading). I saw no obvious flicker, and everything was quite responsive.
Marking as fixed. Pascal, can you reply to comment 42? Thanks.
setting to verified, see comment 43.
On motif Platform.WS_MOTIF.equals(SWT.getPlatform()). However we don't share the same string object. That said, for the motif fragment to load the value of osgi.ws (which underlies Platform.getWS()) needs to be "motif" therefore, checking one or the other is the same.