From 22aed2e59d862f10d131f05dbe9aff52b545156c Mon Sep 17 00:00:00 2001 From: Maria Sokolova Date: Wed, 12 Nov 2025 20:11:47 +0000 Subject: [PATCH] [debugger] Do not update XThreadsView if it's not visible IDEA-381500 Merge-request: IJ-MR-182151 Merged-by: Maria Sokolova (cherry picked from commit 58f3197837b12bade23c35641aca22bda8b691df) (cherry picked from commit f0c0e5f1c39cb6e48dccd842362f0f8fdf9092ac) IJ-CR-182318 GitOrigin-RevId: 741ad09f14be497232fc1b1e16fda0143d73e3cc --- .../xdebugger/impl/frame/XThreadsView.kt | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XThreadsView.kt b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XThreadsView.kt index c143adca80ce..647392d198fa 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XThreadsView.kt +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XThreadsView.kt @@ -1,6 +1,7 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.xdebugger.impl.frame +import com.intellij.openapi.application.EDT import com.intellij.openapi.project.Project import com.intellij.openapi.util.NlsSafe import com.intellij.platform.debugger.impl.rpc.XDebugSessionApi @@ -18,15 +19,26 @@ import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.jetbrains.annotations.ApiStatus import java.awt.Component +import java.awt.event.HierarchyEvent import javax.swing.JPanel +@OptIn(FlowPreview::class) @ApiStatus.Internal class XThreadsView(project: Project, session: XDebugSessionProxy) : XDebugView() { + private val rebuildRequests = MutableSharedFlow(replay = 1, extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) + private var wasShowing = false + @ApiStatus.Obsolete constructor(project: Project, session: XDebugSession) : this(project, session.asProxy()) @@ -52,16 +64,36 @@ class XThreadsView(project: Project, session: XDebugSessionProxy) : XDebugView() } }.install(tree) + panel.addHierarchyListener { e -> + if ((e.changeFlags and HierarchyEvent.SHOWING_CHANGED.toLong()) > 0) { + val isCurrentlyShowing = panel.isShowing + if (!wasShowing && isCurrentlyShowing) { + requestRebuild() + } + wasShowing = isCurrentlyShowing + } + } + subscribeToThreadRefreshEvents(session) + + session.coroutineScope.launch { + rebuildRequests + .debounce(200) + .collectLatest { + withContext(Dispatchers.EDT) { + if (panel.isShowing) { + tree.setRoot(XThreadsRootNode(tree, session), false) + } + } + } + } } private fun subscribeToThreadRefreshEvents(session: XDebugSessionProxy) { session.coroutineScope.launch { XDebugSessionApi.getInstance().getUiUpdateEventsFlow(session.id) .collectLatest { - DebuggerUIUtil.invokeLater { - tree.setRoot(XThreadsRootNode(tree, session), false) - } + requestRebuild() } } } @@ -74,6 +106,10 @@ class XThreadsView(project: Project, session: XDebugSessionProxy) : XDebugView() fun getDefaultFocusedComponent(): XDebuggerTree = tree + private fun requestRebuild() { + rebuildRequests.tryEmit(Unit) + } + override fun clear() { DebuggerUIUtil.invokeLater { tree.setRoot(object : XValueContainerNode(tree, null, true, object : XValueContainer() {}) {}, false) @@ -98,9 +134,7 @@ class XThreadsView(project: Project, session: XDebugSessionProxy) : XDebugView() cancelClear() clear() } - DebuggerUIUtil.invokeLater { - tree.setRoot(XThreadsRootNode(tree, session), false) - } + requestRebuild() } override fun dispose() {