Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 202534 - [Dialogs] SWT error in Wizard dialog when help is displayed and "Finish" is pressed
Summary: [Dialogs] SWT error in Wizard dialog when help is displayed and "Finish" is p...
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.3   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P3 major (vote)
Target Milestone: 3.6 M7   Edit
Assignee: Susan McCourt CLA
QA Contact: Susan McCourt CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-09-06 16:49 EDT by Doug Edmundson CLA
Modified: 2012-01-04 07:26 EST (History)
10 users (show)

See Also:


Attachments
Patch for 3.4.2 - bug 202534 (501 bytes, patch)
2009-03-19 18:13 EDT, Paul Adams CLA
susan: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Doug Edmundson CLA 2007-09-06 16:49:06 EDT
Build ID: I20070625-1500

Steps To Reproduce:
1. Run the JDT.
2. Launch a wizard: New > Project.
3. Choose "Java Project".
4. Enter enough data to enable the "Finish" button.
5. Bring up the dialog's help using the "?" button in the lower left.
6. Press the "Finish" button.
7. Proceed through any "perspective" dialog.

At this point the "New Java Project" dialog remains, but with white rectangles where the controls were.  The controls are redrawn when they are clicked on.

More information:
I found this in my own Eclipse 3.3 project as well.  The following stack trace is printed when I come at the dialog via a cheat sheet:

!ENTRY org.eclipse.ui 4 0 2007-09-06 14:29:33.445
!MESSAGE Unhandled event loop exception
!STACK 0
org.eclipse.swt.SWTException: Graphic is disposed
	at org.eclipse.swt.SWT.error(SWT.java:3563)
	at org.eclipse.swt.SWT.error(SWT.java:3481)
	at org.eclipse.swt.SWT.error(SWT.java:3452)
	at org.eclipse.swt.graphics.Image.getBounds(Image.java:609)
	at org.eclipse.swt.widgets.Label.drawWidget(Label.java:163)
	at org.eclipse.swt.widgets.Widget.kEventControlDraw(Widget.java:1029)
	at org.eclipse.swt.widgets.Widget.controlProc(Widget.java:363)
	at org.eclipse.swt.widgets.Display.controlProc(Display.java:835)
	at org.eclipse.swt.internal.carbon.OS.StillDown(Native Method)
	at org.eclipse.swt.widgets.Display.runEnterExit(Display.java:3310)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2953)
	at org.eclipse.jface.window.Window.runEventLoop(Window.java:820)
	at org.eclipse.jface.window.Window.open(Window.java:796)
	at org.eclipse.ui.internal.handlers.WizardHandler.execute(WizardHandler.java:146)
	at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:239)
	at org.eclipse.core.commands.Command.executeWithChecks(Command.java:475)
	at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:429)
	at org.eclipse.ui.internal.cheatsheets.CommandRunner.executeCommand(CommandRunner.java:83)
	at org.eclipse.ui.internal.cheatsheets.data.CheatSheetCommand.execute(CheatSheetCommand.java:44)
	at org.eclipse.ui.internal.cheatsheets.views.CoreItem.runExecutable(CoreItem.java:497)
	at org.eclipse.ui.internal.cheatsheets.views.CoreItem.runExecutable(CoreItem.java:492)
	at org.eclipse.ui.internal.cheatsheets.views.CheatSheetViewer.runPerformExecutable(CheatSheetViewer.java:1041)
	at org.eclipse.ui.internal.cheatsheets.views.CoreItem$1.linkActivated(CoreItem.java:89)
	at org.eclipse.ui.forms.widgets.AbstractHyperlink.handleActivate(AbstractHyperlink.java:228)
	at org.eclipse.ui.forms.widgets.ImageHyperlink.handleActivate(ImageHyperlink.java:177)
	at org.eclipse.ui.forms.widgets.AbstractHyperlink.handleMouseUp(AbstractHyperlink.java:316)
	at org.eclipse.ui.forms.widgets.AbstractHyperlink.access$2(AbstractHyperlink.java:300)
	at org.eclipse.ui.forms.widgets.AbstractHyperlink$4.handleEvent(AbstractHyperlink.java:119)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1495)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1519)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1504)
	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1295)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3348)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2952)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2389)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2353)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2219)
	at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:466)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:289)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:461)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:106)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:153)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:363)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:324)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:504)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:443)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1169)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1144)

