From ec3631efaea90b3bd7f02c33d449e10bd89ff8d4 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Thu, 13 Oct 2016 17:41:26 +0300 Subject: [PATCH] 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) --- .../ide/actions/CloseEditorAction.java | 4 +- .../fileEditor/ex/FileEditorManagerEx.java | 5 +- .../impl/FileEditorManagerImpl.java | 81 +++++++++---------- .../util/resources/misc/registry.properties | 1 - 4 files changed, 46 insertions(+), 45 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorAction.java index 0975b1219bf9..b2adccb0c820 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorAction.java @@ -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); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java index 0d29eff4c53c..13b1caf2bf26 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java @@ -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 null 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 getActiveWindow(); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java index 019b3ac99377..d05c0446a3bc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -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 getActiveSplitters(boolean syncUsage) { - final boolean async = Registry.is("ide.windowSystem.asyncSplitters") && !syncUsage; - + private AsyncResult getActiveSplittersAsync() { final AsyncResult 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 getActiveWindow() { - return _getActiveWindow(false); - } - - @NotNull - private AsyncResult _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 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(); } diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 12201700c919..4dda4ac17e20 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -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