diff --git a/ShhShell/SSH/SSHHandler.swift b/ShhShell/SSH/SSHHandler.swift index 04783cb..6c4f10b 100644 --- a/ShhShell/SSH/SSHHandler.swift +++ b/ShhShell/SSH/SSHHandler.swift @@ -15,6 +15,7 @@ class SSHHandler: @unchecked Sendable, ObservableObject { private var channel: ssh_channel? var scrollback: [String] = [] + var scrollbackSize = 0.0 @Published var title: String = "" @Published var state: SSHState = .idle @@ -133,6 +134,9 @@ class SSHHandler: @unchecked Sendable, ObservableObject { withAnimation { self.testSuceeded = nil } } + scrollback = [] + scrollbackSize = 0 + //send eof if open if ssh_channel_is_open(channel) == 1 { ssh_channel_send_eof(channel) @@ -396,7 +400,12 @@ class SSHHandler: @unchecked Sendable, ObservableObject { // print(String(data: Data(bytes: buffer, count: Int(nbytes)), encoding: .utf8)!) #endif Task { @MainActor in - scrollback.append(string) + scrollback.append(string) + if scrollbackSize/1024/1024 > 10 { + scrollback.remove(at: 0) + } else { + scrollbackSize += Double(string.lengthOfBytes(using: .utf8)) + } } return string } @@ -429,6 +438,16 @@ class SSHHandler: @unchecked Sendable, ObservableObject { // print("resized tty to \(toRows)rows and \(toCols)cols") } + func prettyScrollbackSize() -> String { + if (scrollbackSize/1024/1024) > 1 { + return "\(scrollbackSize/1024/1024) MiB scrollback" + } else if scrollbackSize/1024 > 1 { + return "\(scrollbackSize/1024) KiB scrollback" + } else { + return "\(scrollbackSize) B scrollback" + } + } + private func logSshGetError() { guard var session = self.session else { return } logger.critical("\(String(cString: ssh_get_error(&session)))") diff --git a/ShhShell/Views/Hosts/ConnectionView.swift b/ShhShell/Views/Hosts/ConnectionView.swift index 6cd7d4c..e86e83a 100644 --- a/ShhShell/Views/Hosts/ConnectionView.swift +++ b/ShhShell/Views/Hosts/ConnectionView.swift @@ -12,8 +12,6 @@ struct ConnectionView: View { @ObservedObject var hostsManager: HostsManager @ObservedObject var keyManager: KeyManager - @State var resuming: Bool = false - @State var passphrase: String = "" @State var pubkeyStr: String = "" @@ -112,7 +110,6 @@ struct ConnectionView: View { Button() { showTerminal.toggle() - resuming = true } label: { Label("Show Terminal", systemImage: "apple.terminal") } @@ -159,7 +156,7 @@ struct ConnectionView: View { } } .fullScreenCover(isPresented: $showTerminal) { - ShellView(handler: handler, resuming: resuming) + ShellView(handler: handler) } .onChange(of: handler.host.key) { _ in guard let previousKnownHost = hostsManager.getHostMatching(handler.host) else { return } @@ -169,7 +166,7 @@ struct ConnectionView: View { } } .onDisappear { -// hostsManager.updateHost(handler.host) + hostsManager.updateHost(handler.host) } .task { if let publicKeyData = handler.host.publicKey { diff --git a/ShhShell/Views/Hosts/HostsView.swift b/ShhShell/Views/Hosts/HostsView.swift index e171c74..eafde56 100644 --- a/ShhShell/Views/Hosts/HostsView.swift +++ b/ShhShell/Views/Hosts/HostsView.swift @@ -29,7 +29,7 @@ struct HostsView: View { NavigationLink() { ForEach(hostsManager.savedHosts) { host in let miniHandler = SSHHandler(host: host) - TerminalController(handler: miniHandler, resuming: false) + TerminalController(handler: miniHandler) .onAppear { miniHandler.go() } } } label: { diff --git a/ShhShell/Views/Terminal/SSHTerminalView.swift b/ShhShell/Views/Terminal/SSHTerminalView.swift index 047ff93..4505a96 100644 --- a/ShhShell/Views/Terminal/SSHTerminalView.swift +++ b/ShhShell/Views/Terminal/SSHTerminalView.swift @@ -12,29 +12,15 @@ import SwiftTerm @MainActor final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalViewDelegate { var handler: SSHHandler? - var sshQueue = DispatchQueue(label: "sshQueue") - var resuming: Bool +// var sshQueue = DispatchQueue(label: "sshQueue") - public convenience init(frame: CGRect, handler: SSHHandler, resuming: Bool) { + public convenience init(frame: CGRect, handler: SSHHandler) { self.init(frame: frame) self.handler = handler - self.resuming = resuming - sshQueue.async { - Task { - if resuming { - if let handler = await self.handler { - for chunk in handler.scrollback { - await MainActor.run { - self.feed(text: chunk) - } - } - } - } - } - } - - sshQueue.async { + restoreScrollback() + + DispatchQueue.main.async { Task { guard let handler = await self.handler else { return } while handler.connected { @@ -52,7 +38,6 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie } public override init(frame: CGRect) { - self.resuming = false super.init(frame: frame) terminalDelegate = self } @@ -100,4 +85,16 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie public func bell(source: TerminalView) { handler?.ring() } + + func restoreScrollback() { + guard let scrollback = handler?.scrollback else { return } + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { + for line in scrollback { + self.feed(text: line) + } + self.setNeedsLayout() + self.setNeedsDisplay() + } + } } diff --git a/ShhShell/Views/Terminal/ShellView.swift b/ShhShell/Views/Terminal/ShellView.swift index cb1c874..3da140e 100644 --- a/ShhShell/Views/Terminal/ShellView.swift +++ b/ShhShell/Views/Terminal/ShellView.swift @@ -9,7 +9,6 @@ import SwiftUI struct ShellView: View { @ObservedObject var handler: SSHHandler - @State var resuming: Bool = false @Environment(\.dismiss) var dismiss @@ -33,7 +32,7 @@ struct ShellView: View { } } .task { - terminalControllerRef = TerminalController(handler: handler, resuming: resuming) + terminalControllerRef = TerminalController(handler: handler) } .toolbar { ToolbarItem { diff --git a/ShhShell/Views/Terminal/TerminalController.swift b/ShhShell/Views/Terminal/TerminalController.swift index 6fdb652..247511c 100644 --- a/ShhShell/Views/Terminal/TerminalController.swift +++ b/ShhShell/Views/Terminal/TerminalController.swift @@ -12,7 +12,6 @@ import SwiftTerm struct TerminalController: UIViewRepresentable { @ObservedObject var handler: SSHHandler - @State var resuming: Bool func makeUIView(context: Context) -> TerminalView { let tv = SSHTerminalView( @@ -20,8 +19,7 @@ struct TerminalController: UIViewRepresentable { origin: CGPoint(x: 0, y: 0), size: .zero ), - handler: handler, - resuming: resuming + handler: handler ) tv.translatesAutoresizingMaskIntoConstraints = false