ok so now you can minimize an ssh session
 - it will remember the scrollback,
- if u uminimixe it and then reconnect, it works
it uses a shared static var in TerminalViewContainer to keep SSHTerminal instances
scrollback restoration works and everything
This commit is contained in:
neon443
2025-06-26 16:25:35 +01:00
parent 747406df5d
commit 09fd4a10fd
4 changed files with 31 additions and 21 deletions

View File

@@ -12,6 +12,8 @@ struct ConnectionView: View {
@ObservedObject var hostsManager: HostsManager
@ObservedObject var keyManager: KeyManager
@State private var shellView: ShellView? = nil
@State var passphrase: String = ""
@State var pubkeyStr: String = ""
@@ -145,6 +147,7 @@ struct ConnectionView: View {
Button() {
handler.go()
showTerminal = checkShell(handler.state)
TerminalController.TerminalViewContainer.shared = nil
} label: {
Label(
handler.connected ? "Disconnect" : "Connect",
@@ -156,7 +159,11 @@ struct ConnectionView: View {
}
}
.fullScreenCover(isPresented: $showTerminal) {
ShellView(handler: handler)
if let shellView {
shellView
} else {
Text("no shellview")
}
}
.onChange(of: handler.host.key) { _ in
guard let previousKnownHost = hostsManager.getHostMatching(handler.host) else { return }
@@ -176,6 +183,11 @@ struct ConnectionView: View {
privkeyStr = String(data: privateKeyData, encoding: .utf8) ?? ""
}
}
.onAppear {
if shellView == nil {
shellView = ShellView(handler: handler)
}
}
}
}

View File

@@ -18,8 +18,6 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie
self.init(frame: frame)
self.handler = handler
restoreScrollback()
DispatchQueue.main.async {
Task {
guard let handler = self.handler else { return }
@@ -88,8 +86,10 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie
func restoreScrollback() {
guard let scrollback = handler?.scrollback else { return }
guard !scrollback.isEmpty else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.getTerminal().resetToInitialState()
for line in scrollback {
self.feed(text: line)
}

View File

@@ -12,12 +12,14 @@ struct ShellView: View {
@Environment(\.dismiss) var dismiss
@State private var terminalControllerRef: TerminalController?
var body: some View {
NavigationStack {
ZStack {
terminalControllerRef
TerminalController(handler: handler)
.onAppear {
print("asd\(handler.scrollback.count)")
TerminalController.TerminalViewContainer.shared?.restoreScrollback()
}
Group {
Color.gray.opacity(0.2)
@@ -31,9 +33,6 @@ struct ShellView: View {
DialogView(handler: handler, showDialog: !handler.connected)
}
}
.task {
terminalControllerRef = TerminalController(handler: handler)
}
.toolbar {
ToolbarItem {
Button() {

View File

@@ -13,18 +13,21 @@ import SwiftTerm
struct TerminalController: UIViewRepresentable {
@ObservedObject var handler: SSHHandler
func makeUIView(context: Context) -> TerminalView {
let tv = SSHTerminalView(
frame: CGRect(
origin: CGPoint(x: 0, y: 0),
size: .zero
),
handler: handler
)
final class TerminalViewContainer {
@MainActor static var shared: SSHTerminalView?
}
func makeUIView(context: Context) -> TerminalView {
if let existing = TerminalViewContainer.shared {
return existing
}
let tv = SSHTerminalView(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: .zero), handler: handler)
tv.translatesAutoresizingMaskIntoConstraints = false
tv.autoresizingMask = [.flexibleWidth, .flexibleHeight]
TerminalViewContainer.shared = tv
return tv
}
@@ -32,8 +35,4 @@ struct TerminalController: UIViewRepresentable {
tv.setNeedsLayout()
tv.layoutIfNeeded()
}
static func dismantleUIView(_ uiView: SSHTerminalView, coordinator: ()) {
uiView.handler?.disconnect()
}
}