From ff7d8346b7f4f480ade13642ef13d650163db257 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Mon, 13 Dec 2010 20:20:12 +0300 Subject: [PATCH] [10.0.1] focus manager deals with expirable runnables --- .../openapi/util/ExpirableRunnable.java | 37 +++++++++++++++++++ .../intellij/openapi/wm/IdeFocusManager.java | 3 ++ .../wm/PassThroughtIdeFocusManager.java | 8 ++++ .../openapi/wm/impl/FocusManagerImpl.java | 19 +++++++++- .../wm/impl/IdeFocusManagerHeadless.java | 8 ++++ .../openapi/wm/impl/IdeFocusManagerImpl.java | 6 +++ .../wm/impl/ToolWindowManagerImpl.java | 17 +++------ 7 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/openapi/util/ExpirableRunnable.java diff --git a/platform/platform-api/src/com/intellij/openapi/util/ExpirableRunnable.java b/platform/platform-api/src/com/intellij/openapi/util/ExpirableRunnable.java new file mode 100644 index 000000000000..27de49f01ff7 --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/util/ExpirableRunnable.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.util; + +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.Nullable; + +public interface ExpirableRunnable extends Runnable, Expirable { + + abstract class ForProject implements ExpirableRunnable { + + private Project myProject; + + protected ForProject(@Nullable Project project) { + myProject = project; + } + + @Override + public boolean isExpired() { + return myProject == null || myProject.isDisposed(); + } + } + +} 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 c77bd74e256d..02c0b221dca8 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/IdeFocusManager.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/IdeFocusManager.java @@ -22,6 +22,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Expirable; +import com.intellij.openapi.util.ExpirableRunnable; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,6 +45,8 @@ public abstract class IdeFocusManager implements FocusRequestor { public abstract void doWhenFocusSettlesDown(@NotNull Runnable runnable); + public abstract void doWhenFocusSettlesDown(@NotNull ExpirableRunnable runnable); + @Nullable public abstract Component getFocusedDescendantFor(final Component comp); diff --git a/platform/platform-api/src/com/intellij/openapi/wm/PassThroughtIdeFocusManager.java b/platform/platform-api/src/com/intellij/openapi/wm/PassThroughtIdeFocusManager.java index 78cd280279e3..1074e7acfec4 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/PassThroughtIdeFocusManager.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/PassThroughtIdeFocusManager.java @@ -18,6 +18,7 @@ package com.intellij.openapi.wm; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Expirable; +import com.intellij.openapi.util.ExpirableRunnable; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -51,6 +52,13 @@ public class PassThroughtIdeFocusManager extends IdeFocusManager { runnable.run(); } + @Override + public void doWhenFocusSettlesDown(@NotNull ExpirableRunnable runnable) { + if (!runnable.isExpired()) { + runnable.run(); + } + } + public Component getFocusedDescendantFor(Component comp) { final Component focused = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); if (focused == null) return null; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index 04ffad38f33b..9f18c64b142a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -26,6 +26,7 @@ import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.EdtRunnable; import com.intellij.openapi.util.Expirable; +import com.intellij.openapi.util.ExpirableRunnable; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.*; import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; @@ -363,6 +364,11 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } } + @Override + public void doWhenFocusSettlesDown(@NotNull ExpirableRunnable runnable) { + doWhenFocusSettlesDown((Runnable)runnable); + } + public void doWhenFocusSettlesDown(@NotNull final Runnable runnable) { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override @@ -373,7 +379,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } if (myRunContext != null) { - runnable.run(); + flushRequest(runnable); return; } @@ -466,9 +472,18 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { final Runnable[] all = myIdleRequests.toArray(new Runnable[myIdleRequests.size()]); myIdleRequests.clear(); for (Runnable each : all) { - if (each != null) { + flushRequest(each); + } + } + + private void flushRequest(Runnable each) { + if (each == null) return; + if (each instanceof Expirable) { + if (!((Expirable)each).isExpired()) { each.run(); } + } else { + each.run(); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFocusManagerHeadless.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFocusManagerHeadless.java index ee2b10a9b4d4..1562f86590eb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFocusManagerHeadless.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFocusManagerHeadless.java @@ -18,6 +18,7 @@ package com.intellij.openapi.wm.impl; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Expirable; +import com.intellij.openapi.util.ExpirableRunnable; import com.intellij.openapi.wm.FocusCommand; import com.intellij.openapi.wm.FocusRequestor; import com.intellij.openapi.wm.IdeFocusManager; @@ -50,6 +51,13 @@ public class IdeFocusManagerHeadless extends IdeFocusManager { runnable.run(); } + @Override + public void doWhenFocusSettlesDown(@NotNull ExpirableRunnable runnable) { + if (!runnable.isExpired()) { + runnable.run(); + } + } + public Component getFocusedDescendantFor(final Component c) { return null; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFocusManagerImpl.java index 95e9c9b30118..43b3e2d66b1c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFocusManagerImpl.java @@ -18,6 +18,7 @@ package com.intellij.openapi.wm.impl; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Expirable; +import com.intellij.openapi.util.ExpirableRunnable; import com.intellij.openapi.wm.FocusCommand; import com.intellij.openapi.wm.FocusRequestor; import com.intellij.openapi.wm.IdeFocusManager; @@ -54,6 +55,11 @@ public class IdeFocusManagerImpl extends IdeFocusManager { getGlobalInstance().doWhenFocusSettlesDown(runnable); } + @Override + public void doWhenFocusSettlesDown(@NotNull ExpirableRunnable runnable) { + getGlobalInstance().doWhenFocusSettlesDown(runnable); + } + @Nullable public Component getFocusedDescendantFor(@NotNull final Component comp) { return getGlobalInstance().getFocusedDescendantFor(comp); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index d1bb54cb33f2..e02c51fc3a5c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -45,14 +45,7 @@ import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopupFactory; -import com.intellij.openapi.util.ActionCallback; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.EdtRunnable; -import com.intellij.openapi.util.Expirable; -import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.util.JDOMExternalizable; -import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.FocusCommand; @@ -239,7 +232,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } public void fileClosed(FileEditorManager source, VirtualFile file) { - getFocusManagerImpl().doWhenFocusSettlesDown(new Runnable() { + getFocusManagerImpl().doWhenFocusSettlesDown(new ExpirableRunnable.ForProject(myProject) { public void run() { if (!hasOpenEditorFiles()) { focusToolWinowByDefault(null); @@ -266,7 +259,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements private void updateToolWindowHeaders() { - getFocusManager().doWhenFocusSettlesDown(new Runnable() { + getFocusManager().doWhenFocusSettlesDown(new ExpirableRunnable.ForProject(myProject) { @Override public void run() { WindowInfoImpl[] infos = myLayout.getInfos(); @@ -592,7 +585,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } ApplicationManager.getApplication().assertIsDispatchThread(); - Runnable runnable = new Runnable() { + Runnable runnable = new ExpirableRunnable.ForProject(myProject) { @Override public void run() { final ArrayList commandList = new ArrayList(); @@ -1928,7 +1921,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements final KeyboardFocusManager mgr = KeyboardFocusManager.getCurrentKeyboardFocusManager(); final Component owner = mgr.getFocusOwner(); - IdeFocusManager.getInstance(myProject).doWhenFocusSettlesDown(new Runnable() { + IdeFocusManager.getInstance(myProject).doWhenFocusSettlesDown(new ExpirableRunnable.ForProject(myProject) { public void run() { if (mgr.getFocusOwner() == owner) { activateEditorComponent(false);