fix: terminal exception caused by reconnection

This commit is contained in:
hstyi
2025-08-01 18:10:34 +08:00
committed by GitHub
parent 79ed6d3858
commit 8ba74f0846
12 changed files with 53 additions and 31 deletions

View File

@@ -4,7 +4,7 @@ plugins {
project.version = "0.0.4"
project.version = "0.0.5"
dependencies {

View File

@@ -1,9 +1,6 @@
package app.termora.plugins.serial
import app.termora.Host
import app.termora.Icons
import app.termora.PtyHostTerminalTab
import app.termora.WindowScope
import app.termora.*
import app.termora.terminal.PtyConnector
import org.apache.commons.io.Charsets
import java.nio.charset.StandardCharsets
@@ -11,6 +8,8 @@ import javax.swing.Icon
class SerialTerminalTab(windowScope: WindowScope, host: Host) :
PtyHostTerminalTab(windowScope, host) {
override suspend fun openPtyConnector(): PtyConnector {
val serialPort = Serials.openPort(host)
return SerialPortPtyConnector(
@@ -19,6 +18,10 @@ class SerialTerminalTab(windowScope: WindowScope, host: Host) :
)
}
override fun createReconnectTerminalTab(): TerminalTab {
return SerialTerminalTab(windowScope, host)
}
override fun getIcon(): Icon {
return Icons.plugin
}

View File

@@ -27,7 +27,7 @@ abstract class HostTerminalTab(
protected val terminalTabbedManager
get() = AnActionEvent(getJComponent(), StringUtils.EMPTY, EventObject(getJComponent()))
.getData(DataProviders.TerminalTabbedManager)
protected val coroutineScope by lazy { CoroutineScope(SupervisorJob() + Dispatchers.Swing) }
protected val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Swing)
protected val terminalModel get() = terminal.getTerminalModel()
protected var unread = false
set(value) {

View File

@@ -173,9 +173,20 @@ abstract class PtyHostTerminalTab(
}
override fun reconnect() {
stop()
start()
val manager = terminalTabbedManager ?: return
val index = manager.indexOfTerminalTab(this)
if (index < 0) return
val tab = createReconnectTerminalTab()
manager.addTerminalTab(index, tab, true)
manager.closeTerminalTab(this, true)
if (tab is HostTerminalTab) {
tab.start()
}
}
protected abstract fun createReconnectTerminalTab(): TerminalTab
override fun getJComponent(): JComponent {
return terminalPanel

View File

@@ -367,6 +367,10 @@ class TerminalTabbed(
}
}
override fun indexOfTerminalTab(tab: TerminalTab):Int {
return tabbedPane.indexOfComponent(tab.getJComponent())
}
private inner class SwitchFindEverywhereResult(
private val title: String,
private val icon: Icon?,

View File

@@ -8,4 +8,5 @@ interface TerminalTabbedManager {
fun setSelectedTerminalTab(tab: TerminalTab)
fun closeTerminalTab(tab: TerminalTab, disposable: Boolean = true)
fun refreshTerminalTabs()
fun indexOfTerminalTab(tab: TerminalTab): Int
}

View File

@@ -62,6 +62,9 @@ class LocalTerminalTab(windowScope: WindowScope, host: Host) :
) == JOptionPane.OK_OPTION
}
override fun createReconnectTerminalTab(): TerminalTab {
return LocalTerminalTab(windowScope, host)
}
private fun getPtyProcessConnector(): PtyProcessConnector? {
var p = getPtyConnector() as PtyConnector?

View File

@@ -185,6 +185,10 @@ class SFTPPtyTerminalTab(windowScope: WindowScope, host: Host) : PtyHostTerminal
return Icons.fileFormat
}
override fun createReconnectTerminalTab(): TerminalTab {
return SFTPPtyTerminalTab(windowScope, host)
}
override fun sendStartupCommand(ptyConnector: PtyConnector, bytes: ByteArray) {
// Nothing
}

View File

@@ -54,6 +54,10 @@ class SSHTerminalTab(
return mutex.isLocked.not()
}
override fun createReconnectTerminalTab(): TerminalTab {
return SSHTerminalTab(windowScope, host)
}
override suspend fun openPtyConnector(): PtyConnector {
if (mutex.tryLock()) {
try {
@@ -211,17 +215,6 @@ class SSHTerminalTab(
return super.getData(dataKey)
}
override fun reconnect() {
stop()
// 重新连接时就等于重新打开了一个标签handler 重置
handler.client = null
handler.session = null
handler.client = null
start()
}
override fun stop() {
if (mutex.tryLock()) {
try {

View File

@@ -1,9 +1,6 @@
package app.termora.plugin.internal.telnet
import app.termora.Host
import app.termora.ProxyType
import app.termora.PtyHostTerminalTab
import app.termora.WindowScope
import app.termora.*
import app.termora.terminal.ControlCharacters
import app.termora.terminal.KeyEncoderImpl
import app.termora.terminal.PtyConnector
@@ -71,5 +68,9 @@ class TelnetTerminalTab(
return ptyConnectorFactory.decorate(TelnetStreamPtyConnector(telnet, telnet.charset, characterMode))
}
override fun createReconnectTerminalTab(): TerminalTab {
return TelnetTerminalTab(windowScope, host)
}
}

View File

@@ -1,9 +1,6 @@
package app.termora.plugin.internal.wsl
import app.termora.Host
import app.termora.PtyConnectorFactory
import app.termora.PtyHostTerminalTab
import app.termora.WindowScope
import app.termora.*
import app.termora.terminal.PtyConnector
import org.apache.commons.io.Charsets
import org.apache.commons.io.FileUtils
@@ -51,6 +48,10 @@ class WSLHostTerminalTab(windowScope: WindowScope, host: Host) : PtyHostTerminal
return ptyConnector
}
override fun createReconnectTerminalTab(): TerminalTab {
return WSLHostTerminalTab(windowScope, host)
}
override fun sendStartupCommand(ptyConnector: PtyConnector, bytes: ByteArray) {
// Nothing

View File

@@ -1,9 +1,6 @@
package app.termora.tlog
import app.termora.Host
import app.termora.Icons
import app.termora.PtyHostTerminalTab
import app.termora.WindowScope
import app.termora.*
import app.termora.terminal.PtyConnector
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -71,6 +68,10 @@ class LogViewerTerminalTab(
return false
}
override fun createReconnectTerminalTab(): TerminalTab {
throw UnsupportedOperationException()
}
override fun canClone(): Boolean {
return false
}