mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 13:26:16 +00:00
fully working v1 of jelly cursor
i plan to redo this cos its an overlay and not actually there, so it kinda breaks the illusion if scrolling
This commit is contained in:
@@ -27,6 +27,7 @@ final class SSHTerminalDelegate: TerminalView, Sendable, @preconcurrency Termina
|
|||||||
restoreScrollback()
|
restoreScrollback()
|
||||||
if let hostsManager {
|
if let hostsManager {
|
||||||
font = UIFont(name: hostsManager.selectedFont, size: hostsManager.fontSize)!
|
font = UIFont(name: hostsManager.selectedFont, size: hostsManager.fontSize)!
|
||||||
|
print(computeFontDimensions())
|
||||||
}
|
}
|
||||||
applySelectedTheme()
|
applySelectedTheme()
|
||||||
applyScrollbackLength()
|
applyScrollbackLength()
|
||||||
@@ -66,6 +67,34 @@ final class SSHTerminalDelegate: TerminalView, Sendable, @preconcurrency Termina
|
|||||||
super.cursorStyleChanged(source: source, newStyle: newStyle)
|
super.cursorStyleChanged(source: source, newStyle: newStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//excerpt from SwiftTerm, modified to get around private properties
|
||||||
|
func computeFontDimensions () -> CGSize
|
||||||
|
{
|
||||||
|
let lineAscent = CTFontGetAscent (font)
|
||||||
|
let lineDescent = CTFontGetDescent (font)
|
||||||
|
let lineLeading = CTFontGetLeading (font)
|
||||||
|
let cellHeight = ceil(lineAscent + lineDescent + lineLeading)
|
||||||
|
#if os(macOS)
|
||||||
|
// The following is a more robust way of getting the largest ascii character width, but comes with a performance hit.
|
||||||
|
// See: https://github.com/migueldeicaza/SwiftTerm/issues/286
|
||||||
|
// var sizes = UnsafeMutablePointer<NSSize>.allocate(capacity: 95)
|
||||||
|
// let ctFont = (font as CTFont)
|
||||||
|
// var glyphs = (32..<127).map { CTFontGetGlyphWithName(ctFont, String(Unicode.Scalar($0)) as CFString) }
|
||||||
|
// withUnsafePointer(to: glyphs[0]) { glyphsPtr in
|
||||||
|
// fontSet.normal.getAdvancements(NSSizeArray(sizes), forCGGlyphs: glyphsPtr, count: 95)
|
||||||
|
// }
|
||||||
|
// let cellWidth = (0..<95).reduce(into: 0) { partialResult, idx in
|
||||||
|
// partialResult = max(partialResult, sizes[idx].width)
|
||||||
|
// }
|
||||||
|
let glyph = font.glyph(withName: "W")
|
||||||
|
let cellWidth = font.advancement(forGlyph: glyph).width
|
||||||
|
#else
|
||||||
|
let fontAttributes = [NSAttributedString.Key.font: font]
|
||||||
|
let cellWidth = "W".size(withAttributes: fontAttributes).width
|
||||||
|
#endif
|
||||||
|
return CGSize(width: max (1, cellWidth), height: max (min (cellHeight, 8192), 1))
|
||||||
|
}
|
||||||
|
|
||||||
func startFeedLoop() {
|
func startFeedLoop() {
|
||||||
Task {
|
Task {
|
||||||
guard let handler else { return }
|
guard let handler else { return }
|
||||||
@@ -73,7 +102,6 @@ final class SSHTerminalDelegate: TerminalView, Sendable, @preconcurrency Termina
|
|||||||
if let read = handler.readFromChannel() {
|
if let read = handler.readFromChannel() {
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
self.feed(text: read)
|
self.feed(text: read)
|
||||||
print(getTerminal().getCursorLocation())
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try? await Task.sleep(nanoseconds: 10_000_000) //10ms
|
try? await Task.sleep(nanoseconds: 10_000_000) //10ms
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ struct ShellView: View {
|
|||||||
@ObservedObject var container = TerminalViewContainer.shared
|
@ObservedObject var container = TerminalViewContainer.shared
|
||||||
|
|
||||||
@State var jellyLoc: (x: Int, y: Int) = (0, 0)
|
@State var jellyLoc: (x: Int, y: Int) = (0, 0)
|
||||||
|
@State var jellySize: CGSize = CGSize(width: 0, height: 0)
|
||||||
@State var jellyShow: Bool = true
|
@State var jellyShow: Bool = true
|
||||||
|
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
@@ -31,19 +32,21 @@ struct ShellView: View {
|
|||||||
let timer = Timer(timeInterval: 0.1, repeats: true) { timer in
|
let timer = Timer(timeInterval: 0.1, repeats: true) { timer in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
let terminalView = container.sessions[handler.sessionID ?? UUID()]?.terminalView
|
let terminalView = container.sessions[handler.sessionID ?? UUID()]?.terminalView
|
||||||
|
let delegate = terminalView?.terminalDelegate as? SSHTerminalDelegate
|
||||||
terminalView?.getTerminal().hideCursor()
|
terminalView?.getTerminal().hideCursor()
|
||||||
jellyLoc = terminalView?.getTerminal().getCursorLocation() ?? (0,0)
|
jellyLoc = terminalView?.getTerminal().getCursorLocation() ?? jellyLoc
|
||||||
jellyShow = terminalView?.getTerminal().buffer.isCursorInViewPort ?? true
|
jellySize = delegate?.computeFontDimensions() ?? jellySize
|
||||||
|
// jellyShow = terminalView?.getTerminal().buffer.isCursorInViewPort ?? jellyShow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RunLoop.main.add(timer, forMode: .common)
|
RunLoop.main.add(timer, forMode: .common)
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.frame(width: 4.3, height: 12)
|
.frame(width: jellySize.width, height: jellySize.height)
|
||||||
.offset(
|
.offset(
|
||||||
x: CGFloat(jellyLoc.x)*4.3,
|
x: CGFloat(jellyLoc.x)*jellySize.width,
|
||||||
y: CGFloat(jellyLoc.y)*8.66
|
y: CGFloat(jellyLoc.y)*jellySize.height
|
||||||
)
|
)
|
||||||
.opacity(jellyShow ? 1 : 0)
|
.opacity(jellyShow ? 1 : 0)
|
||||||
.animation(.spring, value: jellyLoc.x)
|
.animation(.spring, value: jellyLoc.x)
|
||||||
|
|||||||
Reference in New Issue
Block a user