Bug 295165

Summary: [Widgets] Exception when disposing the Display in a Dispose listener of a Shell
Product: [Eclipse Project] Platform Reporter: Jussi Suistomaa <jussi.suistomaa>
Component: SWTAssignee: Platform-SWT-Inbox <platform-swt-inbox>
Status: NEW --- QA Contact:
Severity: enhancement    
Priority: P3 CC: ericwill, pinnamur, Silenio_Quarti
Version: 3.5.1   
Target Milestone: ---   
Hardware: PC   
OS: All   
Whiteboard:

Description Jussi Suistomaa CLA 2009-11-14 13:16:42 EST
Display.release() is disposing all the Shells when Display is getting disposed. If the Display happens to get disposed in a Dispose event listener of a Shell then Display.release() still tries to call Display.readAndDispatch() which throws an exception. Here's a snippet to reproduce the problem:

public static void main(String[] args) {
    final Display display = new Display();
    Shell shell = new Shell();
    shell.setLayout(new FillLayout());
    Button button = new Button(shell, SWT.PUSH);
    button.setText("Display.dispose()");
    shell.pack();
    button.addListener(SWT.Selection, new Listener() {
        public void handleEvent(Event event) {
            display.dispose();
        }
    });
    shell.open();
    shell.addListener(SWT.Dispose, new Listener() {
        public void handleEvent(Event event) {
            display.dispose();
        }
    });
    while(!display.isDisposed()) {
        if(!display.readAndDispatch())
            display.sleep();
    }
}
Comment 1 Bogdan Gheorghe CLA 2009-11-16 17:29:50 EST
Display.release() is doing the proper thing in releasing the shells. Your example below calls dispose twice which is not correct. Do you have a particular use case in mind that requires this form?
Comment 2 Jussi Suistomaa CLA 2009-11-17 04:18:29 EST
(In reply to comment #1)
> Display.release() is doing the proper thing in releasing the shells. Your
> example below calls dispose twice which is not correct. Do you have a
> particular use case in mind that requires this form?

Just noticed it doesn't handle this situation and could be easily improved to do so. That's why I reported it. 

Calling dispose() twice for a Device is ok. Calling it on a disposed Device is ignored silently.