mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-204250 Fixed race conditions in plugin manager UI initialization
GitOrigin-RevId: dadfcff9a52671eeda0fa506bdc2d5e337cda58d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
dc8fe0fa76
commit
f3490e3dbd
@@ -521,7 +521,8 @@ public final class PluginManagerConfigurable
|
||||
try {
|
||||
try {
|
||||
if (project != null) {
|
||||
addSuggestedGroup(groups, model.getErrors(), model.getSuggestedPlugins(), model.getInstalledPlugins(), model.getInstallationStates());
|
||||
addSuggestedGroup(groups, model.getErrors(), model.getSuggestedPlugins(), model.getInstalledPlugins(),
|
||||
model.getInstallationStates());
|
||||
}
|
||||
PluginsViewCustomizer.PluginsGroupDescriptor internalPluginsGroupDescriptor = model.getInternalPluginsGroupDescriptor();
|
||||
if (internalPluginsGroupDescriptor != null) {
|
||||
@@ -1093,9 +1094,14 @@ public final class PluginManagerConfigurable
|
||||
//noinspection ConstantConditions
|
||||
((SearchUpDownPopupController)myInstalledSearchPanel.controller).setEventHandler(eventHandler);
|
||||
myInstalledPanel.startLoading();
|
||||
|
||||
PluginsGroup downloaded =
|
||||
new PluginsGroup(IdeBundle.message("plugins.configurable.downloaded"), PluginsGroupType.INSTALLED);
|
||||
|
||||
PluginsGroup installing = new PluginsGroup(IdeBundle.message("plugins.configurable.installing"), PluginsGroupType.INSTALLING);
|
||||
myPluginModelFacade.getModel().setDownloadedGroup(myInstalledPanel, downloaded, installing);
|
||||
PluginManagerPanelFactory.INSTANCE.createInstalledPanel(myCoroutineScope, myPluginModelFacade.getModel(), model -> {
|
||||
try {
|
||||
PluginsGroup installing = new PluginsGroup(IdeBundle.message("plugins.configurable.installing"), PluginsGroupType.INSTALLING);
|
||||
installing.getPreloadedModel().setErrors(model.getErrors());
|
||||
installing.getPreloadedModel().setPluginInstallationStates(model.getInstallationStates());
|
||||
installing.addModels(MyPluginModel.getInstallingPlugins());
|
||||
@@ -1105,8 +1111,6 @@ public final class PluginManagerConfigurable
|
||||
myInstalledPanel.addGroup(installing);
|
||||
}
|
||||
|
||||
PluginsGroup downloaded =
|
||||
new PluginsGroup(IdeBundle.message("plugins.configurable.downloaded"), PluginsGroupType.INSTALLED);
|
||||
downloaded.getPreloadedModel().setErrors(model.getErrors());
|
||||
downloaded.getPreloadedModel().setPluginInstallationStates(model.getInstallationStates());
|
||||
downloaded.addModels(model.getInstalledPlugins());
|
||||
@@ -1481,7 +1485,7 @@ public final class PluginManagerConfigurable
|
||||
|
||||
private void addSuggestedGroup(@NotNull List<? super PluginsGroup> groups,
|
||||
@NotNull Map<@NotNull PluginId,
|
||||
@NotNull List<@NotNull HtmlChunk>> errors,
|
||||
@NotNull List<@NotNull HtmlChunk>> errors,
|
||||
@NotNull List<@NotNull PluginUiModel> plugins,
|
||||
@NotNull Map<@NotNull PluginId, @NotNull PluginUiModel> installedPlugins,
|
||||
@NotNull Map<@NotNull PluginId, @NotNull PluginInstallationState> installationStates) {
|
||||
@@ -2113,7 +2117,7 @@ public final class PluginManagerConfigurable
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
myPluginModelFacade.closeSession();
|
||||
if (ApplicationManager.getApplication().isExitInProgress()) return; // already shutting down
|
||||
if(myPluginManagerCustomizer != null) {
|
||||
if (myPluginManagerCustomizer != null) {
|
||||
myPluginManagerCustomizer.requestRestart(myPluginModelFacade, myTabHeaderComponent);
|
||||
return;
|
||||
}
|
||||
|
||||
+5
@@ -1,6 +1,9 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ide.plugins.marketplace
|
||||
|
||||
import com.intellij.ide.plugins.api.PluginDto
|
||||
import com.intellij.ide.plugins.newui.PluginInstallationState
|
||||
import com.intellij.ide.plugins.newui.PluginUiModel
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -12,4 +15,6 @@ data class ApplyPluginsStateResult(
|
||||
val pluginsToEnable: Set<PluginId> = emptySet(),
|
||||
var needRestart: Boolean = false,
|
||||
@get:NlsSafe var error: String? = null,
|
||||
var visiblePlugins: List<PluginDto> = emptyList(),
|
||||
var installationStates: Map<PluginId, PluginInstallationState> = emptyMap(),
|
||||
)
|
||||
+3
-1
@@ -381,7 +381,9 @@ object DefaultUiPluginManagerController : UiPluginManagerController {
|
||||
}
|
||||
|
||||
session.isUiDisposedWithApply = true
|
||||
return@withContext ApplyPluginsStateResult(pluginsToEnable, needRestart)
|
||||
val pluginInstallationStates = getPluginInstallationStates()
|
||||
val visiblePlugins = getVisiblePlugins(false)
|
||||
return@withContext ApplyPluginsStateResult(pluginsToEnable, needRestart, null, visiblePlugins.map { PluginDto.fromModel(it) }, pluginInstallationStates)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ public final class ListPluginComponent extends JPanel {
|
||||
createTag();
|
||||
|
||||
if (myIsAvailable) {
|
||||
doCreateButtons(pluginInstallationState, listModel.getInstalledModels().get(pluginId));
|
||||
createButtons(listModel.getInstalledModels().get(pluginId), pluginInstallationState);
|
||||
createMetricsPanel();
|
||||
createLicensePanel();
|
||||
}
|
||||
@@ -250,16 +250,7 @@ public final class ListPluginComponent extends JPanel {
|
||||
ColorButton.setWidth72(myInstallButton);
|
||||
}
|
||||
|
||||
private void createButtons() {
|
||||
PluginModelAsyncOperationsExecutor.INSTANCE.createButtons(myCoroutineScope, this, myPlugin.getPluginId(), myMarketplace,
|
||||
(state, model) -> {
|
||||
doCreateButtons(state, model);
|
||||
fullRepaint();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void doCreateButtons(PluginInstallationState installationState, PluginUiModel installedModel) {
|
||||
private void createButtons(PluginUiModel installedModel, PluginInstallationState installationState) {
|
||||
installationState = installationState == null ? new PluginInstallationState(false, null) : installationState;
|
||||
if (myMarketplace) {
|
||||
if (installationState.getStatus() == PluginStatus.INSTALLED_AND_REQUIRED_RESTART) {
|
||||
@@ -783,7 +774,7 @@ public final class ListPluginComponent extends JPanel {
|
||||
}
|
||||
|
||||
public void hideProgress(boolean success, boolean restartRequired, PluginUiModel installedPlugin) {
|
||||
if(succesefullyFinishedOnce) return;
|
||||
if (succesefullyFinishedOnce) return;
|
||||
myIndicator = null;
|
||||
myLayout.removeProgressComponent();
|
||||
|
||||
@@ -809,7 +800,7 @@ public final class ListPluginComponent extends JPanel {
|
||||
else {
|
||||
myPlugin = myInstalledDescriptorForMarketplace;
|
||||
myInstalledDescriptorForMarketplace = null;
|
||||
updateButtons();
|
||||
updateButtons(installedPlugin, new PluginInstallationState(true, PluginStatus.INSTALLED_WITHOUT_RESTART));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -865,7 +856,7 @@ public final class ListPluginComponent extends JPanel {
|
||||
PluginsViewCustomizerKt.getListPluginComponentCustomizer().processRemoveButtons(this);
|
||||
}
|
||||
|
||||
public void updateButtons() {
|
||||
public void updateButtons(PluginUiModel installedPlugin, PluginInstallationState state) {
|
||||
if (myIsAvailable) {
|
||||
removeButtons(false);
|
||||
if (myRestartButton != null) {
|
||||
@@ -877,7 +868,7 @@ public final class ListPluginComponent extends JPanel {
|
||||
myAlignButton = null;
|
||||
}
|
||||
myAfterUpdate = false;
|
||||
createButtons();
|
||||
createButtons(installedPlugin, state);
|
||||
if (myUpdateDescriptor != null) {
|
||||
setUpdateDescriptor(myUpdateDescriptor);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.externalDependencies.ExternalDependenciesManager
|
||||
import com.intellij.ide.IdeBundle
|
||||
import com.intellij.ide.impl.ProjectUtil.getActiveFrameOrWelcomeScreen
|
||||
import com.intellij.ide.plugins.*
|
||||
import com.intellij.ide.plugins.marketplace.ApplyPluginsStateResult
|
||||
import com.intellij.ide.plugins.marketplace.CheckErrorsResult
|
||||
import com.intellij.ide.plugins.marketplace.InstallPluginResult
|
||||
import com.intellij.ide.plugins.newui.PluginLogo.getDefault
|
||||
@@ -125,7 +126,7 @@ open class MyPluginModel(project: Project?) : InstalledPluginsTableModel(project
|
||||
}
|
||||
applyResult.pluginsToEnable.forEach { id -> super.setEnabled(id, PluginEnabledState.ENABLED) }
|
||||
myUninstalled.clear()
|
||||
updateButtons()
|
||||
updateButtons(applyResult)
|
||||
myPluginManagerCustomizer?.updateAfterModification { }
|
||||
return !applyResult.needRestart
|
||||
}
|
||||
@@ -797,11 +798,26 @@ open class MyPluginModel(project: Project?) : InstalledPluginsTableModel(project
|
||||
myCancelInstallCallback = callback
|
||||
}
|
||||
|
||||
private fun updateButtons() {
|
||||
PluginModelAsyncOperationsExecutor.updateButtons(coroutineScope,
|
||||
myInstalledPluginComponents,
|
||||
myMarketplacePluginComponentMap,
|
||||
myDetailPanels)
|
||||
private suspend fun updateButtons(applyResult: ApplyPluginsStateResult) {
|
||||
for (component in myInstalledPluginComponents) {
|
||||
val pluginId = component.pluginModel.pluginId
|
||||
val installedPlugin = applyResult.visiblePlugins.firstOrNull { it.pluginId == pluginId } ?: continue
|
||||
val installationState = applyResult.installationStates[pluginId] ?: continue
|
||||
component.updateButtons(installedPlugin, installationState)
|
||||
}
|
||||
for (plugins in myMarketplacePluginComponentMap.values) {
|
||||
for (plugin in plugins) {
|
||||
if (plugin.myInstalledDescriptorForMarketplace != null) {
|
||||
val pluginId = plugin.pluginModel.pluginId
|
||||
val installedPlugin = applyResult.visiblePlugins.firstOrNull { it.pluginId == pluginId } ?: continue
|
||||
val installationState = applyResult.installationStates[pluginId] ?: continue
|
||||
plugin.updateButtons(installedPlugin, installationState)
|
||||
}
|
||||
}
|
||||
}
|
||||
for (detailPanel in myDetailPanels) {
|
||||
detailPanel.updateAll()
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyChangedStates(changedStates: Map<PluginId, Boolean>) {
|
||||
|
||||
-23
@@ -136,29 +136,6 @@ internal object PluginModelAsyncOperationsExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
fun updateButtons(
|
||||
cs: CoroutineScope,
|
||||
installedPluginComponents: List<ListPluginComponent>,
|
||||
pluginComponentsMap: Map<PluginId, List<ListPluginComponent>>,
|
||||
detailPanels: List<PluginDetailsPageComponent>,
|
||||
) {
|
||||
cs.launch(Dispatchers.EDT + ModalityState.any().asContextElement()) {
|
||||
for (component in installedPluginComponents) {
|
||||
component.updateButtons()
|
||||
}
|
||||
for (plugins in pluginComponentsMap.values) {
|
||||
for (plugin in plugins) {
|
||||
if (plugin.myInstalledDescriptorForMarketplace != null) {
|
||||
plugin.updateButtons()
|
||||
}
|
||||
}
|
||||
}
|
||||
for (detailPanel in detailPanels) {
|
||||
detailPanel.updateAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun findPlugins(pluginIds: Set<PluginId>, callback: (Map<PluginId, PluginUiModel>) -> Unit) {
|
||||
val coroutineScope = service<CoreUiCoroutineScopeHolder>().coroutineScope
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
|
||||
Reference in New Issue
Block a user