| Summary: | Shells receive pack() calls when not wanted | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [RT] RAP | Reporter: | Matthias Boehm <Matthias.Boehm> | ||||
| Component: | RWT | Assignee: | Project Inbox <rap-inbox> | ||||
| Status: | RESOLVED FIXED | QA Contact: | |||||
| Severity: | major | ||||||
| Priority: | P3 | CC: | ivan, Matthias.Boehm | ||||
| Version: | 2.3 | ||||||
| Target Milestone: | 3.1 M3 | ||||||
| Hardware: | All | ||||||
| OS: | All | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
(In reply to comment #0) > If the shell is packed already, shell.pack() is called again! Shouldn't the > condition in the if-clause be negated: > > private void restoreShellSize( Shell shell, Rectangle bufferedBounds, boolean > isPacked ) { > if( !isPacked ) { > shell.pack(); > } else { > setShellSize( shell, bufferedBounds ); > } > } No... During the text-size-determination resizing, the packed Shells are resized to +1000 and then packed again (only if Shell was packed before - ) in order to do the layouting again. For me it sounds like the internal Control flag "packed" is not reset after the Shell size is changed manually. Could you provide a simple snippet to reproduce the issue? Any chance for a snippet to reproduce it? Created attachment 257499 [details]
Eclipse project demonstrating the described bug
The sample is a simple rap application. When clicking on the "World" button, a sample dialog opens. This contains a table with some (long) items. After 5 seconds, the (long) table items are replaced with short table items. After this happened, a pack() is sent to the dialog unwantedly, so that the dialog resizes. This is not what we expect; we expect that the dialog retains its initial size.
Note that this described behavior occurs only after the first start of the application; when clicking again on the "World" button, the dialog is not resized any more after the table items have been updated! This is how we want it.
I've overwritten the pack method, so that one can see when pack() is called; additionally, a stack trace is printed on the console each time pack() is called.
NOTE: With "After this happened, a pack() is sent to the dialog unwantedly" I mean, that the dialog's method pack() is called unwantedly. That's because of text-size-determination. If the Dialog was packed initially, all sequential changes in it's content, that lead to text size measurement will repack the Dialog. This is how text-size-determination works. As a workaround set the dialog size manually again after the Dialog is packed for the first time. Calling pack() again in TextSizeRecalculation#restoreShellSize will set the internal Control "packed" flag back to true. I think the fix is to replace the pack() call like:
-----
private void restoreShellSize( Shell shell, Rectangle bufferedBounds, boolean isPacked ) {
if( isPacked ) {
shell.setSize( shell.computeSize( SWT.DEFAULT, SWT.DEFAULT, true ) ); // This is the Control#pack() implementation whithout changing the internal "packed" flag
} else {
setShellSize( shell, bufferedBounds );
}
}
Pending change: https://git.eclipse.org/r/#/c/58974/ Fix with change https://git.eclipse.org/r/#/c/58974/ |
I have an open modal dialog. This sometimes receives pack() calls at a (seemingly) arbitrary time, so that then it resizes to its initial size. That is very annoying if the dialog has been resized before. For analysis, I have overwritten the pack() method of my dialog, so that it prints the stack trace. It is as follows: com.heidelberg.servicetools.prinect.lis.console.app.controls.scout.ServiceScoutDialog.pack(ServiceScoutDialog.java:582) org.eclipse.rap.rwt.internal.textsize.TextSizeRecalculation.restoreShellSize(TextSizeRecalculation.java:81) org.eclipse.rap.rwt.internal.textsize.TextSizeRecalculation.forceShellRecalculations(TextSizeRecalculation.java:52) org.eclipse.rap.rwt.internal.textsize.TextSizeRecalculation.execute(TextSizeRecalculation.java:35) org.eclipse.rap.rwt.internal.textsize.MeasurementListener.handleMeasurementResults(MeasurementListener.java:63) org.eclipse.rap.rwt.internal.textsize.MeasurementListener.beforePhase(MeasurementListener.java:36) org.eclipse.rap.rwt.internal.lifecycle.PhaseListenerManager.notifyBeforePhase(PhaseListenerManager.java:63) org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.continueLifeCycle(RWTLifeCycle.java:141) org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.sleep(RWTLifeCycle.java:230) org.eclipse.swt.widgets.Display.sleep(Display.java:1253) org.eclipse.ui.application.WorkbenchAdvisor.eventLoopIdle(WorkbenchAdvisor.java:361) org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2734) org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2694) org.eclipse.ui.internal.Workbench.access$5(Workbench.java:2530) org.eclipse.ui.internal.Workbench$5.run(Workbench.java:701) org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:684) org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:157) com.heidelberg.servicetools.prinect.lis.console.app.EntryPointApp.createUI(EntryPointApp.java:27) org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:172) org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:284) java.lang.Thread.run(Thread.java:745) org.eclipse.rap.rwt.internal.lifecycle.UIThread.run(UIThread.java:105) where ServiceScoutDialog is the open dialog. I took a look at the methods in the stack trace and I think I found the reason for which the pack() method of the dialog is called unwantedly. The method restoreShellSize() in TextSizeRecalculation is as follows: private void restoreShellSize( Shell shell, Rectangle bufferedBounds, boolean isPacked ) { if( isPacked ) { shell.pack(); } else { setShellSize( shell, bufferedBounds ); } } If the shell is packed already, shell.pack() is called again! Shouldn't the condition in the if-clause be negated: private void restoreShellSize( Shell shell, Rectangle bufferedBounds, boolean isPacked ) { if( !isPacked ) { shell.pack(); } else { setShellSize( shell, bufferedBounds ); } }