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 0d0e7a85e4e1..f79f60d4330b 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,13 +15,9 @@ */ 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; @@ -44,7 +40,7 @@ public final class CommandProcessor implements Runnable { /** * Executes passed batch of commands. Note, that the processor surround the - * commands with BlockFocusEventsCmd - UnbockFocusEventsCmd. It's required to + * 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) { @@ -63,32 +59,27 @@ public final class CommandProcessor implements Runnable { public final void run() { synchronized (myLock) { - 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); + //noinspection StatementWithEmptyBody + while (runNext()) { } - // 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(); - } - }); } } + private boolean runNext() { + final CommandGroup commandGroup = getNextCommandGroup(); + if (commandGroup == null || commandGroup.isEmpty()) return false; + + final FinalizableCommand command = commandGroup.takeNextCommand(); + myCommandCount--; + + if (LOG.isDebugEnabled()) { + LOG.debug("CommandProcessor.run " + command); + } + + command.run(); + return true; + } + @Nullable private CommandGroup getNextCommandGroup() { while (!myCommandGroupList.isEmpty()) { 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 8013b4001e93..54632397f6cf 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 @@ -37,14 +37,11 @@ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorsSplitters; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; -import com.intellij.openapi.progress.ProcessCanceledException; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.util.ProgressIndicatorUtils; -import com.intellij.openapi.progress.util.ReadTask; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; -import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.startup.StartupActivity; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Splitter; @@ -62,7 +59,9 @@ import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.switcher.QuickAccessSettings; import com.intellij.ui.switcher.SwitchManager; import com.intellij.util.*; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; +import com.intellij.util.ui.EdtInvocationManager; import com.intellij.util.ui.PositionTracker; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.update.UiNotifyConnector; @@ -100,6 +99,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements private final Map myId2WindowedDecorator = new HashMap<>(); private final Map myId2StripeButton = new HashMap<>(); private final Map myId2FocusWatcher = new HashMap<>(); + private final Set myDumbAwareIds = Collections.synchronizedSet(ContainerUtil.newTroveSet()); private final EditorComponentFocusWatcher myEditorComponentFocusWatcher = new EditorComponentFocusWatcher(); private final MyToolWindowPropertyChangeListener myToolWindowPropertyChangeListener = new MyToolWindowPropertyChangeListener(); @@ -380,20 +380,22 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements myToolWindowsPane = new ToolWindowsPane(myFrame, this); Disposer.register(myProject, myToolWindowsPane); ((IdeRootPane)myFrame.getRootPane()).setToolWindowsPane(myToolWindowsPane); - List commandsList = new ArrayList<>(); - appendUpdateToolWindowsPaneCmd(commandsList); - myFrame.setTitle(FrameTitleBuilder.getInstance().getProjectTitle(myProject)); - JComponent editorComponent = createEditorComponent(myProject); - myEditorComponentFocusWatcher.install(editorComponent); - appendSetEditorComponentCmd(editorComponent, commandsList); - if (myEditorWasActive && editorComponent instanceof EditorsSplitters) { - activateEditorComponentImpl(commandsList, true); - } - execute(commandsList); + final DumbService.DumbModeListener dumbModeListener = new DumbService.DumbModeListener() { + @Override + public void enteredDumbMode() { + disableStripeButtons(); + } - StartupManager.getInstance(myProject).registerPostStartupActivity((DumbAwareRunnable)() -> registerToolWindowsFromBeans()); + @Override + public void exitDumbMode() { + for (final String id : getToolWindowIds()) { + getStripeButton(id).setEnabled(true); + } + } + }; + myProject.getMessageBus().connect().subscribe(DumbService.DUMB_MODE, dumbModeListener); IdeEventQueue.getInstance().addDispatcher(e -> { if (e instanceof KeyEvent) { @@ -406,51 +408,46 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements }, myProject); } + private void initAll() { + List commandsList = new ArrayList<>(); + appendUpdateToolWindowsPaneCmd(commandsList); + + JComponent editorComponent = createEditorComponent(myProject); + myEditorComponentFocusWatcher.install(editorComponent); + + appendSetEditorComponentCmd(editorComponent, commandsList); + if (myEditorWasActive && editorComponent instanceof EditorsSplitters) { + activateEditorComponentImpl(commandsList, true); + } + execute(commandsList); + } + + private void disableStripeButtons() { + for (final String id : getToolWindowIds()) { + if (!myDumbAwareIds.contains(id)) { + if (isToolWindowVisible(id)) { + hideToolWindow(id, true); + } + StripeButton button = getStripeButton(id); + if (button != null) { + button.setEnabled(false); + } + } + } + } + private static JComponent createEditorComponent(@NotNull Project project) { return FrameEditorComponentProvider.EP.getExtensions()[0].createEditorComponent(project); } private void registerToolWindowsFromBeans() { - List beans = new ArrayList<>(Arrays.asList(Extensions.getExtensions(ToolWindowEP.EP_NAME))); - Collections.reverse(beans); - - checkConditionsInReadAction(beans, new ArrayList<>()); - } - - private void checkConditionsInReadAction(@NotNull List beans, @NotNull List checkedSuccessfully) { - ProgressIndicatorUtils.scheduleWithWriteActionPriority(new ReadTask() { - @Nullable - @Override - public Continuation performInReadAction(@NotNull ProgressIndicator indicator) throws ProcessCanceledException { - for (int i = beans.size() - 1; i >= 0; i--) { - indicator.checkCanceled(); - ToolWindowEP bean = beans.remove(i); - Condition condition = ObjectUtils.notNull(bean.getCondition(), Conditions.alwaysTrue()); - if (!myProject.isDisposed() && condition.value(myProject)) { - checkedSuccessfully.add(bean); - } - } - return new Continuation(() -> { - if (!myProject.isDisposed()) { - for (ToolWindowEP bean : checkedSuccessfully) { - if (getToolWindow(bean.id) == null) { - try { - initToolWindow(bean); - } - catch (Throwable e) { - LOG.error(String.format("Tool window %s initialization failed", bean.id), e); - } - } - } - } - }, ModalityState.any()); + List beans = Arrays.asList(Extensions.getExtensions(ToolWindowEP.EP_NAME)); + for (ToolWindowEP bean : beans) { + Condition condition = bean.getCondition(); + if (condition == null || condition.value(myProject)) { + EdtInvocationManager.getInstance().invokeLater(() -> initToolWindow(bean)); } - - @Override - public void onCanceled(@NotNull ProgressIndicator indicator) { - checkConditionsInReadAction(beans, checkedSuccessfully); - } - }); + } } @Override @@ -2454,4 +2451,16 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements WindowInfoImpl info = getInfo(id); return info == null || info.isShowStripeButton(); } + + public static class InitToolWindowsActivity implements StartupActivity, DumbAware { + @Override + public void runActivity(@NotNull Project project) { + ToolWindowManagerEx ex = ToolWindowManagerEx.getInstanceEx(project); + if (ex instanceof ToolWindowManagerImpl) { + ToolWindowManagerImpl myManager = (ToolWindowManagerImpl)ex; + myManager.registerToolWindowsFromBeans(); + EdtInvocationManager.getInstance().invokeLater(() -> myManager.initAll()); + } + } + } } diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index b7970bf6bcbf..60eb886c5d45 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -375,6 +375,7 @@ +