Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 214812

Summary: If a MessageDialog opens in an asyncExec block while a FileDialog is open, Eclipse hangs
Product: [Eclipse Project] Platform Reporter: Mike Morearty <mike>
Component: SWTAssignee: Platform-SWT-Inbox <platform-swt-inbox>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: cocoakevin, lshanmug, namole, Silenio_Quarti, skovatch, swingler, Tod_Creasey
Version: 3.3.1Keywords: triaged
Target Milestone: ---   
Hardware: Macintosh   
OS: Mac OS X   
Whiteboard: stalebug
Attachments:
Description Flags
Sample plugin to demonstrate the problem
none
Potential fix
none
Native Objective-C Cocoa project reproducing the bug none

Description Mike Morearty CLA 2008-01-09 16:05:29 EST
Created attachment 86507 [details]
Sample plugin to demonstrate the problem

Build ID: M20071023-1652

Steps To Reproduce:
1. OS X Leopard only -- I have not been able to reproduce this problem on OS X TIger or on Windows.
2. Download the sample plugin source.  This is the key bit of source code, from SampleAction.java (and this is the only part of the plugin which is modified from the standard Hello World plugin):

		Display.getCurrent().asyncExec(new Runnable() {
			public void run() {
				MessageDialog.openInformation(
						null,
						"DialogHang Plug-in",
						"Hello, Eclipse world");
			}
		});

		FileDialog fileDialog = new FileDialog(window.getShell());
		fileDialog.open();

Notice that that code does as asyncExec() which is going to display a MessageDialog, and then it opens a FileDialog.  So the result is that the FileDialog will appear, and then when its message pump runs, the MessageDialog will appear.

3. With this plugin installed, launch a child instanc of Eclipse.  In the child instance, click Sample Menu > Sample Action on the top-level menu.

Result:
Both the FileDialog and the MessageDialog appear (with the FileDialog at the top of the z-order), and you can drag the FileDialog around and click within it, but you cannot dismiss it.  Niether OK nor Cancel causes the FileDialog to go away.  If you try to click on the MessageDialog, you just get a small beep sound.  You are hung at this point -- you have to forcibly kill Eclipse.

Note that in the call to MessageDialog.openInformation(), I passed null for the Shell.  When you pass null, there is code in Window.defaultModalParent.getShell() that will get invoked, and it does explicitly attempt to deal with the case of other modal windows being present -- as the comment says, "Make sure we don't pick a parent that has a modal child (this can lock the app)."  But in this case, it doesn't seem to work.  I also tried changing my code to pass window.getShell() instead of null; that didn't help.

More information:
Comment 1 Mike Morearty CLA 2008-01-09 17:52:04 EST
I should clarify that this may be a Leopard bug, not an Eclipse bug.  But if it's a Leopard bug, then the question still remains whether Eclipse should try to work around it or not.
Comment 2 Kevin Barnes CLA 2008-01-10 11:51:16 EST
MessageDialog runs its own event loop when it's opened. The second event loop combined with the FileDialog seems to be causing this.

