Project: Eclipse_Platform_UI
Bug 77339 [Progress] [Dialogs] The workbench leaks dialogs
Reported: 2004-10-30 11:18:41 | Status: verified fixed

Here's how to reproduce: 1. Use Windows (though this is not OS specific issue) 1. Fire up Eclipse 3.0/3.0.1 (I suspect this isn't fixed in the 3.1 steam either). 2. Create a realy simple Java testing project. It doesn't even need to have any Java classes in it. 3. Invoke the Project/Properties dialog (you can do it from the Project menu or from the context menu of the test project entry in the Package Explorer - doesn't matter). 4. Switch to the Java Build Path entry in the dialog. 5. Now, just press the OK button to close the dialog (note, you need to press OK, NOT Cancel, or the bug won't be reproduced, for reasons that will become clear below). 6. Fire up the Spy++ thing. It can be found in the Visual Studio 6 Tools package (or later VSs). 7. In Spy++, switch to the Windows view (Ctrl+W). 8. Invoke the Find dialog (Alt+F3) 9. In the dialog, remove the values for 'Handle:' and 'Class:' and for 'Caption:' enter 'Setting build path', without the quotation marks. 10. A leftover dialog will be found, created by the workbench UI Job management stuff. 11. If you repeat step 3-5 10 times, you'll get 10 such dialogs. =================================== Why does this happen? The problematic code is in package org.eclipse.ui.internal.progress, class ProgressMonitorFocusJobDialog, method <public void show(Job jobToWatch)>. What I interpret to happen there, is that: 1. First, the dialog is created, *but not shown* - this is crucial. This happens because of: <snip> setOpenOnRun(false); aboutToRun(); </snip> 2. Then, the UI is being blocked for several hundred milliseconds without any UI progress indication. This happens because of: <snip> //start with a quick busy indicator. Lock the UI as we //want to preserve modality BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(), new Runnable() { public void run() { try { Thread .sleep (ProgressManagerUtil.SHORT_OPERATION_TIME); } catch (InterruptedException e) { WorkbenchPlugin.log(e.getLocalizedMessage()); } } }); </snip> I believe this is done so that the user not to be bugged by flashing UI for job stuff which needs very short time to complete. 3. Finally, a WorkbenchJob is created and kept in a variable 'openJob'. Its method 'public IStatus runInUIThread(IProgressMonitor monitor)' is always run on behalf of the UI thread. Now, this method is I think where the problem is. This <snip> //if the job is done at this point, we don't need the dialog if (job.getState() == Job.NONE){ cleanUpFinishedJob(); return Status.CANCEL_STATUS; } </snip> snippet inside it obviously checks whether the job had finished during point (2.). If so, we don't need to open the dialog at all. Unfortunately, it is not taken into account, that the dialog is created already - and invisible. The "cleanUpFinishedJob();" thing called in the last snippet does not dispose the dialog, so it remains hanging till Eclipse is closed. And no, the dialog will not automatically close itself when the job goes to the DONE state, because a "createCloseListener()" is installed only if the dialog is opened with "setOpenOnRun(true);", and in our case, it is NOT (check point 1.). I found this because SWT/Fox used to have slight semantic difference with the other SWT ports, as to how modality works. In SWT/Fox, if a Shell is created with a modal flag, the rest of the UI is disabled even if the modal shell is invisible, while in the other SWT ports, a modal shell in invisible state is not considered modal. So this hidden dialog hanging around caused Eclipse-on-SWT/Fox to become unresponsive to user input after the steps-to-reproduce are carried out. Anyways, sorry for the long analysis, hope it is correct and will help you guys fix the issue.

Files changed in fix:
bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressMonitorFocusJobDialog.java