[10.0.1] focus manager deals with expirable runnables

This commit is contained in:
Kirill Kalishev
2010-12-13 20:20:12 +03:00
parent cee2d1283a
commit ff7d8346b7
7 changed files with 84 additions and 14 deletions
@@ -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();
}
}
}
@@ -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);
@@ -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;
@@ -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();
}
}
@@ -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;
}
@@ -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);
@@ -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<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
@@ -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);