mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[Run configurations] IJPL-11679 Run widget doesn't use last run config if its stored externally in .run folder
this fixes tests in RunConfigurationSchemeManagerTest: `project loading - initially selected run config stored in run_xml file` and `set any run config as selected if no info` GitOrigin-RevId: 7d4225a9ac127955e6b370b042ecbd936c06b0d4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b25a5eedf0
commit
a5a139dd05
@@ -16,10 +16,7 @@ import com.intellij.ide.plugins.DynamicPluginListener
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.application.*
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.components.impl.stores.stateStore
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
@@ -30,9 +27,9 @@ import com.intellij.openapi.extensions.PluginDescriptor
|
||||
import com.intellij.openapi.extensions.ProjectExtensionPointName
|
||||
import com.intellij.openapi.options.SchemeManagerFactory
|
||||
import com.intellij.openapi.project.IndexNotReadyException
|
||||
import com.intellij.openapi.project.InitialVfsRefreshService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeature
|
||||
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeaturesCollector
|
||||
import com.intellij.openapi.util.Computable
|
||||
@@ -51,7 +48,6 @@ import com.intellij.serviceContainer.NonInjectable
|
||||
import com.intellij.ui.ExperimentalUI
|
||||
import com.intellij.ui.IconManager
|
||||
import com.intellij.util.IconUtil
|
||||
import com.intellij.util.ModalityUiUtil
|
||||
import com.intellij.util.ThreeState
|
||||
import com.intellij.util.concurrency.AppExecutorUtil
|
||||
import com.intellij.util.concurrency.SynchronizedClearableLazy
|
||||
@@ -60,9 +56,11 @@ import com.intellij.util.containers.mapSmart
|
||||
import com.intellij.util.containers.nullize
|
||||
import com.intellij.util.containers.toMutableSmartList
|
||||
import com.intellij.util.text.UniqueNameGenerator
|
||||
import com.intellij.util.text.nullize
|
||||
import com.intellij.util.ui.JBUI
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.annotations.VisibleForTesting
|
||||
@@ -165,14 +163,7 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, share
|
||||
|
||||
// When readExternal not all configuration may be loaded, so we need to remember the selected configuration
|
||||
// so that when it is eventually loaded, we can mark is as a selected.
|
||||
// See also notYetAppliedInitialSelectedConfigurationId,
|
||||
// which helps when the initially selected RC is stored in some arbitrary *.run.xml file in a project
|
||||
protected open var selectedConfigurationId: String? = null
|
||||
// RCs stored in arbitrary *.run.xml files are loaded a bit later than RCs from workspace and from .idea/runConfigurations.
|
||||
// This var helps if initially selected RC is a one from such a file.
|
||||
// Empty string means that there's no information about initially selected RC in workspace.xml => IDE should select any.
|
||||
private var notYetAppliedInitialSelectedConfigurationId: String? = null
|
||||
private var selectedRCSetupScheduled: Boolean = false
|
||||
|
||||
private val iconAndInvalidCache = RunConfigurationIconAndInvalidCache()
|
||||
|
||||
@@ -422,28 +413,7 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, share
|
||||
continue
|
||||
}
|
||||
|
||||
if (!StartupManager.getInstance(project).postStartupActivityPassed()) {
|
||||
// Empty string means that there's no information about initially selected RC in workspace.xml => IDE should select any.
|
||||
if (!selectedRCSetupScheduled && (notYetAppliedInitialSelectedConfigurationId == runConfig.uniqueID ||
|
||||
notYetAppliedInitialSelectedConfigurationId == "" && runConfig.type.isManaged)) {
|
||||
selectedRCSetupScheduled = true
|
||||
// The Project is being loaded.
|
||||
// Finally, we can set the right RC as 'selected' in the RC combo box.
|
||||
// Need to set selectedConfiguration in EDT
|
||||
// to avoid deadlock with ExecutionTargetManagerImpl or similar implementations of runConfigurationSelected()
|
||||
StartupManager.getInstance(project).runAfterOpened {
|
||||
ModalityUiUtil.invokeLaterIfNeeded(ModalityState.nonModal(), project.disposed, Runnable {
|
||||
// Empty string means that there's no information about initially selected RC in workspace.xml
|
||||
// => IDE should select any if still none selected (CLion could have set the selected RC itself).
|
||||
if (selectedConfiguration == null || notYetAppliedInitialSelectedConfigurationId != "") {
|
||||
selectedConfiguration = runConfig
|
||||
}
|
||||
notYetAppliedInitialSelectedConfigurationId = null
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (selectedConfigurationId == null && runConfig.uniqueID == oldSelectedId) {
|
||||
if (selectedConfigurationId == null && runConfig.uniqueID == oldSelectedId) {
|
||||
// don't loosely currently select RC in case of any external changes in the file
|
||||
selectedConfigurationId = oldSelectedId
|
||||
}
|
||||
@@ -943,9 +913,15 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, share
|
||||
}
|
||||
|
||||
if (selectedConfiguration == null) {
|
||||
// Empty string means that there's no information about initially selected RC in workspace.xml => IDE should select any.
|
||||
notYetAppliedInitialSelectedConfigurationId = selectedConfigurationId ?: ""
|
||||
val runConfigIdToSelect = selectedConfigurationId.nullize()
|
||||
|
||||
selectAnyConfiguration()
|
||||
|
||||
// More run configurations may get loaded later by RunConfigurationInArbitraryFileScanner.
|
||||
// We may need to update the selected RC when it's done.
|
||||
if (runConfigIdToSelect != null || selectedConfiguration == null) {
|
||||
updateSelectedRunConfigWhenFileScannerIsDone(runConfigIdToSelect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -953,6 +929,30 @@ open class RunManagerImpl @NonInjectable constructor(val project: Project, share
|
||||
selectedConfiguration = allSettings.firstOrNull { it.type.isManaged }
|
||||
}
|
||||
|
||||
private fun updateSelectedRunConfigWhenFileScannerIsDone(runConfigIdToSelect: String?) {
|
||||
val currentSelectedConfigId = selectedConfigurationId
|
||||
|
||||
(project as ComponentManagerEx).getCoroutineScope().launch(Dispatchers.Default) {
|
||||
project.serviceAsync<InitialVfsRefreshService>().awaitInitialVfsRefreshFinished()
|
||||
|
||||
// RunConfigurationInArbitraryFileScanner has finished its initial scanning, all RCs are loaded.
|
||||
// Now we can set the right RC as 'selected' in the RC combo box.
|
||||
// EDT is needed to avoid deadlock with ExecutionTargetManagerImpl or similar implementations of runConfigurationSelected()
|
||||
withContext(Dispatchers.EDT + ModalityState.nonModal().asContextElement()) {
|
||||
val runConfigToSelect = lock.read {
|
||||
// don't change the selected RC if it has been already changed and is not null
|
||||
if (currentSelectedConfigId != selectedConfigurationId && selectedConfigurationId != null) return@read null
|
||||
// select the 'correct' RC if it is available
|
||||
runConfigIdToSelect?.let { idToSettings[runConfigIdToSelect] }?.let { return@read it }
|
||||
// select any RC if none is selected
|
||||
if (selectedConfiguration == null) return@read allSettings.firstOrNull { it.type.isManaged }
|
||||
return@read null
|
||||
}
|
||||
runConfigToSelect?.let { selectedConfiguration = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun readContext(parentNode: Element) {
|
||||
var selectedConfigurationId = parentNode.getAttributeValue(SELECTED_ATTR)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user