Bug 303956 - [TabbedProperties] complex tab property sheets layout more than they need to.
Summary: [TabbedProperties] complex tab property sheets layout more than they need to.
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.5   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Platform UI Triaged CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-02-25 14:06 EST by Cliff Collins CLA
Modified: 2019-09-06 16:06 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Cliff Collins CLA 2010-02-25 14:06:53 EST
Build Identifier: I20090611-1540

Complex property sheets spend more time doing layout of the controls than they need to. Some of the code generates events to re-layout which does rebuild of the values in the sheet 2 times on a tab property switch. 

The SelectionChangedListener is called multiple times for the same object and should filter the second calls to so it doesn't re-layout the tab a second time. The second call comes from listeners on itself.

Changing the code in TabbedPropertySheetPage: to be this improves the layout issues:

	class SelectionChangedListener
		implements ISelectionChangedListener {

	    IStructuredSelection current = null;
	    Object               previousInput = null;
	    
		/**
		 * Shows the tab associated with the selection.
		 */
		public void selectionChanged(SelectionChangedEvent event) {
			IStructuredSelection selection = (IStructuredSelection) event
				.getSelection();
			if ((current != null) && current.equals(selection) &&
			    (previousInput != null) && previousInput.equals(tabbedPropertyViewer.getInput()) ) {
			    return;
			}
			current = selection;
			previousInput = tabbedPropertyViewer.getInput();
			
			TabContents tab = null;
			ITabDescriptor descriptor = (ITabDescriptor) selection
					.getFirstElement();

			if (descriptor == null) {
				// pretend the tab is empty.
				hideTab(currentTab);
			} else {
				// create tab if necessary
				// can not cache based on the id - tabs may have the same id,
				// but different section depending on the selection
				tab = (TabContents) descriptorToTab.get(descriptor);

				if (tab != currentTab) {
					hideTab(currentTab);
				}

				Composite tabComposite = (Composite) tabToComposite.get(tab);
				if (tabComposite == null) {
					tabComposite = createTabComposite();
					tab.createControls(tabComposite,
						TabbedPropertySheetPage.this);
					// tabAreaComposite.layout(true);
					tabToComposite.put(tab, tabComposite);
				}
				// force widgets to be resized
				tab.setInput(tabbedPropertyViewer.getWorkbenchPart(),
					(ISelection) tabbedPropertyViewer.getInput());

				// store tab selection
				storeCurrentTabSelection(descriptor.getLabel());

				if (tab != currentTab) {
					showTab(tab);
				}

				tab.refresh();
			}
			if (tab != currentTab) {
			    tabbedPropertyComposite.getScrolledComposite().setLayoutDeferred(true);
			    tabbedPropertyComposite.getTabComposite().layout(true);
			    currentTab = tab;
	            resizeScrolledComposite();
                tabbedPropertyComposite.getScrolledComposite().setLayoutDeferred(false);
			}

			if (descriptor != null) {
				handleTabSelection(descriptor);
			}
		}



NOTE: the code below is not as critical but the resizeScrolledComposite cause a "layout" as does the tabbedPropertyComposite.getTabComposite().layout(true); but these could be handled in one layout by doing the deferred. 

			if (tab != currentTab) {
			    tabbedPropertyComposite.getScrolledComposite().setLayoutDeferred(true);
			    tabbedPropertyComposite.getTabComposite().layout(true);
			    currentTab = tab;
	            resizeScrolledComposite();
                tabbedPropertyComposite.getScrolledComposite().setLayoutDeferred(false);
			}

NOTE: it seems like if we are switch inputs with the same tab, we shouldn't need to "layout" so that is why it does the if (tab != currentTab). This also improved some performance.


This change is the most useful change:

if ((current != null) && current.equals(selection) &&
	(previousInput != null) && previousInput.equals(tabbedPropertyViewer.getInput()) ) {
	 return;
}

since the method will be call 2 times for each tab selection change. This prevents the second loop over.


NOTE, this can't be patched by a "coder" (workaround) since all these methods/classes etc are private in the package.




Reproducible: Always

Steps to Reproduce:
1.have an editor with tab properties that have many controls on the sheet (complex controls etc)
2.Switch between edit parts that cause tabs to be switched.
3.THe SelectionChangedListener is called multiple times for the same object and should filter the second calls to it doesn't re-layout the tab a second time.
Comment 1 Anthony Hunter CLA 2010-03-29 16:18:11 EDT
This is probably a duplicate of Bug 145755 .
Comment 2 Cliff Collins CLA 2010-03-29 16:26:23 EDT
(In reply to comment #1)
> This is probably a duplicate of Bug 145755 .

I don't think so. This bug is just listing some duplicate calls. There are other places in general properties that does this type of filtering. The listener installed by the tabs causes a second selection to happen and this should be filter if possible. Placing a break point on the selectChange method will show that it gets called 2 times for each select from an editor.

This came out of some performance testing on the mac.
Comment 3 Szymon Brandys CLA 2010-03-30 04:48:05 EDT
Removing myself from the cc. I guess this is a problem with the triage script. The same that Remy mentioned in Bug 304530.
Comment 4 Eclipse Webmaster CLA 2019-09-06 16:06:50 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.