avoid using AsyncResult for synchronous operations in FileEditorManagerImpl

Each such operation involves Disposer.dispose call which generates a Throwable. When called thousand(s) of time within the same event, this creates a notable performance overhead
(for IDEA-135620)
This commit is contained in:
Dmitry Batrak
2016-10-24 14:55:04 +03:00
parent 1593a974d5
commit ec3631efae
4 changed files with 46 additions and 45 deletions
@@ -34,7 +34,7 @@ public class CloseEditorAction extends AnAction implements DumbAware {
EditorWindow window = e.getData(EditorWindow.DATA_KEY);
VirtualFile file = null;
if (window == null) {
window = editorManager.getActiveWindow().getResult();
window = editorManager.getCurrentWindow();
if (window != null) {
file = window.getSelectedFile();
}
@@ -64,7 +64,7 @@ public class CloseEditorAction extends AnAction implements DumbAware {
}
EditorWindow window = event.getData(EditorWindow.DATA_KEY);
if (window == null) {
window = getEditorManager(project).getActiveWindow().getResult();
window = getEditorManager(project).getCurrentWindow();
}
presentation.setEnabled(window != null && window.getTabCount() > 0);
}
@@ -74,11 +74,14 @@ public abstract class FileEditorManagerEx extends FileEditorManager implements B
public abstract void updateFilePresentation(@NotNull VirtualFile file);
/**
*
* Synchronous version of {@link #getActiveWindow()}. Will return <code>null</code> if invoked not from EDT.
* @return current window in splitters
*/
public abstract EditorWindow getCurrentWindow();
/**
* Asynchronous version of {@link #getCurrentWindow()}. Execution happens after focus settle down. Can be invoked on any thread.
*/
@NotNull
public abstract AsyncResult<EditorWindow> getActiveWindow();
@@ -56,7 +56,6 @@ import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.FileStatusListener;
import com.intellij.openapi.vcs.FileStatusManager;
@@ -262,48 +261,50 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Persis
}
@NotNull
private AsyncResult<EditorsSplitters> getActiveSplitters(boolean syncUsage) {
final boolean async = Registry.is("ide.windowSystem.asyncSplitters") && !syncUsage;
private AsyncResult<EditorsSplitters> getActiveSplittersAsync() {
final AsyncResult<EditorsSplitters> result = new AsyncResult<>();
final IdeFocusManager fm = IdeFocusManager.getInstance(myProject);
Runnable run = () -> {
fm.doWhenFocusSettlesDown(() -> {
if (myProject.isDisposed()) {
result.setRejected();
return;
}
Component focusOwner = fm.getFocusOwner();
if (focusOwner == null && !async) {
focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
}
if (focusOwner == null && !async) {
focusOwner = fm.getLastFocusedFor(fm.getLastFocusedFrame());
}
DockContainer container = myDockManager.getContainerFor(focusOwner);
if (container == null && !async) {
focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
container = myDockManager.getContainerFor(focusOwner);
}
if (container instanceof DockableEditorTabbedContainer) {
result.setDone(((DockableEditorTabbedContainer)container).getSplitters());
}
else {
result.setDone(getMainSplitters());
}
};
});
return result;
}
if (async) {
fm.doWhenFocusSettlesDown(run);
private EditorsSplitters getActiveSplittersSync() {
assertDispatchThread();
final IdeFocusManager fm = IdeFocusManager.getInstance(myProject);
Component focusOwner = fm.getFocusOwner();
if (focusOwner == null) {
focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
}
if (focusOwner == null) {
focusOwner = fm.getLastFocusedFor(fm.getLastFocusedFrame());
}
DockContainer container = myDockManager.getContainerFor(focusOwner);
if (container == null) {
focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
container = myDockManager.getContainerFor(focusOwner);
}
if (container instanceof DockableEditorTabbedContainer) {
return ((DockableEditorTabbedContainer)container).getSplitters();
}
else {
UIUtil.invokeLaterIfNeeded(run);
return getMainSplitters();
}
return result;
}
private final Object myInitLock = new Object();
@@ -458,7 +459,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Persis
@Override
public void unsplitWindow() {
final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow();
final EditorWindow currentWindow = getActiveSplittersSync().getCurrentWindow();
if (currentWindow != null) {
currentWindow.unsplit(true);
}
@@ -466,7 +467,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Persis
@Override
public void unsplitAllWindow() {
final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow();
final EditorWindow currentWindow = getActiveSplittersSync().getCurrentWindow();
if (currentWindow != null) {
currentWindow.unsplitAll();
}
@@ -474,7 +475,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Persis
@Override
public int getWindowSplitCount() {
return getActiveSplitters(true).getResult().getSplitCount();
return getActiveSplittersSync().getSplitCount();
}
@Override
@@ -590,28 +591,25 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Persis
@Override
public VirtualFile getCurrentFile() {
return getActiveSplitters(true).getResult().getCurrentFile();
return getActiveSplittersSync().getCurrentFile();
}
@Override
@NotNull
public AsyncResult<EditorWindow> getActiveWindow() {
return _getActiveWindow(false);
}
@NotNull
private AsyncResult<EditorWindow> _getActiveWindow(boolean now) {
return getActiveSplitters(now).subResult(splitters -> splitters.getCurrentWindow());
return getActiveSplittersAsync().subResult(splitters -> splitters.getCurrentWindow());
}
@Override
public EditorWindow getCurrentWindow() {
return _getActiveWindow(true).getResult();
if (!ApplicationManager.getApplication().isDispatchThread()) return null;
EditorsSplitters splitters = getActiveSplittersSync();
return splitters == null ? null : splitters.getCurrentWindow();
}
@Override
public void setCurrentWindow(final EditorWindow window) {
getActiveSplitters(true).getResult().setCurrentWindow(window, true);
getActiveSplittersSync().setCurrentWindow(window, true);
}
public void closeFile(@NotNull final VirtualFile file, @NotNull final EditorWindow window, final boolean transferFocus) {
@@ -652,7 +650,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Persis
public void run(EditorsSplitters splitters) {
splitters.closeFile(file, moveFocus);
}
}, closeAllCopies ? null : getActiveSplitters(true).getResult());
}, closeAllCopies ? null : getActiveSplittersSync());
}
//-------------------------------------- Open File ----------------------------------------
@@ -675,7 +673,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Persis
EditorWindow wndToOpenIn = null;
if (searchForSplitter) {
Set<EditorsSplitters> all = getAllSplitters();
EditorsSplitters active = getActiveSplitters(true).getResult();
EditorsSplitters active = getActiveSplittersSync();
if (active.getCurrentWindow() != null && active.getCurrentWindow().isFileOpen(file)) {
wndToOpenIn = active.getCurrentWindow();
} else {
@@ -1279,7 +1277,8 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Persis
@Override
@NotNull
public EditorsSplitters getSplitters() {
EditorsSplitters active = getActiveSplitters(true).getResult();
EditorsSplitters active = null;
if (ApplicationManager.getApplication().isDispatchThread()) active = getActiveSplittersSync();
return active == null ? getMainSplitters() : active;
}
@@ -1639,7 +1638,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Persis
@Nullable
EditorComposite getLastSelected() {
final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow();
final EditorWindow currentWindow = getActiveSplittersSync().getCurrentWindow();
if (currentWindow != null) {
return currentWindow.getSelectedEditor();
}
@@ -91,7 +91,6 @@ ide.windowSystem.hScrollChars=5
ide.windowSystem.vScrollChars=5
ide.windowSystem.autoShowProcessPopup=false
ide.windowSystem.showListItemsPopup=true
ide.windowSystem.asyncSplitters=true
ide.windowSystem.showTooWindowButtonsSwitcher=true
passwordSafe.memorySafe.ttl=-1