feat(terminal): refactor runtime and add mobile workspace (#2280)
Replace the legacy terminal flow with a shared authenticated WebSocket runtime used across web, desktop, relay, and mobile surfaces. - introduce the v3 terminal protocol with scoped attachments, snapshots, ordered output, bounded replay history, reconnects, and explicit lifecycle - harden PTY creation, restart, resize, close, force-kill, idle cleanup, shell selection, login mode, environment sanitization, and appearance sync - add runtime-aware terminal APIs with relay authentication and Electron parity - add a fullscreen mobile terminal workspace with touch scrolling, long-press selection, safe-area controls, quick keys, and Ctrl/Alt input - add terminal selection attachments, preview detection, project actions, shell settings, and localized UI - harden Ghostty rendering, resize recovery, Unicode handling, block characters, line height, and stale-row behavior - remove the obsolete terminal SSE path and update reverse-proxy guidance - expand terminal runtime, transport, input, selection, and store coverage - avoid duplicate web builds when preparing mobile assets in root CI builds
This commit is contained in:
committed by
GitHub
parent
f5b4a267c0
commit
d4a8c4d2e1
@@ -10,21 +10,58 @@ index 0000000000000000000000000000000000000000..11111111111111111111111111111111
|
||||
+ this.ctx = g, this.fontSize = B.fontSize ?? 15, this.fontFamily = B.fontFamily ?? "monospace", this.lineHeight = B.lineHeight ?? 1, this.cursorStyle = B.cursorStyle ?? "block", this.cursorBlink = B.cursorBlink ?? !1, this.theme = { ...f, ...B.theme }, this.devicePixelRatio = B.devicePixelRatio ?? window.devicePixelRatio ?? 1, this.palette = [
|
||||
@@ -1366,1 +1366,1 @@
|
||||
- const g = B.measureText("M"), E = Math.ceil(g.width), C = g.actualBoundingBoxAscent || this.fontSize * 0.8, I = g.actualBoundingBoxDescent || this.fontSize * 0.2, D = Math.ceil(C + I) + 2, i = Math.ceil(C) + 1;
|
||||
+ const g = B.measureText("M"), E = Math.ceil(g.width), C = g.actualBoundingBoxAscent || this.fontSize * 0.8, I = g.actualBoundingBoxDescent || this.fontSize * 0.2, D0 = Math.ceil(C + I), extra = Math.max(0, Math.round((this.lineHeight - 1) * D0)), D = D0 + 2 + extra, i = Math.ceil(C) + 1;
|
||||
+ const g = B.measureText("M"), E = Math.ceil(g.width), C = g.actualBoundingBoxAscent || this.fontSize * 0.8, I = g.actualBoundingBoxDescent || this.fontSize * 0.2, D0 = Math.ceil(C + I) + 2, extra = Math.max(0, Math.round((this.lineHeight - 1) * D0)), D = D0 + extra, i = Math.ceil(C) + 1;
|
||||
@@ -1538,1 +1538,1 @@
|
||||
- if (A.grapheme_len > 0 && ((k = this.currentBuffer) != null && k.getGraphemeString) ? N = this.currentBuffer.getGraphemeString(g, B) : N = String.fromCodePoint(A.codepoint || 32), this.ctx.fillText(N, w, s), A.flags & e.FAINT && (this.ctx.globalAlpha = 1), A.flags & e.UNDERLINE) {
|
||||
+ if (A.grapheme_len > 0 && ((k = this.currentBuffer) != null && k.getGraphemeString) ? N = this.currentBuffer.getGraphemeString(g, B) : N = A.codepoint == null || A.codepoint <= 0 || A.codepoint > 1114111 || A.codepoint >= 55296 && A.codepoint <= 57343 ? " " : String.fromCodePoint(A.codepoint), this.ctx.fillText(N, w, s), A.flags & e.FAINT && (this.ctx.globalAlpha = 1), A.flags & e.UNDERLINE) {
|
||||
@@ -1780,1 +1780,1 @@
|
||||
+ if (A.grapheme_len > 0 && ((k = this.currentBuffer) != null && k.getGraphemeString) ? N = this.currentBuffer.getGraphemeString(g, B) : N = A.codepoint == null || A.codepoint <= 0 || A.codepoint > 1114111 || A.codepoint >= 55296 && A.codepoint <= 57343 ? " " : String.fromCodePoint(A.codepoint), this.renderBlockChar(A.codepoint || 32, E, C, I) || this.ctx.fillText(N, w, s), A.flags & e.FAINT && (this.ctx.globalAlpha = 1), A.flags & e.UNDERLINE) {
|
||||
@@ -1557,1 +1557,36 @@
|
||||
}
|
||||
+ renderBlockChar(A, B, g, E) {
|
||||
+ const C = this.metrics.height, I = E / 2, D = C / 2;
|
||||
+ switch (A) {
|
||||
+ case 9600: this.ctx.fillRect(B, g, E, D); return !0;
|
||||
+ case 9601: this.ctx.fillRect(B, g + C * 7 / 8, E, C / 8); return !0;
|
||||
+ case 9602: this.ctx.fillRect(B, g + C * 3 / 4, E, C / 4); return !0;
|
||||
+ case 9603: this.ctx.fillRect(B, g + C * 5 / 8, E, C * 3 / 8); return !0;
|
||||
+ case 9604: this.ctx.fillRect(B, g + D, E, D); return !0;
|
||||
+ case 9605: this.ctx.fillRect(B, g + C * 3 / 8, E, C * 5 / 8); return !0;
|
||||
+ case 9606: this.ctx.fillRect(B, g + C / 4, E, C * 3 / 4); return !0;
|
||||
+ case 9607: this.ctx.fillRect(B, g + C / 8, E, C * 7 / 8); return !0;
|
||||
+ case 9608: this.ctx.fillRect(B, g, E, C); return !0;
|
||||
+ case 9609: this.ctx.fillRect(B, g, E * 7 / 8, C); return !0;
|
||||
+ case 9610: this.ctx.fillRect(B, g, E * 3 / 4, C); return !0;
|
||||
+ case 9611: this.ctx.fillRect(B, g, E * 5 / 8, C); return !0;
|
||||
+ case 9612: this.ctx.fillRect(B, g, I, C); return !0;
|
||||
+ case 9613: this.ctx.fillRect(B, g, E * 3 / 8, C); return !0;
|
||||
+ case 9614: this.ctx.fillRect(B, g, E / 4, C); return !0;
|
||||
+ case 9615: this.ctx.fillRect(B, g, E / 8, C); return !0;
|
||||
+ case 9616: this.ctx.fillRect(B + I, g, I, C); return !0;
|
||||
+ case 9620: this.ctx.fillRect(B, g, E, C / 8); return !0;
|
||||
+ case 9621: this.ctx.fillRect(B + E * 7 / 8, g, E / 8, C); return !0;
|
||||
+ case 9622: this.ctx.fillRect(B, g + D, I, D); return !0;
|
||||
+ case 9623: this.ctx.fillRect(B + I, g + D, I, D); return !0;
|
||||
+ case 9624: this.ctx.fillRect(B, g, I, D); return !0;
|
||||
+ case 9625: this.ctx.fillRect(B, g, I, C); this.ctx.fillRect(B + I, g + D, I, D); return !0;
|
||||
+ case 9626: this.ctx.fillRect(B, g, I, D); this.ctx.fillRect(B + I, g + D, I, D); return !0;
|
||||
+ case 9627: this.ctx.fillRect(B, g, E, D); this.ctx.fillRect(B, g + D, I, D); return !0;
|
||||
+ case 9628: this.ctx.fillRect(B, g, E, D); this.ctx.fillRect(B + I, g + D, I, D); return !0;
|
||||
+ case 9629: this.ctx.fillRect(B + I, g, I, D); return !0;
|
||||
+ case 9630: this.ctx.fillRect(B + I, g, I, D); this.ctx.fillRect(B, g + D, I, D); return !0;
|
||||
+ case 9631: this.ctx.fillRect(B + I, g, I, C); this.ctx.fillRect(B, g + D, I, D); return !0;
|
||||
+ default: return !1;
|
||||
+ }
|
||||
+ }
|
||||
@@ -1780,1 +1815,1 @@
|
||||
- if (a && a.codepoint !== 0) {
|
||||
+ if (a && a.codepoint !== 0 && a.codepoint <= 1114111 && !(a.codepoint >= 55296 && a.codepoint <= 57343)) {
|
||||
@@ -2054,1 +2054,1 @@
|
||||
@@ -2054,1 +2089,1 @@
|
||||
- if (!D || D.codepoint === 0)
|
||||
+ if (!D || D.codepoint === 0 || D.codepoint > 1114111 || D.codepoint >= 55296 && D.codepoint <= 57343)
|
||||
@@ -2205,1 +2205,2 @@
|
||||
@@ -2205,1 +2240,2 @@
|
||||
- fontFamily: A.fontFamily ?? "monospace",
|
||||
+ fontFamily: A.fontFamily ?? "monospace",
|
||||
+ lineHeight: A.lineHeight ?? 1,
|
||||
@@ -2340,1 +2341,2 @@
|
||||
@@ -2340,1 +2376,2 @@
|
||||
- fontFamily: this.options.fontFamily,
|
||||
+ fontFamily: this.options.fontFamily,
|
||||
+ lineHeight: this.options.lineHeight,
|
||||
|
||||
Reference in New Issue
Block a user