Community
Participate
Working Groups
It seems that (under certain circumstances?) a shellActivate event is sent while the display is disposed. Run the snippet below and set a breakpoint in the catch clause of Display#disposeShells(). An IndexOutOfBounds exception is caught because the children of the shell have already been disposed. Is it legal to send such an event to a shell in dispose? public void test() { Display display = new Display(); Shell parentShell = new Shell( display ); new Label(parentShell,SWT.NONE); parentShell.addShellListener(new TestShellListener() ); parentShell.open(); Shell shell = new Shell(parentShell); new Label(shell,SWT.NONE); shell.addShellListener(new TestShellListener() ); shell.open(); display.dispose(); } private static class TestShellListener extends ShellAdapter { public void shellActivated(org.eclipse.swt.events.ShellEvent e) { Shell shell = (Shell) e.widget; Label label = (Label) shell.getChildren()[0]; label.setText( "shell was activated" ); } }
Created attachment 228905 [details] Proposed patch This patch includes a fix and a test case. I've checked the test case in SWT and it is green there too. The fix is not to set the focus on controls which are in dispose. Ruediger, what do you think?
(In reply to comment #1) > This patch includes a fix and a test case. I've checked the test case in SWT > and it is green there too. The fix is not to set the focus on controls which > are in dispose. Ruediger, what do you think? Thanks Ivan for the quick response :) The patch looks good to me. I was thinking if it would be possible for an already disposed control to be in the list of parents so that isInDipose() returns false and isDisposed() would return true. But I couldn't come up with anything to provoke that constellation and thus we might as well wait until such a case occurs in the wild.
Allied patch to master with commit 887c8a73ea9f15adb1c3ffb6b13a21bb47aaf4ad. > I was thinking if it would be possible for an already disposed control to be in the list of parents so that isInDipose() returns false and isDisposed() would return true. I think that this is not possible. If you look at Widget#dispose() the state field contains the bits for the different states. If Widget#isDisposed() return true (state |= DISPOSED is set in releaseWidget), Widget#isInDispose() will always return true as well (state |= DISPOSE_SENT is set before that).
(In reply to comment #3) > Allied patch to master with commit 887c8a73ea9f15adb1c3ffb6b13a21bb47aaf4ad. > > I was thinking if it would be possible for an already disposed control to be in the list of parents so that isInDipose() returns false and isDisposed() would return true. > I think that this is not possible. If you look at Widget#dispose() the state > field contains the bits for the different states. If Widget#isDisposed() > return true (state |= DISPOSED is set in releaseWidget), > Widget#isInDispose() will always return true as well (state |= DISPOSE_SENT > is set before that). That makes sense. Thanks a lot for clarifying.