diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java index c579afd0d46c..e12451f3c641 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java @@ -38,6 +38,7 @@ import com.intellij.ui.content.ContentFactory; import com.intellij.ui.content.ContentManager; import com.intellij.ui.content.impl.ContentImpl; import com.intellij.util.ObjectUtils; +import com.intellij.util.containers.HashSet; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.update.Activatable; import com.intellij.util.ui.update.UiNotifyConnector; @@ -47,9 +48,12 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Set; /** * @author Anton Katilin @@ -74,6 +78,18 @@ public final class ToolWindowImpl implements ToolWindowEx { private boolean myPlaceholderMode; private ToolWindowFactory myContentFactory; + private static Set FORWARD_TRAVERSAL_KEYSTROKES = new HashSet(Arrays.asList( + new KeyStroke[] { + KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0) + } + )); + + private static Set BACKWARD_TRAVERSAL_KEYSTROKES = new HashSet(Arrays.asList( + new KeyStroke[] { + KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK) + } + )); + @NotNull private ActionCallback myActivation = ActionCallback.DONE; private final BusyObject.Impl myShowing = new BusyObject.Impl() { @@ -105,6 +121,8 @@ public final class ToolWindowImpl implements ToolWindowEx { myComponent = myContentManager.getComponent(); + installToolwindowFocusPolicy(); + UiNotifyConnector notifyConnector = new UiNotifyConnector(myComponent, new Activatable.Adapter() { @Override public void showNotify() { @@ -114,6 +132,50 @@ public final class ToolWindowImpl implements ToolWindowEx { Disposer.register(myContentManager, notifyConnector); } + /** + * Installs a focus traversal policy for the tool window. + * If the policy cannot handle a keystroke, it delegates the handling to + * the nearest ancestors focus traversal policy. For instance, + * this policy does not handle KeyEvent.VK_ESCAPE, so it can delegate the handling + * to a ThreeComponentSplitter instance. + */ + private void installToolwindowFocusPolicy() { + + myComponent.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, FORWARD_TRAVERSAL_KEYSTROKES); + myComponent.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYSTROKES); + + FocusTraversalPolicy layoutFocusTraversalPolicy = new LayoutFocusTraversalPolicy(); + + myComponent.setFocusCycleRoot(true); + myComponent.setFocusTraversalPolicyProvider(true); + myComponent.setFocusTraversalPolicy(new FocusTraversalPolicy() { + @Override + public Component getComponentAfter(Container container, Component component) { + return layoutFocusTraversalPolicy.getComponentAfter(container, component); + } + + @Override + public Component getComponentBefore(Container container, Component component) { + return layoutFocusTraversalPolicy.getComponentBefore(container, component); + } + + @Override + public Component getFirstComponent(Container container) { + return layoutFocusTraversalPolicy.getFirstComponent(container); + } + + @Override + public Component getLastComponent(Container container) { + return layoutFocusTraversalPolicy.getLastComponent(container); + } + + @Override + public Component getDefaultComponent(Container container) { + return layoutFocusTraversalPolicy.getDefaultComponent(container); + } + }); + } + public final void addPropertyChangeListener(final PropertyChangeListener l) { myChangeSupport.addPropertyChangeListener(l); }