Compare commits

..

11 Commits

Author SHA1 Message Date
dependabot[bot]
a56774454d chore(deps): bump okhttp from 5.3.0 to 5.3.2
Bumps `okhttp` from 5.3.0 to 5.3.2.

Updates `com.squareup.okhttp3:okhttp` from 5.3.0 to 5.3.2
- [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okhttp/compare/parent-5.3.0...parent-5.3.2)

Updates `com.squareup.okhttp3:logging-interceptor` from 5.3.0 to 5.3.2
- [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okhttp/compare/parent-5.3.0...parent-5.3.2)

---
updated-dependencies:
- dependency-name: com.squareup.okhttp3:okhttp
  dependency-version: 5.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.squareup.okhttp3:logging-interceptor
  dependency-version: 5.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-19 02:14:04 +00:00
dependabot[bot]
2928b35585 chore(deps): bump org.apache.commons:commons-lang3 from 3.19.0 to 3.20.0
Bumps org.apache.commons:commons-lang3 from 3.19.0 to 3.20.0.

---
updated-dependencies:
- dependency-name: org.apache.commons:commons-lang3
  dependency-version: 3.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-19 09:04:14 +08:00
hstyi
04bece21ff feat: insert new terminal tab at the correct index in terminal tab manager 2025-11-17 08:12:55 +08:00
hstyi
9e2e104baa chore: enhance terminal tab closing behavior to support reconnect option 2025-11-13 09:32:36 +08:00
hstyi
0615378a17 fix: selected terminal tab when transferring to a host 2025-11-11 10:52:28 +08:00
dependabot[bot]
013b03f9ef chore(deps): bump commons-codec:commons-codec from 1.19.0 to 1.20.0
Bumps [commons-codec:commons-codec](https://github.com/apache/commons-codec) from 1.19.0 to 1.20.0.
- [Changelog](https://github.com/apache/commons-codec/blob/master/RELEASE-NOTES.txt)
- [Commits](https://github.com/apache/commons-codec/compare/rel/commons-codec-1.19.0...rel/commons-codec-1.20.0)

---
updated-dependencies:
- dependency-name: commons-codec:commons-codec
  dependency-version: 1.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 10:17:06 +08:00
hstyi
026b13ba05 feat: add support for UI scaling via TERMORA_SCALE environment variable 2025-11-07 09:59:37 +08:00
dependabot[bot]
6ec526eeeb chore(deps): bump com.fazecast:jSerialComm from 2.11.2 to 2.11.4
Bumps [com.fazecast:jSerialComm](https://github.com/Fazecast/jSerialComm) from 2.11.2 to 2.11.4.
- [Release notes](https://github.com/Fazecast/jSerialComm/releases)
- [Commits](https://github.com/Fazecast/jSerialComm/commits)

---
updated-dependencies:
- dependency-name: com.fazecast:jSerialComm
  dependency-version: 2.11.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-04 11:00:57 +08:00
dependabot[bot]
e064bb9bb5 chore(deps): bump com.github.hstyi:geolite2
Bumps [com.github.hstyi:geolite2](https://github.com/hstyi/GeoLite2) from v1.0-202510200054 to v1.0-202510270056.
- [Release notes](https://github.com/hstyi/GeoLite2/releases)
- [Commits](https://github.com/hstyi/GeoLite2/commits)

---
updated-dependencies:
- dependency-name: com.github.hstyi:geolite2
  dependency-version: v1.0-202510270056
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 15:58:19 +08:00
dependabot[bot]
1f3fb5e2c0 chore(deps): bump okhttp from 5.2.1 to 5.3.0
Bumps `okhttp` from 5.2.1 to 5.3.0.

Updates `com.squareup.okhttp3:okhttp` from 5.2.1 to 5.3.0
- [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okhttp/compare/parent-5.2.1...parent-5.3.0)

Updates `com.squareup.okhttp3:logging-interceptor` from 5.2.1 to 5.3.0
- [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okhttp/compare/parent-5.2.1...parent-5.3.0)

---
updated-dependencies:
- dependency-name: com.squareup.okhttp3:okhttp
  dependency-version: 5.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.squareup.okhttp3:logging-interceptor
  dependency-version: 5.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 10:37:23 +08:00
hstyi
5984f3e856 chore: update JBR version to 21.0.8-b1163.69 2025-11-03 10:24:58 +08:00
14 changed files with 56 additions and 31 deletions

View File

@@ -4,7 +4,7 @@ on: [ push, pull_request ]
env: env:
JBR_MAJOR: 21.0.8 JBR_MAJOR: 21.0.8
JBR_PATCH: b1138.52 JBR_PATCH: b1163.69
jobs: jobs:
build: build:

View File

@@ -9,14 +9,14 @@ env:
TERMORA_MAC_NOTARY: "${{ startsWith(github.event.head_commit.message, 'release: ') && github.repository == 'TermoraDev/termora' }}" 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 }} TERMORA_MAC_NOTARY_KEYCHAIN_PROFILE: ${{ secrets.TERMORA_MAC_NOTARY_KEYCHAIN_PROFILE }}
JBR_MAJOR: 21.0.8 JBR_MAJOR: 21.0.8
JBR_PATCH: b1138.52 JBR_PATCH: b1163.69
jobs: jobs:
build: build:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
os: [ macos-15, macos-13 ] os: [ macos-15-intel, macos-latest ]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:

View File

@@ -4,7 +4,7 @@ on: [ push, pull_request ]
env: env:
JBR_MAJOR: 21.0.8 JBR_MAJOR: 21.0.8
JBR_PATCH: b1138.52 JBR_PATCH: b1163.69
jobs: jobs:
build: build:

View File

@@ -6,8 +6,8 @@ tinylog = "2.7.0"
kotlinx-coroutines = "1.10.2" kotlinx-coroutines = "1.10.2"
flatlaf = "3.6.2" flatlaf = "3.6.2"
kotlinx-serialization-json = "1.9.0" kotlinx-serialization-json = "1.9.0"
commons-codec = "1.19.0" commons-codec = "1.20.0"
commons-lang3 = "3.19.0" commons-lang3 = "3.20.0"
commons-csv = "1.14.1" commons-csv = "1.14.1"
commons-net = "3.12.0" commons-net = "3.12.0"
commons-text = "1.14.0" commons-text = "1.14.0"
@@ -24,7 +24,7 @@ commons-io = "2.20.0"
jbr-api = "17.1.10.1" jbr-api = "17.1.10.1"
hutool = "5.8.40" hutool = "5.8.40"
jsch = "2.27.3" jsch = "2.27.3"
okhttp = "5.2.1" okhttp = "5.3.2"
sshj = "0.39.0" sshj = "0.39.0"
sshd-core = "2.15.0" sshd-core = "2.15.0"
jgit = "7.4.0.202509020913-r" jgit = "7.4.0.202509020913-r"
@@ -37,7 +37,7 @@ rhino = "1.8.0"
delight-rhino-sandbox = "0.2.1" delight-rhino-sandbox = "0.2.1"
testcontainers = "2.0.1" testcontainers = "2.0.1"
mixpanel = "1.5.4" mixpanel = "1.5.4"
jSerialComm = "2.11.2" jSerialComm = "2.11.4"
ini4j = "0.5.5-2" ini4j = "0.5.5-2"
restart4j = "0.0.1" restart4j = "0.0.1"
eddsa = "0.3.0" eddsa = "0.3.0"

View File

@@ -9,7 +9,7 @@ dependencies {
compileOnly(project(":")) compileOnly(project(":"))
implementation("com.maxmind.geoip2:geoip2:4.4.0") implementation("com.maxmind.geoip2:geoip2:4.4.0")
// https://github.com/hstyi/geolite2 // 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") apply(from = "$rootDir/plugins/common.gradle.kts")

View File

@@ -10,7 +10,7 @@ project.version = "0.0.5"
dependencies { dependencies {
testImplementation(kotlin("test")) testImplementation(kotlin("test"))
compileOnly(project(":")) compileOnly(project(":"))
implementation("com.fazecast:jSerialComm:2.11.2") implementation("com.fazecast:jSerialComm:2.11.4")
} }
apply(from = "$rootDir/plugins/common.gradle.kts") apply(from = "$rootDir/plugins/common.gradle.kts")

View File

@@ -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 runtime = measureTimeMillis { ApplicationRunner().run() }
val log = LoggerFactory.getLogger(javaClass) val log = LoggerFactory.getLogger(javaClass)

View File

@@ -3,5 +3,5 @@ package app.termora
import app.termora.actions.AnActionEvent import app.termora.actions.AnActionEvent
import java.util.* 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) AnActionEvent(source, String(), event)

View File

@@ -179,7 +179,7 @@ abstract class PtyHostTerminalTab(
val tab = createReconnectTerminalTab() val tab = createReconnectTerminalTab()
manager.addTerminalTab(index, tab, true) manager.addTerminalTab(index, tab, true)
manager.closeTerminalTab(this, true) manager.closeTerminalTab(this, disposable = true, reconnect = true)
if (tab is HostTerminalTab) { if (tab is HostTerminalTab) {
tab.start() tab.start()

View File

@@ -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)) { if (tabbedPane.isTabClosable(index)) {
val tab = tabs[index] val tab = tabs[index]
// 询问是否可以关闭 // 询问是否可以关闭
if (disposable) { if (disposable) {
// 如果开启了关闭确认,那么直接询问用户 // 如果是重连接,那么直接关闭不进行任何形式的询问
if (appearance.confirmTabClose) { if (reconnect.not()) {
if (OptionPane.showConfirmDialog( // 如果开启了关闭确认,那么直接询问用户
windowScope.window, if (appearance.confirmTabClose) {
I18n.getString("termora.tabbed.tab.close-prompt"), if (OptionPane.showConfirmDialog(
messageType = JOptionPane.QUESTION_MESSAGE, windowScope.window,
optionType = JOptionPane.OK_CANCEL_OPTION I18n.getString("termora.tabbed.tab.close-prompt"),
) != JOptionPane.OK_OPTION messageType = JOptionPane.QUESTION_MESSAGE,
) { optionType = JOptionPane.OK_CANCEL_OPTION
) != JOptionPane.OK_OPTION
) {
return
}
} else if (!tab.willBeClose()) { // 如果没有开启则询问用户
return return
} }
} else if (!tab.willBeClose()) { // 如果没有开启则询问用户
return
} }
} }
@@ -233,7 +236,7 @@ class TerminalTabbed(
if (tab is HostTerminalTab) { if (tab is HostTerminalTab) {
actionManager actionManager
.getAction(OpenHostAction.OPEN_HOST) .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()) 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) { for (i in 0 until tabs.size) {
if (tabs[i] == tab) { if (tabs[i] == tab) {
removeTabAt(i, disposable) removeTabAt(i, disposable, reconnect)
break break
} }
} }

View File

@@ -6,7 +6,7 @@ interface TerminalTabbedManager {
fun getSelectedTerminalTab(): TerminalTab? fun getSelectedTerminalTab(): TerminalTab?
fun getTerminalTabs(): List<TerminalTab> fun getTerminalTabs(): List<TerminalTab>
fun setSelectedTerminalTab(tab: 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 refreshTerminalTabs()
fun indexOfTerminalTab(tab: TerminalTab): Int fun indexOfTerminalTab(tab: TerminalTab): Int
} }

View File

@@ -56,7 +56,12 @@ class OpenHostAction : AnAction() {
if (tab == null) return if (tab == null) return
terminalTabbedManager.addTerminalTab(tab) if (evt.tabIndex >= 0) {
terminalTabbedManager.addTerminalTab(evt.tabIndex, tab)
} else {
terminalTabbedManager.addTerminalTab(tab)
}
if (tab is PtyHostTerminalTab) { if (tab is PtyHostTerminalTab) {
tab.start() tab.start()
} }

View File

@@ -27,9 +27,14 @@ class CloneSessionTerminalTabbedContextMenuExtension private constructor() : Ter
cloneSession.addActionListener(object : AnAction() { cloneSession.addActionListener(object : AnAction() {
override fun actionPerformed(evt: AnActionEvent) { override fun actionPerformed(evt: AnActionEvent) {
val terminalTabbedManager = evt.getData(DataProviders.TerminalTabbedManager) ?: return val terminalTabbedManager = evt.getData(DataProviders.TerminalTabbedManager) ?: return
val index = terminalTabbedManager.indexOfTerminalTab(tab)
val handler = c.copy(channel = null) val handler = c.copy(channel = null)
val newTab = SSHTerminalTab(windowScope, tab.host, handler) val newTab = SSHTerminalTab(windowScope, tab.host, handler)
terminalTabbedManager.addTerminalTab(newTab) if (index >= 0) {
terminalTabbedManager.addTerminalTab(index + 1, newTab)
} else {
terminalTabbedManager.addTerminalTab(newTab)
}
newTab.start() newTab.start()
} }
}) })

View File

@@ -46,6 +46,7 @@ class TransferAnAction : AnAction(I18n.getString("termora.transport.sftp"), Icon
val panel = tabbed.getTransportPanel(i) ?: continue val panel = tabbed.getTransportPanel(i) ?: continue
if (panel.host.id == host.id) { if (panel.host.id == host.id) {
tabbed.selectedIndex = i tabbed.selectedIndex = i
terminalTabbedManager.setSelectedTerminalTab(sftpTab)
return return
} }
} }