diff --git a/platform/configuration-store-impl/src/HeadlessSaveAndSyncHandler.kt b/platform/configuration-store-impl/src/HeadlessSaveAndSyncHandler.kt index 4a72c4646b4d..080f7ca924ee 100644 --- a/platform/configuration-store-impl/src/HeadlessSaveAndSyncHandler.kt +++ b/platform/configuration-store-impl/src/HeadlessSaveAndSyncHandler.kt @@ -1,6 +1,7 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.configurationStore +import com.intellij.openapi.application.AccessToken import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.ComponentManager @@ -22,6 +23,8 @@ internal class HeadlessSaveAndSyncHandler : BaseSaveAndSyncHandler() { override fun unblockSyncOnFrameActivation() {} + override fun disableAutoSave() = AccessToken.EMPTY_ACCESS_TOKEN + override fun saveSettingsUnderModalProgress(componentManager: ComponentManager, isSaveAppAlso: Boolean): Boolean { StoreUtil.saveSettings(componentManager, forceSavingAllSettings = true) if (isSaveAppAlso && componentManager !== ApplicationManager.getApplication()) { diff --git a/platform/configuration-store-impl/src/SaveAndSyncHandlerImpl.kt b/platform/configuration-store-impl/src/SaveAndSyncHandlerImpl.kt index 5da0595cd90f..84f18c22688b 100644 --- a/platform/configuration-store-impl/src/SaveAndSyncHandlerImpl.kt +++ b/platform/configuration-store-impl/src/SaveAndSyncHandlerImpl.kt @@ -7,6 +7,7 @@ import com.intellij.ide.GeneralSettings import com.intellij.ide.IdeEventQueue import com.intellij.ide.SaveAndSyncHandler import com.intellij.openapi.Disposable +import com.intellij.openapi.application.AccessToken import com.intellij.openapi.application.Application import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ModalityState @@ -74,6 +75,10 @@ internal class SaveAndSyncHandlerImpl : BaseSaveAndSyncHandler(), Disposable { continue } + if (blockSaveOnFrameDeactivationCount.get() > 0 || ProgressManager.getInstance().hasModalProgressIndicator()) { + return + } + LOG.runAndLogException { runBlocking { coroutineScope { @@ -203,7 +208,7 @@ internal class SaveAndSyncHandlerImpl : BaseSaveAndSyncHandler(), Disposable { } var isSavedSuccessfully = true - runInSaveOnFrameDeactivationDisabledMode { + runInAutoSaveDisabledMode { edtPoolDispatcherManager.processTasks() ProgressManager.getInstance().run(object : Task.Modal(componentManager as? Project, "Saving " + (if (componentManager is Application) "Application" else "Project"), /* canBeCancelled = */ false) { @@ -290,6 +295,15 @@ internal class SaveAndSyncHandlerImpl : BaseSaveAndSyncHandler(), Disposable { } } + override fun disableAutoSave(): AccessToken { + blockSaveOnFrameDeactivation() + return object : AccessToken() { + override fun finish() { + unblockSaveOnFrameDeactivation() + } + } + } + override fun blockSaveOnFrameDeactivation() { LOG.debug("save blocked") blockSaveOnFrameDeactivationCount.incrementAndGet() diff --git a/platform/platform-api/src/com/intellij/ide/SaveAndSyncHandler.kt b/platform/platform-api/src/com/intellij/ide/SaveAndSyncHandler.kt index 12cf06498a7e..c08274bb14e4 100644 --- a/platform/platform-api/src/com/intellij/ide/SaveAndSyncHandler.kt +++ b/platform/platform-api/src/com/intellij/ide/SaveAndSyncHandler.kt @@ -1,6 +1,7 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide +import com.intellij.openapi.application.AccessToken import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ModalityState import com.intellij.openapi.components.ComponentManager @@ -53,6 +54,8 @@ abstract class SaveAndSyncHandler { abstract fun refreshOpenFiles() + abstract fun disableAutoSave(): AccessToken + abstract fun blockSaveOnFrameDeactivation() abstract fun unblockSaveOnFrameDeactivation() diff --git a/platform/platform-impl/src/com/intellij/configurationStore/storeUtil.kt b/platform/platform-impl/src/com/intellij/configurationStore/storeUtil.kt index 5e0567e9043c..983f36baf37e 100644 --- a/platform/platform-impl/src/com/intellij/configurationStore/storeUtil.kt +++ b/platform/platform-impl/src/com/intellij/configurationStore/storeUtil.kt @@ -168,13 +168,8 @@ private suspend fun saveAllProjects(forceSavingAllSettings: Boolean) { } } -inline fun runInSaveOnFrameDeactivationDisabledMode(task: () -> Unit) { - val saveAndSyncManager = SaveAndSyncHandler.getInstance() - saveAndSyncManager.blockSaveOnFrameDeactivation() - try { +inline fun runInAutoSaveDisabledMode(task: () -> Unit) { + SaveAndSyncHandler.getInstance().disableAutoSave().use { task() } - finally { - saveAndSyncManager.unblockSaveOnFrameDeactivation() - } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/CloseProjectWindowHelper.kt b/platform/platform-impl/src/com/intellij/openapi/wm/impl/CloseProjectWindowHelper.kt index ff198429275e..e4274347a87f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/CloseProjectWindowHelper.kt +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/CloseProjectWindowHelper.kt @@ -1,7 +1,7 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.wm.impl -import com.intellij.configurationStore.runInSaveOnFrameDeactivationDisabledMode +import com.intellij.configurationStore.runInAutoSaveDisabledMode import com.intellij.ide.AppLifecycleListener import com.intellij.ide.GeneralSettings import com.intellij.ide.SaveAndSyncHandler @@ -39,7 +39,7 @@ open class CloseProjectWindowHelper { protected open fun getNumberOfOpenedProjects() = ProjectManager.getInstance().openProjects.size protected open fun closeProjectAndShowWelcomeFrameIfNoProjectOpened(project: Project?) { - runInSaveOnFrameDeactivationDisabledMode { + runInAutoSaveDisabledMode { if (project != null && project.isOpen) { ProjectManagerEx.getInstanceEx().closeAndDispose(project) } diff --git a/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java b/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java index bd2639744a75..93878c9fbbd8 100644 --- a/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java +++ b/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java @@ -11,6 +11,7 @@ import com.intellij.ide.impl.OpenProjectTask; import com.intellij.ide.impl.ProjectUtil; import com.intellij.ide.lightEdit.LightEditUtil; import com.intellij.ide.util.PsiNavigationSupport; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; @@ -188,22 +189,13 @@ public final class PlatformProjectOpenProcessor extends ProjectOpenProcessor imp } } - SaveAndSyncHandler saveAndSyncHandler = ApplicationManager.getApplication().getServiceIfCreated(SaveAndSyncHandler.class); - if (saveAndSyncHandler != null) { - saveAndSyncHandler.blockSyncOnFrameActivation(); - } - try { + try (AccessToken ignored = SaveAndSyncHandler.getInstance().disableAutoSave()) { Project project = openExistingProject(file, baseDir, options); if (project != null && file != baseDir && !Files.isDirectory(file)) { openFileFromCommandLine(project, file, line); } return project; } - finally { - if (saveAndSyncHandler != null) { - saveAndSyncHandler.unblockSyncOnFrameActivation(); - } - } } @Nullable @@ -211,9 +203,13 @@ public final class PlatformProjectOpenProcessor extends ProjectOpenProcessor imp public static Project openExistingProject(@NotNull Path file, @Nullable("null for IPR project") Path projectDir, @NotNull OpenProjectTask options) { - if (options.getProject() != null && ProjectManagerEx.getInstanceEx().isProjectOpened(options.getProject())) { - return null; + if (options.getProject() != null) { + ProjectManagerEx projectManager = ProjectManagerEx.getInstanceExIfCreated(); + if (projectManager != null && projectManager.isProjectOpened(options.getProject())) { + return null; + } } + Activity activity = StartUpMeasurer.startMainActivity("project opening preparation"); if (!options.forceOpenInNewFrame) { Project[] openProjects = ProjectUtil.getOpenProjects(); diff --git a/platform/platform-impl/src/com/intellij/platform/ProjectFrameAllocator.kt b/platform/platform-impl/src/com/intellij/platform/ProjectFrameAllocator.kt index fb81a5929dbe..059f8ba1c3d2 100644 --- a/platform/platform-impl/src/com/intellij/platform/ProjectFrameAllocator.kt +++ b/platform/platform-impl/src/com/intellij/platform/ProjectFrameAllocator.kt @@ -1,6 +1,7 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.platform +import com.intellij.configurationStore.runInAutoSaveDisabledMode import com.intellij.conversion.CannotConvertException import com.intellij.diagnostic.ActivityCategory import com.intellij.diagnostic.runActivity @@ -29,7 +30,9 @@ import java.nio.file.Path internal open class ProjectFrameAllocator { open fun run(task: Runnable): Boolean { - task.run() + runInAutoSaveDisabledMode { + task.run() + } return true } @@ -58,23 +61,26 @@ internal class ProjectUiFrameAllocator(private var options: OpenProjectTask, pri override fun run(task: Runnable): Boolean { var completed = false - ApplicationManager.getApplication().invokeAndWait { - val frame = createFrameIfNeeded() - completed = ProgressManager.getInstance().runProcessWithProgressSynchronously({ - if (frameHelper == null) { - ApplicationManager.getApplication().invokeLater { - if (cancelled) { - return@invokeLater + runInAutoSaveDisabledMode { + ApplicationManager.getApplication().invokeAndWait { + val frame = createFrameIfNeeded() + completed = ProgressManager.getInstance().runProcessWithProgressSynchronously( + { + if (frameHelper == null) { + ApplicationManager.getApplication().invokeLater { + if (cancelled) { + return@invokeLater + } + + runActivity("project frame initialization") { + initNewFrame(frame) + } + } } - runActivity("project frame initialization") { - initNewFrame(frame) - } - } - } - - task.run() - }, "Loading ${projectFile.fileName} Project", true, null, frame.rootPane) + task.run() + }, "Loading ${projectFile.fileName} Project", true, null, frame.rootPane) + } } return completed }