Java – Get Active Shell in SWT, even if the Shell is not on focus

javaswtwindows

Display.getActiveShell() seems to only consider a Shell as active if it's focused. If at the moment another application has focus that means Display.getActiveShell() returns null.

I need a method that will always tell me which is the Shell on focus on my SWT application, even when my SWT application is not on focus.

I've quickly hacked this piece of code together, although sometimes I get an AssertionException:

public static Shell getActiveShell() {
    Display display = Display.getDefault();
    Shell result = display.getActiveShell();

    if (result == null) {
        Shell[] shells = display.getShells();
        for (Shell shell : shells) {
            if (shell.getShells().length == 0) {
                if (result != null)
                    throw new AssertionException();
                result = shell;
            }
        }
    }

    return result;
}

Is there any standard way to approach this issue other than writing your own method?

Best Solution

Recently, I had a similar problem and though you probably found a solution in the meanwhile, I'd like to share mine for future reference.

The ShellActivationTracker adds a display filter that listens for Activate events and - if the activated widget is a Shell - remembers the most recently activated Shell. Thus you can query the (last) active shell even if your application is currently not active/focused.

class ShellActivationTracker implements Listener {
  Shell activeShell;

  ShellActivationTracker(Display display) {
    activeShell = display.getActiveShell();
    display.addFilter(SWT.Activate, this);
  }

  @Override
  public void handleEvent(Event event) {
    if (event.widget instanceof Shell) {
      activeShell = (Shell)event.widget;
    }
  }
}