I am using a Wizard with just one WizardPage.  If I don't add my wizard page in Wizard.addPages(), then the error does not occur.  If I comment out the code that constructs my wizard page, I still get the error.  Hence it seems that the offending label might be in the banner region of the wizard.
Comment 1 Martin Aeschlimann CLA 2007-09-12 11:01:50 EDT
I can't reproduce this on Windows.
Comment 2 Doug Edmundson CLA 2007-09-12 11:17:57 EDT
(In reply to comment #1)
> I can't reproduce this on Windows.
> 

We only see this on the Mac.
Comment 3 Chris Torrence CLA 2007-10-21 16:15:16 EDT
I have a possible fix for this. The problem is the following:

1. When the user presses Finish or Cancel in a Wizard, then org.eclipse.jface.wizard.WizardDialog.hardClose() is called. This disposes of all wizards owned by the WizardDialog. The currentPage (owned by one of these wizards) then disposes of the wizard title bar image.
2. org.eclipse.help.ui.internal.views.HelpTray has a dispose method which adds a one-time listener, to re-set the wizard shell size to be the size it was without the HelpTray.
3. On the Mac, setting the shell size causes a redraw. Other platforms don't do this for some reason.
4. This redraw tries to draw the wizard title bar image, which has already been disposed, but the wizard label was never informed that the image was disposed.

The solution:
In org.eclipse.jface.wizard.WizardDialog#hardClose(), after disposing of the wizards, set the title image to null. The code would look like:

private boolean hardClose() {
	// inform wizards
	for (int i = 0; i < createdWizards.size(); i++) {
	 ...
	}
	// One of our wizards might have disposed of our title image,
	// so be sure to inform the title label.
	setTitleImage(null);
	return super.close();
}
Comment 4 Chris Torrence CLA 2008-04-03 21:04:52 EDT
I just tried to reproduce this in Eclipse 3.4M6, and it appears to be fixed. I looked at the source code for org.eclipse.jface.wizard.WizardDialog and org.eclipse.help.ui.internal.views.HelpTray, and I don't see any changes that would explain the fixed behavior. Did something else change with closing dialogs that would explain the fixed behavior?

Regardless, if someone else can verify, then this bug could be closed out.
Comment 5 Mike Wilson CLA 2008-04-11 14:18:52 EDT
Verified on Mac OS X 10.5.2 using:
  Version: 3.4.0
  Build id: I20080330-1350

Following the steps to reproduce simply causes the wizard to close as expected. No log messages or walkbacks are generated.

Comment 6 Paul Adams CLA 2009-03-19 18:13:46 EDT
Created attachment 129400 [details]
Patch for 3.4.2 - bug 202534

This bug has not yet been fixed - it is still an issue on Mac OS. The problem arises when the help tray re-sizes its host dialog shell to make the height of the shell more suitable. I have been able to reproduce this problem using the New Java Project wizard using the following modified instructions:

1. Run the JDT.
2. Launch a wizard: New > Project.
3. Choose "Java Project".
4. Enter enough data to enable the "Finish" button.
5. Re-size the dialog
6. Bring up the dialog's help using the "?" button in the lower left.
7. Repeat steps 5 & 6 as necessary until you see the height of the wizard grow when the Help Tray is added to the wizard
8. Press either of the "Finish" or "Cancel" buttons.

I have tried the fix suggested by Chris Torrence in a previous post, and it appears to correct the problem. I have proposed Chris' fix as a patch.
Comment 7 Doug Edmundson CLA 2009-03-20 11:11:45 EDT
Bug is still present (on Mac) - see Paul Adams' comment.
Comment 8 Carolyn MacLeod CLA 2009-08-06 13:06:10 EDT
Moving to JFace. Please see suggested fix in comment 3. Thanks!
Comment 9 Susan McCourt CLA 2009-08-06 15:53:31 EDT
marking milestone 3.6 so we can fix this as suggested.
However I'm downgrading severity from "critical" since this bug is close to two years old.
Comment 10 Susan McCourt CLA 2010-03-02 15:37:50 EST
moving to M7, my plate runneth over with API freeze bugs for M6.
Comment 11 Susan McCourt CLA 2010-04-14 15:15:06 EDT
I verified that this is indeed a framework problem (vs. some mistake in the client/Java wizard code).

I think the ideal fix would be that the wizard, when disposing its default image, would check to see if this was the image showing in the container dialog, and if so, set the dialog's image to null.  However, IWizardContainer doesn't have API for setting the image, so the page would have to presume that the container might be a WizardDialog that is showing the image and cast it. 

The fix as proposed has the dialog presuming to know that an image could have been disposed by a page. 

Given that someone has to assume something, the proposed fix seems the most simple and pragmatic.
Fixed in HEAD >20100414.
Comment 12 Remy Suen CLA 2010-04-15 07:15:07 EDT
(In reply to comment #11)
> Given that someone has to assume something, the proposed fix seems the most
> simple and pragmatic.
> Fixed in HEAD >20100414.

Susan, I believe we need to iplog+ Paul's attachment 129400 [details]?
Comment 13 Susan McCourt CLA 2010-04-15 12:21:59 EDT
You are correct, Remy.
Because the patch was out of date and I had tried several different solutions in the course of fixing it, I forgot to mark the original patch.  I'll also include the attribution in the class header.
Comment 14 Susan McCourt CLA 2010-04-15 12:26:53 EDT
Comment on attachment 129400 [details]
Patch for 3.4.2 - bug 202534

marking iplog.  Updated class header committed to HEAD.
Comment 15 Susan McCourt CLA 2010-04-26 11:18:57 EDT
I can't verify this bug since I'm not on a Mac.
Can someone who reported bug please verify the bug using the steps in comment 6?
Also cc'ing Prakash since he has a Mac (Prakash, can you verify?)
Comment 16 Prakash Rangaraj CLA 2010-04-28 04:50:18 EDT
Can't reproduce the bug using the steps in Comment # 6

Verified on I20100426-0852.
Comment 17 Holger Grote CLA 2012-01-04 04:46:54 EST
With this fix it is not possible to Call GWizardDialog.close() twice. The Method setTitleImage() should check if the dialog is already closed.
Comment 18 Paul Webster CLA 2012-01-04 07:26:54 EST
(In reply to comment #17)
> With this fix it is not possible to Call GWizardDialog.close() twice. The
> Method setTitleImage() should check if the dialog is already closed.

If something is not working right, please open a new bug and reference this one.

PW