mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-16 02:12:58 +08:00
Compare commits
11 Commits
2.0.0-beta
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a56774454d | ||
|
|
2928b35585 | ||
|
|
04bece21ff | ||
|
|
9e2e104baa | ||
|
|
0615378a17 | ||
|
|
013b03f9ef | ||
|
|
026b13ba05 | ||
|
|
6ec526eeeb | ||
|
|
e064bb9bb5 | ||
|
|
1f3fb5e2c0 | ||
|
|
5984f3e856 |
2
.github/workflows/linux.yml
vendored
2
.github/workflows/linux.yml
vendored
@@ -4,7 +4,7 @@ on: [ push, pull_request ]
|
||||
|
||||
env:
|
||||
JBR_MAJOR: 21.0.8
|
||||
JBR_PATCH: b1138.52
|
||||
JBR_PATCH: b1163.69
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
4
.github/workflows/osx.yml
vendored
4
.github/workflows/osx.yml
vendored
@@ -9,14 +9,14 @@ env:
|
||||
TERMORA_MAC_NOTARY: "${{ startsWith(github.event.head_commit.message, 'release: ') && github.repository == 'TermoraDev/termora' }}"
|
||||
TERMORA_MAC_NOTARY_KEYCHAIN_PROFILE: ${{ secrets.TERMORA_MAC_NOTARY_KEYCHAIN_PROFILE }}
|
||||
JBR_MAJOR: 21.0.8
|
||||
JBR_PATCH: b1138.52
|
||||
JBR_PATCH: b1163.69
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ macos-15, macos-13 ]
|
||||
os: [ macos-15-intel, macos-latest ]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
|
||||
2
.github/workflows/windows.yml
vendored
2
.github/workflows/windows.yml
vendored
@@ -4,7 +4,7 @@ on: [ push, pull_request ]
|
||||
|
||||
env:
|
||||
JBR_MAJOR: 21.0.8
|
||||
JBR_PATCH: b1138.52
|
||||
JBR_PATCH: b1163.69
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -6,8 +6,8 @@ tinylog = "2.7.0"
|
||||
kotlinx-coroutines = "1.10.2"
|
||||
flatlaf = "3.6.2"
|
||||
kotlinx-serialization-json = "1.9.0"
|
||||
commons-codec = "1.19.0"
|
||||
commons-lang3 = "3.19.0"
|
||||
commons-codec = "1.20.0"
|
||||
commons-lang3 = "3.20.0"
|
||||
commons-csv = "1.14.1"
|
||||
commons-net = "3.12.0"
|
||||
commons-text = "1.14.0"
|
||||
@@ -24,7 +24,7 @@ commons-io = "2.20.0"
|
||||
jbr-api = "17.1.10.1"
|
||||
hutool = "5.8.40"
|
||||
jsch = "2.27.3"
|
||||
okhttp = "5.2.1"
|
||||
okhttp = "5.3.2"
|
||||
sshj = "0.39.0"
|
||||
sshd-core = "2.15.0"
|
||||
jgit = "7.4.0.202509020913-r"
|
||||
@@ -37,7 +37,7 @@ rhino = "1.8.0"
|
||||
delight-rhino-sandbox = "0.2.1"
|
||||
testcontainers = "2.0.1"
|
||||
mixpanel = "1.5.4"
|
||||
jSerialComm = "2.11.2"
|
||||
jSerialComm = "2.11.4"
|
||||
ini4j = "0.5.5-2"
|
||||
restart4j = "0.0.1"
|
||||
eddsa = "0.3.0"
|
||||
|
||||
@@ -9,7 +9,7 @@ dependencies {
|
||||
compileOnly(project(":"))
|
||||
implementation("com.maxmind.geoip2:geoip2:4.4.0")
|
||||
// https://github.com/hstyi/geolite2
|
||||
implementation("com.github.hstyi:geolite2:v1.0-202510200054")
|
||||
implementation("com.github.hstyi:geolite2:v1.0-202510270056")
|
||||
}
|
||||
|
||||
apply(from = "$rootDir/plugins/common.gradle.kts")
|
||||
|
||||
@@ -10,7 +10,7 @@ project.version = "0.0.5"
|
||||
dependencies {
|
||||
testImplementation(kotlin("test"))
|
||||
compileOnly(project(":"))
|
||||
implementation("com.fazecast:jSerialComm:2.11.2")
|
||||
implementation("com.fazecast:jSerialComm:2.11.4")
|
||||
}
|
||||
|
||||
apply(from = "$rootDir/plugins/common.gradle.kts")
|
||||
|
||||
@@ -50,6 +50,17 @@ class ApplicationInitializr {
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/TermoraDev/termora/issues/1254
|
||||
if (System.getProperty(FlatSystemProperties.UI_SCALE).isNullOrBlank()) {
|
||||
val scale = System.getenv("TERMORA_SCALE")
|
||||
if (scale.isNullOrBlank().not()) {
|
||||
if (NumberUtils.toDouble(scale, -1.0) > 0) {
|
||||
System.setProperty(FlatSystemProperties.UI_SCALE_ENABLED, "true")
|
||||
System.setProperty(FlatSystemProperties.UI_SCALE, scale)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 启动
|
||||
val runtime = measureTimeMillis { ApplicationRunner().run() }
|
||||
val log = LoggerFactory.getLogger(javaClass)
|
||||
|
||||
@@ -3,5 +3,5 @@ package app.termora
|
||||
import app.termora.actions.AnActionEvent
|
||||
import java.util.*
|
||||
|
||||
class OpenHostActionEvent(source: Any, val host: Host, event: EventObject) :
|
||||
class OpenHostActionEvent(source: Any, val host: Host, event: EventObject, val tabIndex: Int = -1) :
|
||||
AnActionEvent(source, String(), event)
|
||||
@@ -179,7 +179,7 @@ abstract class PtyHostTerminalTab(
|
||||
|
||||
val tab = createReconnectTerminalTab()
|
||||
manager.addTerminalTab(index, tab, true)
|
||||
manager.closeTerminalTab(this, true)
|
||||
manager.closeTerminalTab(this, disposable = true, reconnect = true)
|
||||
|
||||
if (tab is HostTerminalTab) {
|
||||
tab.start()
|
||||
|
||||
@@ -141,25 +141,28 @@ class TerminalTabbed(
|
||||
|
||||
}
|
||||
|
||||
private fun removeTabAt(index: Int, disposable: Boolean = true) {
|
||||
private fun removeTabAt(index: Int, disposable: Boolean = true, reconnect: Boolean = false) {
|
||||
if (tabbedPane.isTabClosable(index)) {
|
||||
val tab = tabs[index]
|
||||
|
||||
// 询问是否可以关闭
|
||||
if (disposable) {
|
||||
// 如果开启了关闭确认,那么直接询问用户
|
||||
if (appearance.confirmTabClose) {
|
||||
if (OptionPane.showConfirmDialog(
|
||||
windowScope.window,
|
||||
I18n.getString("termora.tabbed.tab.close-prompt"),
|
||||
messageType = JOptionPane.QUESTION_MESSAGE,
|
||||
optionType = JOptionPane.OK_CANCEL_OPTION
|
||||
) != JOptionPane.OK_OPTION
|
||||
) {
|
||||
// 如果是重连接,那么直接关闭不进行任何形式的询问
|
||||
if (reconnect.not()) {
|
||||
// 如果开启了关闭确认,那么直接询问用户
|
||||
if (appearance.confirmTabClose) {
|
||||
if (OptionPane.showConfirmDialog(
|
||||
windowScope.window,
|
||||
I18n.getString("termora.tabbed.tab.close-prompt"),
|
||||
messageType = JOptionPane.QUESTION_MESSAGE,
|
||||
optionType = JOptionPane.OK_CANCEL_OPTION
|
||||
) != JOptionPane.OK_OPTION
|
||||
) {
|
||||
return
|
||||
}
|
||||
} else if (!tab.willBeClose()) { // 如果没有开启则询问用户
|
||||
return
|
||||
}
|
||||
} else if (!tab.willBeClose()) { // 如果没有开启则询问用户
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +236,7 @@ class TerminalTabbed(
|
||||
if (tab is HostTerminalTab) {
|
||||
actionManager
|
||||
.getAction(OpenHostAction.OPEN_HOST)
|
||||
.actionPerformed(OpenHostActionEvent(this, tab.host, evt))
|
||||
.actionPerformed(OpenHostActionEvent(this, tab.host, evt, tabIndex + 1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,7 +364,7 @@ class TerminalTabbed(
|
||||
}
|
||||
}
|
||||
|
||||
override fun indexOfTerminalTab(tab: TerminalTab):Int {
|
||||
override fun indexOfTerminalTab(tab: TerminalTab): Int {
|
||||
return tabbedPane.indexOfComponent(tab.getJComponent())
|
||||
}
|
||||
|
||||
@@ -451,10 +454,10 @@ class TerminalTabbed(
|
||||
}
|
||||
}
|
||||
|
||||
override fun closeTerminalTab(tab: TerminalTab, disposable: Boolean) {
|
||||
override fun closeTerminalTab(tab: TerminalTab, disposable: Boolean, reconnect: Boolean) {
|
||||
for (i in 0 until tabs.size) {
|
||||
if (tabs[i] == tab) {
|
||||
removeTabAt(i, disposable)
|
||||
removeTabAt(i, disposable, reconnect)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ interface TerminalTabbedManager {
|
||||
fun getSelectedTerminalTab(): TerminalTab?
|
||||
fun getTerminalTabs(): List<TerminalTab>
|
||||
fun setSelectedTerminalTab(tab: TerminalTab)
|
||||
fun closeTerminalTab(tab: TerminalTab, disposable: Boolean = true)
|
||||
fun closeTerminalTab(tab: TerminalTab, disposable: Boolean = true, reconnect: Boolean = false)
|
||||
fun refreshTerminalTabs()
|
||||
fun indexOfTerminalTab(tab: TerminalTab): Int
|
||||
}
|
||||
@@ -56,7 +56,12 @@ class OpenHostAction : AnAction() {
|
||||
|
||||
if (tab == null) return
|
||||
|
||||
terminalTabbedManager.addTerminalTab(tab)
|
||||
if (evt.tabIndex >= 0) {
|
||||
terminalTabbedManager.addTerminalTab(evt.tabIndex, tab)
|
||||
} else {
|
||||
terminalTabbedManager.addTerminalTab(tab)
|
||||
}
|
||||
|
||||
if (tab is PtyHostTerminalTab) {
|
||||
tab.start()
|
||||
}
|
||||
|
||||
@@ -27,9 +27,14 @@ class CloneSessionTerminalTabbedContextMenuExtension private constructor() : Ter
|
||||
cloneSession.addActionListener(object : AnAction() {
|
||||
override fun actionPerformed(evt: AnActionEvent) {
|
||||
val terminalTabbedManager = evt.getData(DataProviders.TerminalTabbedManager) ?: return
|
||||
val index = terminalTabbedManager.indexOfTerminalTab(tab)
|
||||
val handler = c.copy(channel = null)
|
||||
val newTab = SSHTerminalTab(windowScope, tab.host, handler)
|
||||
terminalTabbedManager.addTerminalTab(newTab)
|
||||
if (index >= 0) {
|
||||
terminalTabbedManager.addTerminalTab(index + 1, newTab)
|
||||
} else {
|
||||
terminalTabbedManager.addTerminalTab(newTab)
|
||||
}
|
||||
newTab.start()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -46,6 +46,7 @@ class TransferAnAction : AnAction(I18n.getString("termora.transport.sftp"), Icon
|
||||
val panel = tabbed.getTransportPanel(i) ?: continue
|
||||
if (panel.host.id == host.id) {
|
||||
tabbed.selectedIndex = i
|
||||
terminalTabbedManager.setSelectedTerminalTab(sftpTab)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user