Simplified test case:

	public static void main(String[] args) {
		final Display display = new Display();
		final Shell shell = new Shell(display);

		display.asyncExec(new Runnable() {
			public void run() {
				Shell shell2 = new Shell(display);
				shell2.setBounds(25, 25, 100, 45);
				shell2.open();
				while (shell2 != null && !shell2.isDisposed()) {
					if (!display.readAndDispatch()) {
						display.sleep();
					}
				}
			}
		});
		
		FileDialog fileDialog = new FileDialog(shell);
		fileDialog.open();
		shell.setBounds(100, 100, 640, 480);
		shell.open();		

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
Comment 3 Kevin Barnes CLA 2008-01-10 14:12:30 EST
This case also fails on GTK.
Comment 4 Kevin Barnes CLA 2008-01-11 15:32:44 EST
This is difficult to fix in SWT. 
Tod, you guys are running the event loop. Maybe there's a work around in your world?
Comment 5 Tod Creasey CLA 2008-01-11 15:34:45 EST
When you say "fix" what are you suggesting?

The main issue we have is keeping painting while something else is going on in the UI Thread.
Comment 6 Kevin Barnes CLA 2008-01-15 11:59:29 EST
The test case in comment 2 should include SWT.APPLICATION_MODAL when constructing the shell.

I can confirm that this bug happens on Leopard, but not on Tiger. 
Comment 7 Kevin Barnes CLA 2008-04-28 16:13:24 EDT
The only workaround I've found for this so far is to prevent the async messages from running when there's a file dialog open on Leopard. Something like:

parent.getDisplay().runAsyncMessages = false;
OS.NavDialogRun (outDialog [0]);
parent.getDisplay().runAsyncMessages = true;

This would avoid the problem, but it would make the behavior of FileDialog different on Leopard from every other platform.
Comment 8 Mike Morearty CLA 2008-04-28 17:30:35 EDT
I don't know the Mac well enough to answer this question, but I wonder, should this be considered a bug in Leopard?  And if so, is the proper resolution to simply file a bug with Apple, and not change Eclipse?  Or, file a bug with Apple and still put in a workaround into Eclipse?

Although I filed this Eclipse bug, I don't think I should be the person to file an Apple bug, because I don't know Mac coding well enough to give any example other than the Eclipse one.
Comment 9 Kevin Barnes CLA 2008-04-29 10:28:25 EDT
We try to find work around in SWT if we can. I'm not sure if this is a bug in Carbon or not. I haven't yet had time to try writing an example in xcode.
Comment 10 Scott Kovatch CLA 2010-06-02 14:03:31 EDT
Mass move of Kevin's open Mac Carbon & Cocoa bugs to Scott K.
Comment 11 Scott Kovatch CLA 2011-02-09 12:31:39 EST
Created attachment 188606 [details]
Potential fix

This needs more testing, but basically we block sync/async execs from running when a modal dialog is up. I thought I could block them just in NSModalPanelRunLoopMode, but clicks and other events also arrive in normal mode or event tracking mode, so they still execute.
Comment 12 Nam Le CLA 2012-07-02 17:10:07 EDT
Aptana Studio and Appcelerator Titanium Studio is also running into this issue. Are there any work-arounds to the mechanism used to display the MessageDialog (we do it in an async)?
Comment 13 Nam Le CLA 2012-07-02 17:11:30 EDT
I forgot to mention my environment. Tested on OSX 10.7.4 using Eclipse 3.7.1, 4.2. Issue occurs on both versions
Comment 14 Mike Morearty CLA 2012-07-06 18:58:15 EDT
Created attachment 218405 [details]
Native Objective-C Cocoa project reproducing the bug

I was able to reproduce this with a native Objective-C Cocoa app in Xcode; if you care, see the attached Xcode project.

In this project, I tried to copy the things that SWT's Cocoa implementation does.  SWT hooks into the run loop in order to run async messages more often; see Display.init() in Display.java near line 2188; specifically, the call to OS.CFRunLoopAddObserver() near line 2194.

In that call, the value OS.kCFRunLoopCommonModes is passed for the "modes" argument.  This means that the callback will be called whenever any of the "common" modes are in effect.  This includes the default mode, the modal mode (CFModalPanelRunLoopMode), and the mode for tracking scrollbar-drag events (NSEventTrackingRunLoopMode), and possibly others.

So the result of all that is that even when a modal dialog is running its own message loop, async messages are processed, and they can do whatever they want, including UI activities such as the one that causes these hangs.

In my sample app, if you specify kCFRunLoopDefaultMode instead of kCFRunLoopCommonModes, the problem goes away (because the window doesn't open while the File dialog is up).

I can't think of anything better than what Kevin and Scott have already suggested -- just various ways of preventing async messages from being processed while in a modal dialog.
Comment 15 Lakshmi P Shanmugam CLA 2017-07-03 07:46:30 EDT
Bug triaged, visit https://wiki.eclipse.org/SWT/Devel/Triage for more
information.
Comment 16 Eclipse Genie CLA 2020-01-08 12:13:36 EST
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.

--
The automated Eclipse Genie.