Bug 231751 - Shell#controlResize is fired too often
Summary: Shell#controlResize is fired too often
Status: ASSIGNED
Alias: None
Product: RAP
Classification: RT
Component: RWT (show other bugs)
Version: 1.0   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 397590
Blocks:
  Show dependency tree
 
Reported: 2008-05-13 04:25 EDT by Stefan Röck CLA
Modified: 2015-04-08 05:31 EDT (History)
5 users (show)

See Also:


Attachments
Patch to solve this problem (3.22 KB, patch)
2008-06-25 08:59 EDT, Stefan Röck CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Röck CLA 2008-05-13 04:25:34 EDT
The resize event of a Shell is fired even when no resize has occurred. The origin of these events are the following lines in TextSizeDeterminationHandler:

            WidgetTreeVisitor.accept( shells[ i ], saveSCOrigins );
            WidgetTreeVisitor.accept( shells[ i ], clearLayout );
            shells[ i ].setSize( buffer.x + 1000, buffer.y + 1000 );
            WidgetTreeVisitor.accept( shells[ i ], clearLayout );
            shells[ i ].setSize( buffer );
            WidgetTreeVisitor.accept( shells[ i ], restoreSCOrigins );

To reproduce this bug in the RAP demo project, add the following lines to 
DemoWorkbenchWindowAdvisor#postWindowOpen():
    
    final Shell shell = window.getShell();
    shell.addControlListener(new ControlAdapter() {

        public void controlResized(ControlEvent e){
            System.out.println("Shell resized: " + shell.getSize());
        }
    });

Now, start the demo. Each time, one clicks on "Open new editor" in the toolbar, the resize event is fired.
Sample output:
Shell resized: Point {1949, 1763}
Shell resized: Point {949, 763}
Shell resized: Point {1949, 1763}
Shell resized: Point {949, 763}
Comment 1 Stefan Röck CLA 2008-06-25 08:59:41 EDT
Created attachment 105804 [details]
Patch to solve this problem

This patch temporary removes all control listeners from all controls before enlarging all shells and resetting them. Afterwards, the listeners are added, again. 
This prevents all resize events from being fired with every request so that the event behaviour is more identical to SWT.
Comment 2 Rüdiger Herrmann CLA 2008-06-25 11:52:17 EDT
Stefan, thanks for the patch. Though this works in your environment, it does not serve for a general solution.
Removing the control listeners would break code that 'manually' layouts widgets by attaching control listeners.
A similar case are widgets that use control listeners to re-arrange contained items (i.e. CTabFolder). These would also be affected by the patch.
Comment 3 Austin Riddle CLA 2008-09-17 17:32:33 EDT
I am implementing a clock that calls setText() on a label at an interval.  I also have various controls that have ControlListeners registered on them.

Problem: Whenever setText() is called on the one label, it triggers a controlResized() on all of the ControlListeners for all of my controls.  After further testing, the same behavior happens when I call Graphics.stringExtent(testFont, text); (I am resizing the font to make the text fit).

I have tried it with Text, Label, CLabel, and a custom widget.  The problem is the same with each.
Comment 4 Enrico Zanaga CLA 2009-02-10 04:55:35 EST
Is it possible to add a boolean property to the control useful to detect TextSizeDeterminationHandler events?

Example:

final String textSizeDeterminationKey = "org.eclipse.rap.text-size-determination";
AllWidgetTreeVisitor textSizeDeterminationOn = new AllWidgetTreeVisitor() {
	public boolean doVisit( final Widget widget ) {
		widget.setData( textSizeDeterminationKey, Boolean.TRUE );
		return true;
	}
};
AllWidgetTreeVisitor textSizeDeterminationOff = new AllWidgetTreeVisitor() {
	public boolean doVisit( final Widget widget ) {
		widget.setData( textSizeDeterminationKey, null );
		return true;
	}
};

WidgetTreeVisitor.accept( shells[ i ], textSizeDeterminationOn );
WidgetTreeVisitor.accept( shells[ i ], saveSCOrigins );
WidgetTreeVisitor.accept( shells[ i ], clearLayout );
shells[ i ].setSize( buffer.x + 1000, buffer.y + 1000 );
WidgetTreeVisitor.accept( shells[ i ], clearLayout );
shells[ i ].setSize( buffer );
WidgetTreeVisitor.accept( shells[ i ], restoreSCOrigins );
WidgetTreeVisitor.accept( shells[ i ], textSizeDeterminationOff );
Comment 5 Tim Buschtoens CLA 2013-07-22 11:54:55 EDT
Improved with commit d7e9a50b1f23220a997e07ae597a8e8da8f4c328.

With this change a request is sent no more than once every 500ms (as opposed 60 ms before). However, the request still contains all events. The way the server currently processes the message, only the last event is processed, but this might change with RAP 2.2 (See Bug 397590) and we should re-visit this issue until release.