diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/CommandProcessor.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/CommandProcessor.java index f79f60d4330b..acb4db25073f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/CommandProcessor.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/CommandProcessor.java @@ -15,9 +15,13 @@ */ package com.intellij.openapi.wm.impl; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Conditions; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.impl.commands.FinalizableCommand; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,7 +47,7 @@ public final class CommandProcessor implements Runnable { * commands with BlockFocusEventsCmd - UnblockFocusEventsCmd. It's required to * prevent focus handling of events which is caused by the commands to be executed. */ - public final void execute(@NotNull List commandList, @NotNull Condition expired) { + void execute(@NotNull List commandList, @NotNull Condition expired, boolean synchronously) { synchronized (myLock) { final boolean isBusy = myCommandCount > 0; @@ -52,16 +56,44 @@ public final class CommandProcessor implements Runnable { myCommandCount += commandList.size(); if (!isBusy) { - run(); + if (synchronously) { + //noinspection StatementWithEmptyBody + while (runNext()) { + } + } + else { + run(); + } } } } public final void run() { synchronized (myLock) { - //noinspection StatementWithEmptyBody - while (runNext()) { + + final CommandGroup commandGroup = getNextCommandGroup(); + if (commandGroup == null || commandGroup.isEmpty()) return; + + final Condition conditionForGroup = commandGroup.getExpireCondition(); + + final FinalizableCommand command = commandGroup.takeNextCommand(); + myCommandCount--; + + final Condition expire = command.getExpireCondition() != null ? command.getExpireCondition() : conditionForGroup; + + if (LOG.isDebugEnabled()) { + LOG.debug("CommandProcessor.run " + command); } + // max. I'm not actually quite sure this should have NON_MODAL modality but it should + // definitely have some since runnables in command list may (and do) request some PSI activity + final boolean queueNext = myCommandCount > 0; + Application application = ApplicationManager.getApplication(); + ModalityState modalityState = Registry.is("ide.perProjectModality") ? ModalityState.current() : ModalityState.NON_MODAL; + application.getInvokator().invokeLater(command, modalityState, expire == null ? application.getDisposed() : expire).doWhenDone(() -> { + if (queueNext) { + this.run(); + } + }); } } 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 edec3ae37125..b2b6ae086e75 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 @@ -522,7 +522,11 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements * This is helper method. It delegated its functionality to the WindowManager. * Before delegating it fires state changed. */ - public void execute(@NotNull List commandList) { + void execute(@NotNull List commandList) { + execute(commandList, false); + } + + private void execute(@NotNull List commandList, boolean synchronously) { for (FinalizableCommand each : commandList) { if (each.willChangeState()) { fireStateChanged(); @@ -533,7 +537,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements for (FinalizableCommand each : commandList) { each.beforeExecute(this); } - myWindowManager.getCommandProcessor().execute(commandList, myProject.getDisposed()); + myWindowManager.getCommandProcessor().execute(commandList, myProject.getDisposed(), synchronously); } @Override @@ -2442,7 +2446,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements myManager.registerToolWindowsFromBeans(list); myManager.initAll(list); EdtInvocationManager.getInstance().invokeLater(() -> { - myManager.execute(list); + myManager.execute(list, true); }); } }