From 45c2001d0223e9651070fef49bd8abb96280982a Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 18 Dec 2019 08:46:32 +0100 Subject: [PATCH] extract hideIfNeededAndShowAfterTask GitOrigin-RevId: 401f6432ae63bd453cfecedae42f961fe747bf0f --- .../intellij/openapi/wm/IdeFocusManager.java | 2 +- .../wm/ex/IdeFocusTraversalPolicy.java | 52 ++++++--- .../openapi/wm/impl/ToolWindowImpl.kt | 2 +- .../openapi/wm/impl/ToolWindowManagerImpl.kt | 110 ++++++++++-------- .../openapi/wm/impl/ToolWindowsPane.java | 63 +++++----- .../RequestFocusInToolWindowCommand.java | 40 ++++--- 6 files changed, 153 insertions(+), 116 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/wm/IdeFocusManager.java b/platform/platform-api/src/com/intellij/openapi/wm/IdeFocusManager.java index 1c4d1df0d952..4d36fcbaff5c 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/IdeFocusManager.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/IdeFocusManager.java @@ -49,7 +49,7 @@ public abstract class IdeFocusManager implements FocusRequestor { * @return suitable component to focus */ @Nullable - public abstract JComponent getFocusTargetFor(@NotNull final JComponent comp); + public abstract JComponent getFocusTargetFor(@NotNull JComponent comp); /** * Executes given runnable after all focus activities are finished. diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java b/platform/platform-impl/src/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java index 97537eec2c06..592ebd7b1d62 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java @@ -4,18 +4,17 @@ package com.intellij.openapi.wm.ex; import com.intellij.openapi.editor.impl.EditorComponentImpl; import com.intellij.openapi.fileEditor.impl.EditorWindowHolder; import com.intellij.openapi.fileEditor.impl.EditorsSplitters; -import com.intellij.util.ReflectionUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.text.JTextComponent; import java.awt.*; +import java.lang.reflect.Field; import static com.intellij.util.ui.FocusUtil.findFocusableComponentIn; public class IdeFocusTraversalPolicy extends LayoutFocusTraversalPolicy { - @Override public Component getDefaultComponent(Container focusCycleRoot) { if (!(focusCycleRoot instanceof JComponent)) { @@ -24,7 +23,7 @@ public class IdeFocusTraversalPolicy extends LayoutFocusTraversalPolicy { return getPreferredFocusedComponent((JComponent)focusCycleRoot, this); } - public static JComponent getPreferredFocusedComponent(@NotNull final JComponent component) { + public static JComponent getPreferredFocusedComponent(@NotNull JComponent component) { return getPreferredFocusedComponent(component, null); } @@ -63,34 +62,56 @@ public class IdeFocusTraversalPolicy extends LayoutFocusTraversalPolicy { * (JTextField)focusable * */ - public static JComponent getPreferredFocusedComponent(@NotNull final JComponent component, final FocusTraversalPolicy policyToIgnore) { + @Nullable + public static JComponent getPreferredFocusedComponent(@NotNull JComponent component, @Nullable FocusTraversalPolicy policyToIgnore) { + return getPreferredFocusedComponent(component, policyToIgnore, null); + } + + @Nullable + private static JComponent getPreferredFocusedComponent(@NotNull JComponent component, @Nullable FocusTraversalPolicy policyToIgnore, @Nullable Field focusTraversalPolicyField) { if (!component.isVisible()) { return null; } - final FocusTraversalPolicy focusTraversalPolicy = getFocusTraversalPolicyAwtImpl(component); + FocusTraversalPolicy focusTraversalPolicy = null; + if (component.isFocusTraversalPolicySet()) { + try { + focusTraversalPolicyField = Container.class.getDeclaredField("focusTraversalPolicy"); + focusTraversalPolicyField.setAccessible(true); + } + catch (ReflectiveOperationException e) { + focusTraversalPolicyField = null; + } + + try { + focusTraversalPolicy = focusTraversalPolicyField != null && component.isFocusTraversalPolicySet() ? (FocusTraversalPolicy)focusTraversalPolicyField.get(component) : null; + } + catch (IllegalAccessException e) { + focusTraversalPolicy = null; + } + } + if (focusTraversalPolicy != null && focusTraversalPolicy != policyToIgnore) { if (focusTraversalPolicy.getClass().getName().contains("LegacyGlueFocusTraversalPolicy")) { return component; } Component defaultComponent = focusTraversalPolicy.getDefaultComponent(component); - if (defaultComponent instanceof JComponent) { return (JComponent)defaultComponent; } } if (component instanceof JTabbedPane) { - final JTabbedPane tabbedPane = (JTabbedPane)component; - final Component selectedComponent = tabbedPane.getSelectedComponent(); + JTabbedPane tabbedPane = (JTabbedPane)component; + Component selectedComponent = tabbedPane.getSelectedComponent(); if (selectedComponent instanceof JComponent) { return getPreferredFocusedComponent((JComponent)selectedComponent); } return null; } - if(_accept(component)) { + if (_accept(component)) { return component; } @@ -98,7 +119,8 @@ public class IdeFocusTraversalPolicy extends LayoutFocusTraversalPolicy { if (!(ca instanceof JComponent)) { continue; } - final JComponent c = getPreferredFocusedComponent((JComponent)ca); + + JComponent c = getPreferredFocusedComponent((JComponent)ca, null, focusTraversalPolicyField); if (c != null) { return c; } @@ -106,19 +128,15 @@ public class IdeFocusTraversalPolicy extends LayoutFocusTraversalPolicy { return null; } - private static FocusTraversalPolicy getFocusTraversalPolicyAwtImpl(final JComponent component) { - return ReflectionUtil.getField(Container.class, component, FocusTraversalPolicy.class, "focusTraversalPolicy"); - } - @Override - protected final boolean accept(final Component aComponent) { + protected final boolean accept(Component aComponent) { if (aComponent instanceof JComponent) { return _accept((JComponent)aComponent); } return super.accept(aComponent); } - private static boolean _accept(final JComponent component) { + private static boolean _accept(@NotNull JComponent component) { if (!component.isEnabled() || !component.isVisible() || !component.isFocusable()) { return false; } @@ -128,7 +146,7 @@ public class IdeFocusTraversalPolicy extends LayoutFocusTraversalPolicy { return true; } - if(component instanceof JTextComponent){ + if (component instanceof JTextComponent) { return ((JTextComponent)component).isEditable(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.kt b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.kt index 774686110c59..d5cd35bcbd53 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.kt +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.kt @@ -164,7 +164,7 @@ class ToolWindowImpl internal constructor(val toolWindowManager: ToolWindowManag } override fun activate(runnable: Runnable?, autoFocusContents: Boolean, forced: Boolean) { - toolWindowManager.activateToolWindow(id, runnable, autoFocusContents, forced) + toolWindowManager.activateToolWindow(id, runnable, autoFocusContents) } override fun isActive(): Boolean { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.kt b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.kt index 6c1ae0250b63..e23b720573ff 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.kt +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.kt @@ -533,34 +533,35 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), } } - internal fun activateToolWindow(id: String, runnable: Runnable?, autoFocusContents: Boolean, forced: Boolean) { + internal fun activateToolWindow(id: String, runnable: Runnable?, autoFocusContents: Boolean) { ApplicationManager.getApplication().assertIsDispatchThread() + val activity = UiActivity.Focus("toolWindow:$id") UiActivityMonitor.getInstance().addActivity(project, activity, ModalityState.NON_MODAL) - activateToolWindow(idToEntry.get(id)!!, getRegisteredMutableInfoOrLogError(id), forced, autoFocusContents) + activateToolWindow(idToEntry.get(id)!!, getRegisteredMutableInfoOrLogError(id), autoFocusContents) invokeLater(Runnable { runnable?.run() UiActivityMonitor.getInstance().removeActivity(project, activity) }) } - private fun activateToolWindow(entry: ToolWindowEntry, info: WindowInfoImpl, forced: Boolean, autoFocusContents: Boolean) { + private fun activateToolWindow(entry: ToolWindowEntry, info: WindowInfoImpl, autoFocusContents: Boolean = true) { LOG.debug { "activateToolWindow($entry)" } ToolWindowCollector.recordActivation(entry.id, info) - val effectiveAutoFocusContents = autoFocusContents && forced if (!entry.toolWindow.isAvailable) { // Tool window can be "logically" active but not focused. For example, // when the user switched to another application. So we just need to bring // tool window's window to front. - if (effectiveAutoFocusContents && !entry.toolWindow.hasFocus) { + if (autoFocusContents && !entry.toolWindow.hasFocus) { RequestFocusInToolWindowCommand(entry.toolWindow).run() } + return } - showAndActivate(entry, info, autoFocusContents = effectiveAutoFocusContents) + showAndActivate(entry, info, autoFocusContents) } // mutate operation must use info from layout and not from decorator @@ -573,12 +574,12 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), return info } - private fun doDeactivateToolWindow(info: WindowInfoImpl, entry: ToolWindowEntry) { + private fun doDeactivateToolWindow(info: WindowInfoImpl, entry: ToolWindowEntry, dirtyMode: Boolean = false) { LOG.debug { "enter: deactivateToolWindowImpl(${info.id})" } info.isActive = false info.isVisible = false - removeDecorator(info, entry, dirtyMode = false) + removeDecorator(info, entry, dirtyMode = dirtyMode) entry.applyWindowInfo(info.copy()) } @@ -702,12 +703,12 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), ApplicationManager.getApplication().assertIsDispatchThread() val info = getRegisteredMutableInfoOrLogError(id) - if (doHide(idToEntry.get(id)!!, info, hideSide, moveFocus)) { + if (doHide(idToEntry.get(id)!!, info, dirtyMode = false, hideSide = hideSide, moveFocus = moveFocus)) { fireStateChanged() } } - private fun doHide(entry: ToolWindowEntry, info: WindowInfoImpl, hideSide: Boolean = false, moveFocus: Boolean = true): Boolean { + private fun doHide(entry: ToolWindowEntry, info: WindowInfoImpl, dirtyMode: Boolean, hideSide: Boolean = false, moveFocus: Boolean = true): Boolean { // info.isActive is not reliable (not set to false on focus lost) val wasActive = entry.toolWindow.isFocused @@ -716,7 +717,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), } // hide and deactivate - doDeactivateToolWindow(info, entry) + doDeactivateToolWindow(info, entry, dirtyMode = dirtyMode) if (hideSide && info.type != ToolWindowType.FLOATING && info.type != ToolWindowType.WINDOWED) { for (each in getVisibleToolWindowsOn(info.anchor)) { @@ -730,7 +731,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), for ((otherId, otherEntry) in idToEntry) { val otherInfo = layout.getInfo(otherId) ?: continue if (otherInfo.isVisible && otherInfo.anchor == info.anchor) { - doDeactivateToolWindow(otherInfo, otherEntry) + doDeactivateToolWindow(otherInfo, otherEntry, dirtyMode = dirtyMode) } } } @@ -752,13 +753,13 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), } } if (info2 != null) { - showToolWindowImpl(idToEntry.get(info2.id!!)!!, false) + showToolWindowImpl(idToEntry.get(info2.id!!)!!, dirtyMode = dirtyMode) } } activeStack.remove(entry, false) } - if (wasActive && moveFocus) { + if (moveFocus && wasActive) { activateEditorComponent() } @@ -770,21 +771,21 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), */ private fun showToolWindowImpl(entry: ToolWindowEntry, dirtyMode: Boolean) { val id = entry.id - if (entry.readOnlyWindowInfo.type == ToolWindowType.WINDOWED && entry.toolWindow.getComponentIfInitialized() != null) { - UIUtil.toFront(UIUtil.getWindow(entry.toolWindow.component)) - } if (entry.readOnlyWindowInfo.isVisible || !entry.toolWindow.isAvailable) { return } + if (entry.readOnlyWindowInfo.type == ToolWindowType.WINDOWED && entry.toolWindow.getComponentIfInitialized() != null) { + UIUtil.toFront(UIUtil.getWindow(entry.toolWindow.component)) + } + val toBeShownInfo = layout.getInfo(id) ?: throw IllegalThreadStateException("window with id=\"$id\" is unknown") toBeShownInfo.isVisible = true toBeShownInfo.isShowStripeButton = true val snapshotInfo = toBeShownInfo.copy() entry.applyWindowInfo(snapshotInfo) - doShowWindow(entry, snapshotInfo, dirtyMode) checkInvariants("Id: $id; dirtyMode: $dirtyMode") @@ -913,7 +914,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), if (contentFactory != null /* not null on init tool window from EP */) { // do not activate tool window that is the part of project frame - default component should be focused if (wasActive && (info.type == ToolWindowType.WINDOWED || info.type == ToolWindowType.FLOATING)) { - activateToolWindow(entry, info, forced = true, autoFocusContents = true) + activateToolWindow(entry, info) } else if (wasVisible) { showToolWindowImpl(entry, dirtyMode = false) @@ -1080,8 +1081,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), } } - toolWindowPane!!.layeredPane.revalidate() - toolWindowPane!!.layeredPane.repaint() + toolWindowPane!!.validateAndRepaint() activateEditorComponent() @@ -1230,6 +1230,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), ApplicationManager.getApplication().assertIsDispatchThread() setToolWindowAnchorImpl(entry, info, getRegisteredMutableInfoOrLogError(id), anchor, order) + toolWindowPane!!.validateAndRepaint() fireStateChanged() } @@ -1242,7 +1243,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), else { // for docked and sliding windows we have to move buttons and window's decorators layoutInfo.isVisible = false - toolWindowPane.removeDecorator(currentInfo, entry.toolWindow.decoratorComponent, false, this) + toolWindowPane.removeDecorator(currentInfo, entry.toolWindow.decoratorComponent, /* dirtyMode = */ true, this) doSetAnchor(entry, currentInfo, layoutInfo, anchor, order) @@ -1279,22 +1280,12 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), return } - info.isSplit = isSplit - val wasActive = info.isActive - val wasVisible = info.isVisible // we should hide the window and show it in a 'new place' to automatically hide possible window that is already located in a 'new place' - if (wasActive || wasVisible) { - doHide(entry, info) - } - - for ((otherId, otherEntry) in idToEntry) { - otherEntry.applyWindowInfo((layout.getInfo(otherId) ?: continue).copy()) - } - if (wasVisible || wasActive) { - showToolWindowImpl(entry, true) - } - if (wasActive) { - activateToolWindow(entry, info, true, true) + hideIfNeededAndShowAfterTask(entry, info) { + info.isSplit = isSplit + for ((otherId, otherEntry) in idToEntry) { + otherEntry.applyWindowInfo((layout.getInfo(otherId) ?: continue).copy()) + } } toolWindowPane!!.updateButtonPosition(entry.readOnlyWindowInfo.anchor) } @@ -1306,22 +1297,43 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), fireStateChanged() } - fun setSideToolAndAnchor(id: String, anchor: ToolWindowAnchor, order: Int, isSide: Boolean) { + fun setSideToolAndAnchor(id: String, anchor: ToolWindowAnchor, order: Int, isSplit: Boolean) { val entry = idToEntry.get(id)!! - val wasVisible = entry.readOnlyWindowInfo.isVisible - val info = getRegisteredMutableInfoOrLogError(id) - doHide(entry, info) + if (anchor == entry.readOnlyWindowInfo.anchor && order == entry.readOnlyWindowInfo.order && entry.readOnlyWindowInfo.isSplit == isSplit) { + return + } - info.isSplit = isSide - setToolWindowAnchor(id, anchor, order) - if (wasVisible) { - doShowWindow(entry, info, dirtyMode = false) + hideIfNeededAndShowAfterTask(entry, info) { + info.isSplit = isSplit + doSetAnchor(entry, entry.readOnlyWindowInfo, info, anchor, order) } fireStateChanged() } + private fun hideIfNeededAndShowAfterTask(entry: ToolWindowEntry, info: WindowInfoImpl, task: () -> Unit) { + val wasVisible = entry.readOnlyWindowInfo.isVisible + val wasFocused = entry.toolWindow.isFocused + if (wasVisible) { + doHide(entry, info, dirtyMode = true, moveFocus = false) + } + + task() + + if (wasVisible) { + info.isVisible = true + val infoSnapshot = info.copy() + entry.applyWindowInfo(infoSnapshot) + doShowWindow(entry, infoSnapshot, dirtyMode = true) + if (wasFocused) { + RequestFocusInToolWindowCommand.getShowingComponentToRequestFocus(entry.toolWindow)?.requestFocusInWindow() + } + } + + toolWindowPane!!.validateAndRepaint() + } + protected open fun fireStateChanged() { project.messageBus.syncPublisher(ToolWindowManagerListener.TOPIC).stateChanged(this) } @@ -1379,7 +1391,6 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), val newInfo = info.copy() entry.applyWindowInfo(newInfo) - doShowWindow(entry, newInfo, dirtyMode) if (toApplyInfo) { activeStack.push(entry) @@ -1628,7 +1639,8 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), if (!windowInfo.isVisible) { return@Runnable } - toolWindowManager.activateToolWindow(entry, toolWindowManager.getRegisteredMutableInfoOrLogError(entry.id), forced = false, autoFocusContents = false) + toolWindowManager.activateToolWindow(entry, toolWindowManager.getRegisteredMutableInfoOrLogError(entry.id), + autoFocusContents = false) }, ModalityState.defaultModalityState(), toolWindowManager.project.disposed) } }) @@ -1659,7 +1671,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), } fun activated(toolWindow: ToolWindowImpl) { - activateToolWindow(idToEntry.get(toolWindow.id)!!, getRegisteredMutableInfoOrLogError(toolWindow.id), true, true) + activateToolWindow(idToEntry.get(toolWindow.id)!!, getRegisteredMutableInfoOrLogError(toolWindow.id)) } /** @@ -1741,7 +1753,7 @@ open class ToolWindowManagerImpl(val project: Project) : ToolWindowManagerEx(), } if (toFocus != null && !ApplicationManager.getApplication().isDisposed) { - activateToolWindow(toFocus, getRegisteredMutableInfoOrLogError(toFocus.id), false, true) + activateToolWindow(toFocus, getRegisteredMutableInfoOrLogError(toFocus.id)) } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java index 7ba285664da2..df23fd3f1421 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java @@ -198,12 +198,12 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi boolean side = !info.isSplit(); WindowInfo sideInfo = manager.getDockedInfoAt(info.getAnchor(), side); if (sideInfo == null) { - ToolWindowAnchor anchor = info.getAnchor(); - setComponent(decorator, anchor, normalizeWeigh(info.getWeight())); - if (!dirtyMode) { - layeredPane.validate(); - layeredPane.repaint(); - } + ToolWindowAnchor anchor = info.getAnchor(); + setComponent(decorator, anchor, normalizeWeigh(info.getWeight())); + if (!dirtyMode) { + layeredPane.validate(); + layeredPane.repaint(); + } } else { addAndSplitDockedComponentCmd(decorator, info, dirtyMode, manager); @@ -223,13 +223,25 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi WindowInfo sideInfo = manager.getDockedInfoAt(info.getAnchor(), side); if (sideInfo == null) { setComponent(null, info.getAnchor(), 0); - if (!dirtyMode) { - layeredPane.validate(); - layeredPane.repaint(); - } } else { - removeSplitAndDockedComponent(info, dirtyMode); + ToolWindowAnchor anchor = info.getAnchor(); + JComponent c = getComponentAt(anchor); + if (c instanceof Splitter) { + Splitter splitter = (Splitter)c; + InternalDecorator component1 = (InternalDecorator)(info.isSplit() ? splitter.getFirstComponent() : splitter.getSecondComponent()); + state.addSplitProportion(info, component1, splitter); + setComponent(component1, anchor, + component1 == null ? 0 : ToolWindowManagerImpl.getRegisteredMutableInfoOrLogError(component1).getWeight()); + } + else { + setComponent(null, anchor, 0); + } + } + + if (!dirtyMode) { + layeredPane.validate(); + layeredPane.repaint(); } } else if (info.isSliding()) { @@ -269,6 +281,16 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi return layeredPane; } + public void validateAndRepaint() { + layeredPane.validate(); + layeredPane.repaint(); + + for (Stripe stripe : stripes) { + stripe.revalidate(); + stripe.repaint(); + } + } + private void setComponent(@Nullable JComponent component, @NotNull ToolWindowAnchor anchor, final float weight) { if (ToolWindowAnchor.TOP == anchor) { verticalSplitter.setFirstComponent(component); @@ -833,25 +855,6 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi } } - private void removeSplitAndDockedComponent(@NotNull WindowInfo info, boolean dirtyMode) { - ToolWindowAnchor anchor = info.getAnchor(); - JComponent c = getComponentAt(anchor); - if (c instanceof Splitter) { - Splitter splitter = (Splitter)c; - InternalDecorator component = (InternalDecorator)(info.isSplit() ? splitter.getFirstComponent() : splitter.getSecondComponent()); - state.addSplitProportion(info, component, splitter); - setComponent(component, anchor, - component == null ? 0 : ToolWindowManagerImpl.getRegisteredMutableInfoOrLogError(component).getWeight()); - } - else { - setComponent(null, anchor, 0); - } - if (!dirtyMode) { - layeredPane.validate(); - layeredPane.repaint(); - } - } - private void removeSlidingComponentCmd(@NotNull Component component, @NotNull WindowInfo info, boolean dirtyMode) { UISettings uiSettings = UISettings.getInstance(); if (!dirtyMode && uiSettings.getAnimateWindows() && !RemoteDesktopService.isRemoteSession()) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInToolWindowCommand.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInToolWindowCommand.java index 0245c1930a2e..645bd23cb203 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInToolWindowCommand.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInToolWindowCommand.java @@ -19,32 +19,32 @@ import java.awt.*; */ public final class RequestFocusInToolWindowCommand implements Runnable { private static final Logger LOG = Logger.getInstance(RequestFocusInToolWindowCommand.class); - private final ToolWindowImpl myToolWindow; + private final ToolWindowImpl toolWindow; public RequestFocusInToolWindowCommand(@NotNull ToolWindowImpl toolWindow) { - myToolWindow = toolWindow; + this.toolWindow = toolWindow; } @Override public void run() { - Alarm checkerAlarm = new Alarm(myToolWindow.getDisposable()); + Alarm checkerAlarm = new Alarm(toolWindow.getDisposable()); checkerAlarm.addRequest(new Runnable() { final long startTime = System.currentTimeMillis(); @Override public void run() { if (System.currentTimeMillis() - startTime > 10000) { - LOG.debug(myToolWindow.getId(), " tool window - cannot wait for showing component"); + LOG.debug(toolWindow.getId(), " tool window - cannot wait for showing component"); return; } - Component component = getShowingComponentToRequestFocus(); + Component component = getShowingComponentToRequestFocus(toolWindow); if (component == null) { checkerAlarm.addRequest(this, 100); } else { Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); - ToolWindowManagerImpl manager = myToolWindow.getToolWindowManager(); + ToolWindowManagerImpl manager = toolWindow.getToolWindowManager(); if (owner != component) { manager.getFocusManager().requestFocusInProject(component, manager.getProject()); bringOwnerToFront(); @@ -56,12 +56,14 @@ public final class RequestFocusInToolWindowCommand implements Runnable { } private void bringOwnerToFront() { - final Window owner = SwingUtilities.getWindowAncestor(myToolWindow.getComponent()); + final Window owner = SwingUtilities.getWindowAncestor(toolWindow.getComponent()); //Toolwindow component shouldn't take focus back if new dialog or frame appears //Example: Ctrl+D on file history brings a diff dialog to front and then hides it by main frame by calling // toFront on toolwindow window Window activeFrame = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); - if (activeFrame != null && activeFrame != owner) return; + if (activeFrame != null && activeFrame != owner) { + return; + } //if (owner == null) { // System.out.println("owner = " + owner); // return; @@ -74,7 +76,7 @@ public final class RequestFocusInToolWindowCommand implements Runnable { // 3. At that time "preview" tool window is being activated and modal "don't show..." dialog // isn't active. if (owner != null && owner.getFocusOwner() == null) { - final Window activeWindow = getActiveWindow(owner.getOwnedWindows()); + Window activeWindow = getActiveWindow(owner.getOwnedWindows()); if (activeWindow == null || activeWindow instanceof FloatingDecorator) { LOG.debug("owner.toFront()"); //Thread.dumpStack(); @@ -85,20 +87,22 @@ public final class RequestFocusInToolWindowCommand implements Runnable { } @Nullable - private Component getShowingComponentToRequestFocus() { - JComponent container = myToolWindow.getComponent(); + public static Component getShowingComponentToRequestFocus(@NotNull ToolWindowImpl toolWindow) { + JComponent container = toolWindow.getComponentIfInitialized(); if (container == null || !container.isShowing()) { - LOG.debug(myToolWindow.getId(), " tool window - parent container is hidden: ", container); + LOG.debug(toolWindow.getId(), " tool window: parent container is hidden: ", container); return null; } + FocusTraversalPolicy policy = container.getFocusTraversalPolicy(); if (policy == null) { - LOG.warn(myToolWindow.getId() + " tool window does not provide focus traversal policy"); + LOG.warn(toolWindow.getId() + " tool window does not provide focus traversal policy"); return null; } - Component component = myToolWindow.getToolWindowManager().getFocusManager().getFocusTargetFor(container); + + Component component = toolWindow.getToolWindowManager().getFocusManager().getFocusTargetFor(container); if (component == null || !component.isShowing()) { - LOG.debug(myToolWindow.getId(), " tool window - default component is hidden: ", container); + LOG.debug(toolWindow.getId(), " tool window: default component is hidden: ", container); return null; } return component; @@ -106,9 +110,9 @@ public final class RequestFocusInToolWindowCommand implements Runnable { private void updateToolWindow(@NotNull Component component) { if (component.isFocusOwner()) { - myToolWindow.setFocusedComponent(component); - if (myToolWindow.isAvailable() && !myToolWindow.isActive()) { - myToolWindow.activate(null, true, false); + toolWindow.setFocusedComponent(component); + if (toolWindow.isAvailable() && !toolWindow.isActive()) { + toolWindow.activate(null, true, false); } }