[rd debugger] IDEA-377734 Move mute renderers action to frontend

GitOrigin-RevId: 38a3aa2a8c4ca9991e4d1de3c3bd2b51e67bc044
This commit is contained in:
Maksim Zuev
2025-08-20 10:54:25 +00:00
committed by intellij-monorepo-bot
parent bb4679f390
commit 2a885a7037
12 changed files with 101 additions and 44 deletions
+2
View File
@@ -33,6 +33,8 @@ jvm_library(
"//java/execution/openapi:java-execution",
"//platform/xdebugger-impl/shared",
"//platform/xdebugger-impl/rpc",
"//platform/projectModel-api:projectModel",
"//platform/util/jdom",
],
runtime_deps = [":backend_resources"]
)
@@ -53,5 +53,7 @@
<orderEntry type="module" module-name="intellij.java.execution" />
<orderEntry type="module" module-name="intellij.platform.debugger.impl.shared" />
<orderEntry type="module" module-name="intellij.platform.debugger.impl.rpc" />
<orderEntry type="module" module-name="intellij.platform.projectModel" />
<orderEntry type="module" module-name="intellij.platform.util.jdom" />
</component>
</module>
@@ -1,6 +1,7 @@
// 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.java.debugger.impl.backend
import com.intellij.debugger.actions.MuteRendererUtils
import com.intellij.debugger.engine.DebugProcessImpl
import com.intellij.debugger.engine.JavaDebugProcess
import com.intellij.debugger.impl.DebuggerSession
@@ -21,9 +22,12 @@ internal class BackendJavaDebuggerManagerApi : JavaDebuggerManagerApi {
val javaProcess = debuggerSession.process
val sessionStateFlow = debuggerSession.sessionStateFlow
val renderersFlow = MuteRendererUtils.getOrCreateFlow(xSession.sessionData)
return JavaDebuggerSessionDto(
initialState = getJavaSessionState(debuggerSession, javaProcess),
stateFlow = sessionStateFlow.map { getJavaSessionState(debuggerSession, javaProcess) }.toRpc(),
areRenderersMutedInitial = renderersFlow.value,
areRenderersMutedFlow = renderersFlow.toRpc(),
)
}
}
@@ -3,6 +3,7 @@ package com.intellij.java.debugger.impl.backend
import com.intellij.debugger.actions.*
import com.intellij.debugger.engine.*
import com.intellij.debugger.settings.NodeRendererSettings
import com.intellij.execution.filters.ExceptionFilters
import com.intellij.ide.ui.icons.rpcId
import com.intellij.java.debugger.impl.shared.engine.NodeRendererId
@@ -87,6 +88,13 @@ internal class BackendJavaDebuggerSessionApi : JavaDebuggerSessionApi {
}
}
override suspend fun muteRenderers(sessionId: XDebugSessionId, state: Boolean) {
val xSession = sessionId.findValue() ?: return
val renderersFlow = MuteRendererUtils.getFlow(xSession.sessionData)
renderersFlow.value = state
NodeRendererSettings.getInstance().fireRenderersChanged()
}
override suspend fun resumeThread(executionStackId: XExecutionStackId) {
invokeThreadCommand(executionStackId, ThreadCommand.RESUME)
}
@@ -294,8 +294,9 @@
<override-text place="XDebuggerTreePopup"/>
</action>
<action id="Debugger.AutoRenderer" class="com.intellij.java.debugger.impl.shared.actions.AutoRendererAction"/>
<action id="Debugger.MuteRenderers" class="com.intellij.debugger.actions.ForceOnDemandRenderersAction">
<action id="Debugger.MuteRenderers" class="com.intellij.java.debugger.impl.shared.actions.MuteRenderersAction">
<add-to-group group-id="XDebugger.ValueGroup" anchor="last"/>
<add-to-group group-id="XDebugger.Inspect.Tree.Popup.Bottom.Section.Frontend" anchor="last"/>
</action>
<action id="Debugger.SwitchToTheNextContext" class="com.intellij.debugger.actions.SwitchToTheNextContextAction"/>
@@ -1,41 +0,0 @@
// Copyright 2000-2020 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.debugger.actions
import com.intellij.debugger.settings.NodeRendererSettings
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.ToggleAction
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.util.Key
import com.intellij.xdebugger.impl.XDebugSessionImpl
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil
class ForceOnDemandRenderersAction : ToggleAction(), DumbAware {
override fun isSelected(e: AnActionEvent): Boolean {
return RENDERERS_ONDEMAND_FORCED.get(DebuggerUIUtil.getSessionData(e), false)
}
override fun setSelected(e: AnActionEvent, state: Boolean) {
RENDERERS_ONDEMAND_FORCED.set(DebuggerUIUtil.getSessionData(e), state)
NodeRendererSettings.getInstance().fireRenderersChanged()
}
override fun update(e: AnActionEvent) {
super.update(e)
e.presentation.isEnabledAndVisible = DebuggerAction.isInJavaSession(e)
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.BGT
}
companion object {
private val RENDERERS_ONDEMAND_FORCED = Key.create<Boolean>("RENDERERS_ONDEMAND_FORCED")
@JvmStatic
fun isForcedOnDemand(session: XDebugSessionImpl): Boolean {
return RENDERERS_ONDEMAND_FORCED.get(session.sessionData, false)
}
}
}
@@ -0,0 +1,26 @@
// 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.debugger.actions
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.getOrCreateUserData
import com.intellij.xdebugger.impl.ui.XDebugSessionData
import kotlinx.coroutines.flow.MutableStateFlow
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
object MuteRendererUtils {
private val MUTE_RENDERERS_FLOW = Key.create<MutableStateFlow<Boolean>>("MUTE_RENDERERS_FLOW")
fun getOrCreateFlow(sessionData: XDebugSessionData): MutableStateFlow<Boolean> {
return sessionData.getOrCreateUserData(MUTE_RENDERERS_FLOW) { MutableStateFlow(false) }
}
fun getFlow(sessionData: XDebugSessionData): MutableStateFlow<Boolean> {
return sessionData.getUserData(MUTE_RENDERERS_FLOW)!!
}
@JvmStatic
fun isMuted(sessionData: XDebugSessionData): Boolean {
return sessionData.getUserData(MUTE_RENDERERS_FLOW)?.value ?: false
}
}
@@ -1,7 +1,7 @@
// 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.debugger.ui.tree.render;
import com.intellij.debugger.actions.ForceOnDemandRenderersAction;
import com.intellij.debugger.actions.MuteRendererUtils;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.FullValueEvaluatorProvider;
import com.intellij.debugger.engine.JavaDebugProcess;
@@ -102,6 +102,6 @@ public interface OnDemandRenderer extends FullValueEvaluatorProvider {
static boolean isOnDemandForced(DebugProcessImpl debugProcess) {
JavaDebugProcess process = debugProcess.getXdebugProcess();
return process != null && ForceOnDemandRenderersAction.isForcedOnDemand((XDebugSessionImpl)process.getSession());
return process != null && MuteRendererUtils.isMuted(((XDebugSessionImpl)process.getSession()).getSessionData());
}
}
@@ -2,6 +2,8 @@
package com.intellij.java.debugger.impl.shared
import com.intellij.java.debugger.impl.shared.rpc.JavaDebuggerSessionDto
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.SharingStarted
@@ -12,13 +14,24 @@ import org.jetbrains.annotations.ApiStatus
class SharedJavaDebuggerSession(dto: JavaDebuggerSessionDto, private val cs: CoroutineScope) {
private val stateFlow = dto.stateFlow.toFlow()
.stateIn(cs, SharingStarted.Eagerly, dto.initialState)
private val areRenderersMutedFlow = dto.areRenderersMutedFlow.toFlow()
.stateIn(cs, SharingStarted.Eagerly, dto.areRenderersMutedInitial)
val isAttached: Boolean get() = stateFlow.value.isAttached
val isEvaluationPossible: Boolean get() = stateFlow.value.isEvaluationPossible
val areRenderersMuted: Boolean get() = areRenderersMutedFlow.value
internal var isAsyncStacksEnabled: Boolean = true
fun close() {
cs.cancel()
}
companion object {
fun findSession(e: AnActionEvent): SharedJavaDebuggerSession? {
val project = e.project ?: return null
val sessionProxy = DebuggerUIUtil.getSessionProxy(e) ?: return null
return SharedJavaDebuggerManager.getInstance(project).getJavaSession(sessionProxy.id)
}
}
}
@@ -0,0 +1,38 @@
// 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.java.debugger.impl.shared.actions
import com.intellij.java.debugger.impl.shared.SharedJavaDebuggerSession
import com.intellij.java.debugger.impl.shared.SharedJavaDebuggerSession.Companion
import com.intellij.java.debugger.impl.shared.rpc.JavaDebuggerSessionApi
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.ToggleAction
import com.intellij.openapi.actionSystem.remoting.ActionRemoteBehaviorSpecification
import com.intellij.openapi.project.DumbAware
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil
import kotlinx.coroutines.launch
internal class MuteRenderersAction : ToggleAction(), DumbAware, ActionRemoteBehaviorSpecification.FrontendOtherwiseBackend {
override fun isSelected(e: AnActionEvent): Boolean {
val javaSession = SharedJavaDebuggerSession.findSession(e) ?: return false
return javaSession.areRenderersMuted
}
override fun setSelected(e: AnActionEvent, state: Boolean) {
val session = DebuggerUIUtil.getSessionProxy(e) ?: return
session.coroutineScope.launch {
JavaDebuggerSessionApi.getInstance().muteRenderers(session.id, state)
}
}
override fun update(e: AnActionEvent) {
super.update(e)
val javaSession = Companion.findSession(e)
e.presentation.isEnabledAndVisible = javaSession != null
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.BGT
}
}
@@ -28,6 +28,8 @@ interface JavaDebuggerManagerApi : RemoteApi<Unit> {
data class JavaDebuggerSessionDto(
val initialState: JavaSessionState,
val stateFlow: RpcFlow<JavaSessionState>,
val areRenderersMutedInitial: Boolean,
val areRenderersMutedFlow: RpcFlow<Boolean>,
)
@ApiStatus.Internal
@@ -38,6 +38,8 @@ interface JavaDebuggerSessionApi : RemoteApi<Unit> {
suspend fun setRenderer(rendererId: NodeRendererId?, xValueIds: List<XValueId>)
suspend fun muteRenderers(sessionId: XDebugSessionId, state: Boolean)
companion object {
@JvmStatic
suspend fun getInstance(): JavaDebuggerSessionApi {