eclipse-platform / .github

Common contribution content for eclipse-platform repositories
https://www.eclipse.org/eclipse/
5 stars 10 forks source link

Using the IWizardContainer::run() method in FocusListener::focusLost will block the entire WizardPage. #88

Open pponikox opened 1 year ago

pponikox commented 1 year ago

When we have a wizard page containing any SWT widget with a FocusListener which invokes the getContainer().run() method on focusLost then the user is not able to change the focused widget since the focus is restored after finishing the asynchronous method.

Consider an example below with a simple TestPage is with three Text widgets:

import java.lang.reflect.InvocationTargetException;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;

public abstract class TestPage extends WizardPage {

    protected TestPage(final String pageName) {
        super(pageName);
    }

    @Override
    public void createControl(final Composite parent) {
        final Composite container = new Composite(parent, SWT.NONE);
        setControl(container);
        container.setLayout(new GridLayout());

        final Text text1 = new Text(container, SWT.BORDER);
        text1.addFocusListener(new FocusAdapter() {

            @Override
            public void focusLost(final FocusEvent e) {
                doAsyncStuff();
            }

        });

        final Text dummy1 = new Text(container, SWT.BORDER);
        final Text dummy2 = new Text(container, SWT.BORDER);
    }

    private void doAsyncStuff() {
        try {
            getContainer().run(true, true, monitor -> {
                monitor.beginTask("doing async stuff...", 100);
                monitor.done();
            });
        } catch (InvocationTargetException | InterruptedException e) {
            System.out.println("async stuff -> ERROR");
        }
    }
}

When a focus is given to the text1 then there is no way to change it to a different widget. It is not possible with the TAB key nor by clicking on other element or on "Finish"/"Cancel" buttons because every time the run() method is finished then the focus is restored to text1. focus-lost-bug-img

pponikox commented 1 year ago

Issue created also in Bugzilla: https://bugs.eclipse.org/bugs/show_bug.cgi?id=581438