From a866ebb5ea09f6e1a6ef75bea73f28b2e779deaa Mon Sep 17 00:00:00 2001 From: "Ilia.Shulgin" Date: Tue, 25 Nov 2025 15:05:34 +0100 Subject: [PATCH] fix (vcs): Merge AllowExcludeFromCommitStateHolder into ChangesViewWorkflowManager Previously `workflowManager.commitWorkflowHandler` with side effect of `updateCommitWorkflowHandler` was called in the constructor blocking EDT. Also, get rid of `ChangesViewEx.isAllowExcludeFromCommit`. Fixes IJPL-219614 GitOrigin-RevId: 22c4b55d2f96d317d3288a2c82fda492d2a1917b --- platform/vcs-impl/api-dump.txt | 3 +- .../AllowExcludeFromCommitStateHolder.kt | 38 ------------------- .../ChangesViewDiffPreviewProcessor.kt | 2 +- .../openapi/vcs/changes/ChangesViewEx.kt | 2 - .../vcs/changes/ChangesViewManager.java | 5 --- .../vcs/changes/ChangesViewWorkflowManager.kt | 3 ++ .../changes/ChangesViewWorkflowManagerImpl.kt | 28 +++++++++++--- .../openapi/vcs/changes/DummyChangesView.java | 5 --- ...howDiffFromLocalChangesActionProvider.java | 2 +- .../vcs/changes/ChangesViewApiImpl.kt | 4 +- 10 files changed, 30 insertions(+), 62 deletions(-) delete mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/changes/AllowExcludeFromCommitStateHolder.kt diff --git a/platform/vcs-impl/api-dump.txt b/platform/vcs-impl/api-dump.txt index 56d197956f42..da36e16cb375 100644 --- a/platform/vcs-impl/api-dump.txt +++ b/platform/vcs-impl/api-dump.txt @@ -758,7 +758,6 @@ f:com.intellij.openapi.vcs.changes.ChangesPreprocess com.intellij.openapi.vcs.changes.ChangesViewEx - com.intellij.openapi.vcs.changes.ChangesViewI - a:getCommitWorkflowHandler():com.intellij.vcs.commit.ChangesViewCommitWorkflowHandler -- a:isAllowExcludeFromCommit():Z - a:resetViewImmediatelyAndRefreshLater():V - a:scheduleRefresh(java.lang.Runnable):V com.intellij.openapi.vcs.changes.ChangesViewI @@ -778,7 +777,6 @@ c:com.intellij.openapi.vcs.changes.ChangesViewManager - s:getInstance(com.intellij.openapi.project.Project):com.intellij.openapi.vcs.changes.ChangesViewI - s:getInstanceEx(com.intellij.openapi.project.Project):com.intellij.openapi.vcs.changes.ChangesViewEx - s:getLocalChangesToolWindowName(com.intellij.openapi.project.Project):java.lang.String -- isAllowExcludeFromCommit():Z - isDiffPreviewAvailable():Z - resetViewImmediatelyAndRefreshLater():V - scheduleRefresh():V @@ -798,6 +796,7 @@ c:com.intellij.openapi.vcs.changes.ChangesViewManager$DisplayNameSupplier Fa:com.intellij.openapi.vcs.changes.ChangesViewWorkflowManager - sf:Companion:com.intellij.openapi.vcs.changes.ChangesViewWorkflowManager$Companion - sf:TOPIC:com.intellij.util.messages.Topic +- a:getAllowExcludeFromCommit():kotlinx.coroutines.flow.StateFlow - f:getCommitWorkflowHandler():com.intellij.vcs.commit.ChangesViewCommitWorkflowHandler - sf:getInstance(com.intellij.openapi.project.Project):com.intellij.openapi.vcs.changes.ChangesViewWorkflowManager com.intellij.openapi.vcs.changes.ChangesViewWorkflowManager$ChangesViewWorkflowListener diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/AllowExcludeFromCommitStateHolder.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/AllowExcludeFromCommitStateHolder.kt deleted file mode 100644 index 60f23770baa4..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/AllowExcludeFromCommitStateHolder.kt +++ /dev/null @@ -1,38 +0,0 @@ -// 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.openapi.vcs.changes - -import com.intellij.openapi.components.Service -import com.intellij.openapi.project.Project -import com.intellij.vcs.commit.ChangesViewCommitWorkflowHandler -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow - -@Service(Service.Level.PROJECT) -internal class AllowExcludeFromCommitStateHolder(project: Project) { - private val _allowExcludeFromCommit = MutableStateFlow(false) - val allowExcludeFromCommit: StateFlow = _allowExcludeFromCommit.asStateFlow() - - init { - val workflowManager = ChangesViewWorkflowManager.getInstance(project) - project.messageBus.connect().subscribe(ChangesViewWorkflowManager.TOPIC, ChangesViewWorkflowManager.ChangesViewWorkflowListener { - registerListener(workflowManager.commitWorkflowHandler) - }) - - val currentWorkflowHandler = workflowManager.commitWorkflowHandler - registerListener(currentWorkflowHandler) - } - - private fun registerListener(workflowHandler: ChangesViewCommitWorkflowHandler?) { - workflowHandler?.addActivityListener(object : ChangesViewCommitWorkflowHandler.ActivityListener { - override fun activityStateChanged() { - allowExcludeFromCommit(workflowHandler) - } - }) - allowExcludeFromCommit(workflowHandler) - } - - private fun allowExcludeFromCommit(workflowHandler: ChangesViewCommitWorkflowHandler?) { - _allowExcludeFromCommit.value = workflowHandler?.isActive == true - } -} \ No newline at end of file diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewDiffPreviewProcessor.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewDiffPreviewProcessor.kt index b4ba77e53887..cb56a6467ef3 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewDiffPreviewProcessor.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewDiffPreviewProcessor.kt @@ -89,7 +89,7 @@ class ChangesViewDiffPreviewProcessor( fun subscribeOnAllowExcludeFromCommit() { VcsDisposable.getInstance(project).coroutineScope.launch { - project.serviceAsync().allowExcludeFromCommit.collect { + project.serviceAsync().allowExcludeFromCommit.collect { withContext(Dispatchers.EDT) { setAllowExcludeFromCommit(it) } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewEx.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewEx.kt index 6410919ffe2d..ba0160a434fa 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewEx.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewEx.kt @@ -16,8 +16,6 @@ interface ChangesViewEx : ChangesViewI { @CalledInAny fun scheduleRefresh(@RequiresBackgroundThread callback: Runnable) - val isAllowExcludeFromCommit: Boolean - @get:Deprecated("Use {@link ChangesViewWorkflowManager#getCommitWorkflowHandler}.") val commitWorkflowHandler: ChangesViewCommitWorkflowHandler? } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java index 5dbdfc0b8d08..4c703c195f1b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java @@ -214,11 +214,6 @@ public class ChangesViewManager implements ChangesViewEx, Disposable { myToolWindowPanel.updateCommitWorkflow(); } - @Override - public boolean isAllowExcludeFromCommit() { - return myProject.getService(AllowExcludeFromCommitStateHolder.class).getAllowExcludeFromCommit().getValue(); - } - public void closeEditorPreview(boolean onlyIfEmpty) { if (myToolWindowPanel == null) return; myToolWindowPanel.closeEditorPreview(onlyIfEmpty); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewWorkflowManager.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewWorkflowManager.kt index 62cd44aecb7a..b72bac541b05 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewWorkflowManager.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewWorkflowManager.kt @@ -5,6 +5,7 @@ import com.intellij.openapi.components.service import com.intellij.openapi.project.Project import com.intellij.util.messages.Topic import com.intellij.vcs.commit.ChangesViewCommitWorkflowHandler +import kotlinx.coroutines.flow.StateFlow import org.jetbrains.annotations.ApiStatus import java.util.* @@ -13,6 +14,8 @@ abstract class ChangesViewWorkflowManager @ApiStatus.Internal protected construc val commitWorkflowHandler: ChangesViewCommitWorkflowHandler? get() = doGetCommitWorkflowHandler() + abstract val allowExcludeFromCommit: StateFlow + @ApiStatus.Internal protected abstract fun doGetCommitWorkflowHandler(): ChangesViewCommitWorkflowHandler? diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewWorkflowManagerImpl.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewWorkflowManagerImpl.kt index 8d5176315c8b..79fb59a0340c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewWorkflowManagerImpl.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewWorkflowManagerImpl.kt @@ -10,10 +10,15 @@ import com.intellij.openapi.util.Disposer import com.intellij.util.concurrency.annotations.RequiresEdt import com.intellij.vcs.commit.* import com.intellij.vcs.commit.CommitModeManager.Companion.subscribeOnCommitModeChange +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow internal class ChangesViewWorkflowManagerImpl( private val project: Project, ) : ChangesViewWorkflowManager(), Disposable { + private val _allowExcludeFromCommit = MutableStateFlow(false) + override val allowExcludeFromCommit: StateFlow = _allowExcludeFromCommit.asStateFlow() private var _commitWorkflowHandler: ChangesViewCommitWorkflowHandler? = null @@ -43,9 +48,7 @@ internal class ChangesViewWorkflowManagerImpl( val changesView = (ChangesViewManager.getInstance(project) as ChangesViewManager).initChangesView() val workflow = ChangesViewCommitWorkflow(project) val commitPanel = ChangesViewCommitPanel(project, changesView) - _commitWorkflowHandler = ChangesViewCommitWorkflowHandler(workflow, commitPanel) - - project.messageBus.syncPublisher(TOPIC).commitWorkflowChanged() + setCommitWorkflowHandler(ChangesViewCommitWorkflowHandler(workflow, commitPanel)) activity.end() } @@ -56,13 +59,26 @@ internal class ChangesViewWorkflowManagerImpl( else { if (currentHandler != null) { Disposer.dispose(currentHandler) - _commitWorkflowHandler = null - - project.messageBus.syncPublisher(TOPIC).commitWorkflowChanged() + setCommitWorkflowHandler(null) } } } + private fun setCommitWorkflowHandler(handler: ChangesViewCommitWorkflowHandler?) { + _commitWorkflowHandler = handler + if (handler != null) { + handler.addActivityListener(object : ChangesViewCommitWorkflowHandler.ActivityListener { + override fun activityStateChanged() { + _allowExcludeFromCommit.value = handler.isActive + } + }) + _allowExcludeFromCommit.value = handler.isActive + } else { + _allowExcludeFromCommit.value = false + } + project.messageBus.syncPublisher(TOPIC).commitWorkflowChanged() + } + override fun dispose() { val handler = _commitWorkflowHandler if (handler != null) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DummyChangesView.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DummyChangesView.java index 176e5b2f1737..c846fa500822 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DummyChangesView.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DummyChangesView.java @@ -56,11 +56,6 @@ class DummyChangesView implements ChangesViewEx { public void scheduleRefresh(@NotNull Runnable callback) { } - @Override - public boolean isAllowExcludeFromCommit() { - return false; - } - @Override public @Nullable ChangesViewCommitWorkflowHandler getCommitWorkflowHandler() { return null; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffFromLocalChangesActionProvider.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffFromLocalChangesActionProvider.java index 05bb1209f810..674095cb0fa4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffFromLocalChangesActionProvider.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffFromLocalChangesActionProvider.java @@ -197,7 +197,7 @@ public class ShowDiffFromLocalChangesActionProvider implements AnActionExtension } private static void setAllowExcludeFromCommit(@NotNull Project project, @NotNull DiffRequestChain chain) { - boolean allowExcludeFromCommit = ChangesViewManager.getInstanceEx(project).isAllowExcludeFromCommit(); + boolean allowExcludeFromCommit = ChangesViewWorkflowManager.getInstance(project).getAllowExcludeFromCommit().getValue(); chain.putUserData(ALLOW_EXCLUDE_FROM_COMMIT, allowExcludeFromCommit); } } diff --git a/platform/vcs-impl/src/com/intellij/vcs/changes/ChangesViewApiImpl.kt b/platform/vcs-impl/src/com/intellij/vcs/changes/ChangesViewApiImpl.kt index f4e23bbe18f2..504e1bba9526 100644 --- a/platform/vcs-impl/src/com/intellij/vcs/changes/ChangesViewApiImpl.kt +++ b/platform/vcs-impl/src/com/intellij/vcs/changes/ChangesViewApiImpl.kt @@ -6,8 +6,8 @@ import com.intellij.openapi.components.serviceAsync import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.diagnostic.trace import com.intellij.openapi.vcs.AbstractVcsHelper -import com.intellij.openapi.vcs.changes.AllowExcludeFromCommitStateHolder import com.intellij.openapi.vcs.changes.ChangesUtil +import com.intellij.openapi.vcs.changes.ChangesViewWorkflowManager import com.intellij.openapi.vcs.changes.InclusionListener import com.intellij.openapi.vcs.changes.InclusionModel import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager @@ -56,7 +56,7 @@ internal class ChangesViewApiImpl : ChangesViewApi { } override suspend fun canExcludeFromCommit(projectId: ProjectId): Flow = getProjectScoped(projectId) { project -> - project.serviceAsync().allowExcludeFromCommit + project.serviceAsync().allowExcludeFromCommit } ?: flowOf(false) override suspend fun showResolveConflictsDialog(projectId: ProjectId, changeIds: List) = projectScoped(projectId) { project ->