mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-16 10:22:58 +08:00
feat: support auto close terminal tab when ssh disconnected normally (#169)
This commit is contained in:
@@ -468,6 +468,11 @@ class Database private constructor(private val env: Environment) : Disposable {
|
|||||||
* 光标样式
|
* 光标样式
|
||||||
*/
|
*/
|
||||||
var cursor by CursorStylePropertyDelegate(CursorStyle.Block)
|
var cursor by CursorStylePropertyDelegate(CursorStyle.Block)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 终端断开连接时自动关闭Tab
|
||||||
|
*/
|
||||||
|
var autoCloseTabWhenDisconnected by BooleanPropertyDelegate(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import app.termora.terminal.PtyConnector
|
|||||||
import org.apache.commons.io.Charsets
|
import org.apache.commons.io.Charsets
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
class LocalTerminalTab(windowScope: WindowScope, host: Host) : PtyHostTerminalTab(windowScope, host) {
|
class LocalTerminalTab(windowScope: WindowScope, host: Host) :
|
||||||
|
PtyHostTerminalTab(windowScope, host) {
|
||||||
|
|
||||||
override suspend fun openPtyConnector(): PtyConnector {
|
override suspend fun openPtyConnector(): PtyConnector {
|
||||||
val winSize = terminalPanel.winSize()
|
val winSize = terminalPanel.winSize()
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package app.termora
|
package app.termora
|
||||||
|
|
||||||
|
import app.termora.actions.AnActionEvent
|
||||||
|
import app.termora.actions.DataProviders
|
||||||
import app.termora.actions.TabReconnectAction
|
import app.termora.actions.TabReconnectAction
|
||||||
import app.termora.addons.zmodem.ZModemPtyConnectorAdaptor
|
import app.termora.addons.zmodem.ZModemPtyConnectorAdaptor
|
||||||
import app.termora.keyboardinteractive.TerminalUserInteraction
|
import app.termora.keyboardinteractive.TerminalUserInteraction
|
||||||
@@ -27,11 +29,13 @@ import org.apache.sshd.common.session.SessionListener.Event
|
|||||||
import org.apache.sshd.common.util.net.SshdSocketAddress
|
import org.apache.sshd.common.util.net.SshdSocketAddress
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.util.EventObject
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
import javax.swing.SwingUtilities
|
import javax.swing.SwingUtilities
|
||||||
|
|
||||||
|
|
||||||
class SSHTerminalTab(windowScope: WindowScope, host: Host) : PtyHostTerminalTab(windowScope, host) {
|
class SSHTerminalTab(windowScope: WindowScope, host: Host) :
|
||||||
|
PtyHostTerminalTab(windowScope, host) {
|
||||||
companion object {
|
companion object {
|
||||||
private val log = LoggerFactory.getLogger(PtyHostTerminalTab::class.java)
|
private val log = LoggerFactory.getLogger(PtyHostTerminalTab::class.java)
|
||||||
}
|
}
|
||||||
@@ -41,6 +45,9 @@ class SSHTerminalTab(windowScope: WindowScope, host: Host) : PtyHostTerminalTab(
|
|||||||
private var sshClient: SshClient? = null
|
private var sshClient: SshClient? = null
|
||||||
private var sshSession: ClientSession? = null
|
private var sshSession: ClientSession? = null
|
||||||
private var sshChannelShell: ChannelShell? = null
|
private var sshChannelShell: ChannelShell? = null
|
||||||
|
private val terminalTabbedManager
|
||||||
|
get() = AnActionEvent(getJComponent(), StringUtils.EMPTY, EventObject(getJComponent()))
|
||||||
|
.getData(DataProviders.TerminalTabbedManager)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
terminalPanel.dropFiles = false
|
terminalPanel.dropFiles = false
|
||||||
@@ -126,6 +133,13 @@ class SSHTerminalTab(windowScope: WindowScope, host: Host) : PtyHostTerminalTab(
|
|||||||
terminal.write("\r\n")
|
terminal.write("\r\n")
|
||||||
terminal.write("${ControlCharacters.ESC}[0m")
|
terminal.write("${ControlCharacters.ESC}[0m")
|
||||||
terminalModel.setData(DataKey.ShowCursor, false)
|
terminalModel.setData(DataKey.ShowCursor, false)
|
||||||
|
if (Database.getDatabase().terminal.autoCloseTabWhenDisconnected) {
|
||||||
|
terminalTabbedManager?.let { manager ->
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
manager.closeTerminalTab(this@SSHTerminalTab, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import org.apache.commons.io.Charsets
|
|||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import javax.swing.Icon
|
import javax.swing.Icon
|
||||||
|
|
||||||
class SerialTerminalTab(windowScope: WindowScope, host: Host) : PtyHostTerminalTab(windowScope, host) {
|
class SerialTerminalTab(windowScope: WindowScope, host: Host) :
|
||||||
|
PtyHostTerminalTab(windowScope, host) {
|
||||||
override suspend fun openPtyConnector(): PtyConnector {
|
override suspend fun openPtyConnector(): PtyConnector {
|
||||||
val serialPort = Serials.openPort(host)
|
val serialPort = Serials.openPort(host)
|
||||||
return SerialPortPtyConnector(
|
return SerialPortPtyConnector(
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import java.awt.BorderLayout
|
|||||||
import java.awt.Component
|
import java.awt.Component
|
||||||
import java.awt.Toolkit
|
import java.awt.Toolkit
|
||||||
import java.awt.datatransfer.StringSelection
|
import java.awt.datatransfer.StringSelection
|
||||||
|
import java.awt.event.ActionEvent
|
||||||
import java.awt.event.ItemEvent
|
import java.awt.event.ItemEvent
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
@@ -307,6 +308,7 @@ class SettingsOptionsPane : OptionsPane() {
|
|||||||
private val fontSizeTextField = IntSpinner(0, 9, 99)
|
private val fontSizeTextField = IntSpinner(0, 9, 99)
|
||||||
private val terminalSetting get() = Database.getDatabase().terminal
|
private val terminalSetting get() = Database.getDatabase().terminal
|
||||||
private val selectCopyComboBox = YesOrNoComboBox()
|
private val selectCopyComboBox = YesOrNoComboBox()
|
||||||
|
private val autoCloseTabComboBox = YesOrNoComboBox()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
initView()
|
initView()
|
||||||
@@ -322,6 +324,13 @@ class SettingsOptionsPane : OptionsPane() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
autoCloseTabComboBox.addItemListener { e ->
|
||||||
|
if (e.stateChange == ItemEvent.SELECTED) {
|
||||||
|
terminalSetting.autoCloseTabWhenDisconnected = autoCloseTabComboBox.selectedItem as Boolean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
autoCloseTabComboBox.toolTipText = I18n.getString("termora.settings.terminal.auto-close-tab-description")
|
||||||
|
|
||||||
selectCopyComboBox.addItemListener { e ->
|
selectCopyComboBox.addItemListener { e ->
|
||||||
if (e.stateChange == ItemEvent.SELECTED) {
|
if (e.stateChange == ItemEvent.SELECTED) {
|
||||||
terminalSetting.selectCopy = selectCopyComboBox.selectedItem as Boolean
|
terminalSetting.selectCopy = selectCopyComboBox.selectedItem as Boolean
|
||||||
@@ -466,6 +475,7 @@ class SettingsOptionsPane : OptionsPane() {
|
|||||||
beepComboBox.selectedItem = terminalSetting.beep
|
beepComboBox.selectedItem = terminalSetting.beep
|
||||||
cursorStyleComboBox.selectedItem = terminalSetting.cursor
|
cursorStyleComboBox.selectedItem = terminalSetting.cursor
|
||||||
selectCopyComboBox.selectedItem = terminalSetting.selectCopy
|
selectCopyComboBox.selectedItem = terminalSetting.selectCopy
|
||||||
|
autoCloseTabComboBox.selectedItem = terminalSetting.autoCloseTabWhenDisconnected
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIcon(isSelected: Boolean): Icon {
|
override fun getIcon(isSelected: Boolean): Icon {
|
||||||
@@ -483,7 +493,7 @@ class SettingsOptionsPane : OptionsPane() {
|
|||||||
private fun getCenterComponent(): JComponent {
|
private fun getCenterComponent(): JComponent {
|
||||||
val layout = FormLayout(
|
val layout = FormLayout(
|
||||||
"left:pref, $formMargin, default:grow, $formMargin, left:pref, $formMargin, pref, default:grow",
|
"left:pref, $formMargin, default:grow, $formMargin, left:pref, $formMargin, pref, default:grow",
|
||||||
"pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref"
|
"pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref, $formMargin, pref"
|
||||||
)
|
)
|
||||||
|
|
||||||
val beepBtn = JButton(Icons.run)
|
val beepBtn = JButton(Icons.run)
|
||||||
@@ -511,7 +521,9 @@ class SettingsOptionsPane : OptionsPane() {
|
|||||||
.add("${I18n.getString("termora.settings.terminal.cursor-style")}:").xy(1, rows)
|
.add("${I18n.getString("termora.settings.terminal.cursor-style")}:").xy(1, rows)
|
||||||
.add(cursorStyleComboBox).xy(3, rows).apply { rows += step }
|
.add(cursorStyleComboBox).xy(3, rows).apply { rows += step }
|
||||||
.add("${I18n.getString("termora.settings.terminal.local-shell")}:").xy(1, rows)
|
.add("${I18n.getString("termora.settings.terminal.local-shell")}:").xy(1, rows)
|
||||||
.add(shellComboBox).xyw(3, rows, 5)
|
.add(shellComboBox).xyw(3, rows, 5).apply { rows += step }
|
||||||
|
.add("${I18n.getString("termora.settings.terminal.auto-close-tab")}:").xy(1, rows)
|
||||||
|
.add(autoCloseTabComboBox).xy(3, rows)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ import java.io.FileNotFoundException
|
|||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import javax.swing.Icon
|
import javax.swing.Icon
|
||||||
|
|
||||||
class LogViewerTerminalTab(windowScope: WindowScope, private val file: File) : PtyHostTerminalTab(
|
class LogViewerTerminalTab(
|
||||||
|
windowScope: WindowScope,
|
||||||
|
private val file: File,
|
||||||
|
) : PtyHostTerminalTab(
|
||||||
windowScope,
|
windowScope,
|
||||||
Host(
|
Host(
|
||||||
name = file.name,
|
name = file.name,
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ termora.settings.terminal.beep=Beep
|
|||||||
termora.settings.terminal.select-copy=Select copy
|
termora.settings.terminal.select-copy=Select copy
|
||||||
termora.settings.terminal.cursor-style=Cursor type
|
termora.settings.terminal.cursor-style=Cursor type
|
||||||
termora.settings.terminal.local-shell=Local shell
|
termora.settings.terminal.local-shell=Local shell
|
||||||
|
termora.settings.terminal.auto-close-tab=Auto Close Tab
|
||||||
|
termora.settings.terminal.auto-close-tab-description=Automatically close the tab when the terminal is disconnected normally.
|
||||||
|
|
||||||
termora.settings.sync=Sync
|
termora.settings.sync=Sync
|
||||||
termora.settings.sync.push=Push
|
termora.settings.sync.push=Push
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ termora.settings.terminal.beep=蜂鸣声
|
|||||||
termora.settings.terminal.select-copy=选中复制
|
termora.settings.terminal.select-copy=选中复制
|
||||||
termora.settings.terminal.cursor-style=光标样式
|
termora.settings.terminal.cursor-style=光标样式
|
||||||
termora.settings.terminal.local-shell=本地终端
|
termora.settings.terminal.local-shell=本地终端
|
||||||
|
termora.settings.terminal.auto-close-tab=自动关闭标签
|
||||||
|
termora.settings.terminal.auto-close-tab-description=当终端正常断开连接时自动关闭标签页。
|
||||||
|
|
||||||
|
|
||||||
termora.settings.sync=同步
|
termora.settings.sync=同步
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ termora.settings.terminal.beep=蜂鳴聲
|
|||||||
termora.settings.terminal.select-copy=選取複製
|
termora.settings.terminal.select-copy=選取複製
|
||||||
termora.settings.terminal.cursor-style=遊標風格
|
termora.settings.terminal.cursor-style=遊標風格
|
||||||
termora.settings.terminal.local-shell=本地端
|
termora.settings.terminal.local-shell=本地端
|
||||||
|
termora.settings.terminal.auto-close-tab=自動關閉標籤
|
||||||
|
termora.settings.terminal.auto-close-tab-description=當終端正常斷開連線時自動關閉標籤頁。。
|
||||||
|
|
||||||
termora.settings.sync=同步
|
termora.settings.sync=同步
|
||||||
termora.settings.sync.push=推送
|
termora.settings.sync.push=推送
|
||||||
|
|||||||
Reference in New Issue
Block a user