mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[terminal] IJPL-215159 Try to fix race of terminal editors disposing on project closing
Editors can be disposed before the terminal tool window tab is hidden. Because terminal coroutine scope is bound to the project and is canceled concurrently with other things, like tool window tabs disposing. Let's try to hide the tool window tab right when terminal coroutine scope is canceled. GitOrigin-RevId: 47123bb56714c0717e4e528a8e227bbb76ebbff9
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c50cb61de5
commit
30fcd456ee
+17
@@ -46,6 +46,7 @@ import org.jetbrains.plugins.terminal.fus.ReworkedTerminalUsageCollector
|
||||
import org.jetbrains.plugins.terminal.fus.TerminalOpeningWay
|
||||
import org.jetbrains.plugins.terminal.fus.TerminalStartupFusInfo
|
||||
import org.jetbrains.plugins.terminal.util.fireListenersAndLogAllExceptions
|
||||
import java.lang.ref.WeakReference
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
internal class TerminalToolWindowTabsManagerImpl(
|
||||
@@ -129,6 +130,7 @@ internal class TerminalToolWindowTabsManagerImpl(
|
||||
return tab
|
||||
}
|
||||
|
||||
@OptIn(AwaitCancellationAndInvoke::class)
|
||||
private fun doCreateTab(terminal: TerminalView): TerminalToolWindowTab {
|
||||
val panel = TerminalToolWindowPanel()
|
||||
panel.setContent(terminal.component)
|
||||
@@ -163,6 +165,21 @@ internal class TerminalToolWindowTabsManagerImpl(
|
||||
}
|
||||
}
|
||||
|
||||
// In case of project closing there can be a race between terminal coroutine scope cancellation
|
||||
// and removing the content from the tool window.
|
||||
// If the terminal coroutine scope is canceled before the content is removed, the editor may be shown green for a moment.
|
||||
// The ideal solution is to cancel the terminal scope only after the content is removed.
|
||||
// However, the terminal component has a broader lifecycle than the tool window tab (to be able to detach it),
|
||||
// so it can't be tied to the content removal directly.
|
||||
// Let's try to hide the tool window tab right on terminal scope cancellation,
|
||||
// but do not store strong reference to the content to avoid leaks.
|
||||
val tabReference = WeakReference(content)
|
||||
terminal.coroutineScope.awaitCancellationAndInvoke(Dispatchers.EDT) {
|
||||
val content = tabReference.get() ?: return@awaitCancellationAndInvoke
|
||||
val manager = content.manager ?: return@awaitCancellationAndInvoke
|
||||
manager.removeContent(content, true)
|
||||
}
|
||||
|
||||
return TerminalToolWindowTabImpl(terminal, content)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user