@floegence/floeterm-terminal-web 0.4.21 → 0.4.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,6 +47,19 @@ const core = new TerminalCore(container, {
47
47
  });
48
48
  ```
49
49
 
50
+ Passive mirrors of a remote PTY can render with the session owner's current dimensions instead of fitting their own
51
+ container:
52
+
53
+ ```ts
54
+ const core = new TerminalCore(container, {
55
+ fixedDimensions: { cols: 100, rows: 30 },
56
+ });
57
+
58
+ // Later, when this surface becomes the active geometry owner:
59
+ core.setFixedDimensions(null);
60
+ core.forceResize();
61
+ ```
62
+
50
63
  ## Clipboard behavior
51
64
  By default, upstream mouse selection keeps the `ghostty-web` behavior and copies immediately on selection.
52
65
  Consumers that want explicit copy commands only can disable that side effect:
@@ -1,4 +1,4 @@
1
- import { TerminalState, type Logger, type TerminalConfig, type TerminalCopySelectionResult, type TerminalCopySelectionSource, type TerminalEventHandlers, type TerminalLinkProvider } from '../types';
1
+ import { TerminalState, type Logger, type TerminalConfig, type TerminalCopySelectionResult, type TerminalCopySelectionSource, type TerminalDimensions, type TerminalEventHandlers, type TerminalLinkProvider } from '../types';
2
2
  export declare class TerminalCore {
3
3
  private container;
4
4
  private config;
@@ -11,6 +11,7 @@ export declare class TerminalCore {
11
11
  private renderHost;
12
12
  private resizeObserver;
13
13
  private resizeDebounceTimer;
14
+ private resizeRaf;
14
15
  private focusResizeRaf;
15
16
  private presentationScaleRaf;
16
17
  private state;
@@ -23,6 +24,7 @@ export declare class TerminalCore {
23
24
  private responsive;
24
25
  private logicalFontSize;
25
26
  private presentationScale;
27
+ private fixedDimensions;
26
28
  private pendingPresentationScale;
27
29
  private suppressResizeNotifications;
28
30
  private clearResizeSuppressionRaf;
@@ -51,18 +53,22 @@ export declare class TerminalCore {
51
53
  private openTerminal;
52
54
  private installDemandRenderPatchBeforeOpen;
53
55
  private patchDemandRenderTriggersAfterOpen;
56
+ private patchRendererCursorBlinkForDemandRendering;
57
+ private keepDemandCursorVisible;
54
58
  private installRendererRowCachePatch;
55
59
  private ensurePresentationHosts;
56
60
  private applyPresentationScaleStyles;
57
61
  private patchSelectionManagerClipboardBehavior;
62
+ private patchSelectionManagerRenderingBehavior;
58
63
  private setupInputBridge;
59
64
  private waitForDOMAndFonts;
60
65
  private ensureContainerReady;
61
66
  private setupEventListeners;
62
67
  private setupResponsiveListeners;
63
68
  private startSizeWatching;
64
- private debouncedResize;
69
+ private scheduleObservedResize;
65
70
  private performResize;
71
+ private applyFixedDimensions;
66
72
  private scheduleFocusResize;
67
73
  private emitResize;
68
74
  private isContainerFocused;
@@ -127,6 +133,7 @@ export declare class TerminalCore {
127
133
  focus(): void;
128
134
  setConnected(isConnected: boolean): void;
129
135
  forceResize(): void;
136
+ setFixedDimensions(dimensions: TerminalDimensions | null): void;
130
137
  setTheme(theme: Record<string, string>): void;
131
138
  setFontSize(size: number): void;
132
139
  setPresentationScale(scale: number): void;
@@ -1 +1 @@
1
- {"version":3,"file":"TerminalCore.d.ts","sourceRoot":"","sources":["../../src/core/TerminalCore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TerminalCore.d.ts","sourceRoot":"","sources":["../../src/core/TerminalCore.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,14 @@ const PRESENTATION_SCALE_EPSILON = 0.0001;
8
8
  const TERMINAL_SEARCH_MATCH_BACKGROUND = 'rgba(255, 234, 0, 0.38)';
9
9
  const TERMINAL_SEARCH_ACTIVE_BACKGROUND = 'rgba(255, 234, 0, 0.72)';
10
10
  const TERMINAL_SEARCH_ACTIVE_FOREGROUND = '#dc2626';
11
+ const TERMINAL_SELECTION_BACKGROUND = '#f5e6b3';
12
+ const TERMINAL_SELECTION_FOREGROUND = '#1f2328';
13
+ const getPerfProbe = () => {
14
+ if (typeof window === 'undefined') {
15
+ return undefined;
16
+ }
17
+ return window.__floetermPerfProbe;
18
+ };
11
19
  // Dynamic imports avoid SSR issues and keep the bundle flexible.
12
20
  let TerminalCtor = null;
13
21
  let FitAddonCtor = null;
@@ -96,6 +104,21 @@ function canSkipCachedRowRender(renderer, row) {
96
104
  function samePresentationScale(left, right) {
97
105
  return Math.abs(left - right) <= PRESENTATION_SCALE_EPSILON;
98
106
  }
107
+ function normalizeTerminalDimensions(value) {
108
+ const raw = (typeof value === 'object' && value) ? value : null;
109
+ if (!raw) {
110
+ return null;
111
+ }
112
+ const cols = Math.floor(Number(raw.cols));
113
+ const rows = Math.floor(Number(raw.rows));
114
+ if (!Number.isFinite(cols) || !Number.isFinite(rows) || cols <= 0 || rows <= 0) {
115
+ return null;
116
+ }
117
+ return { cols, rows };
118
+ }
119
+ function sameTerminalDimensions(left, right) {
120
+ return Boolean(left && right && left.cols === right.cols && left.rows === right.rows);
121
+ }
99
122
  function hasTransientRendererState(renderer) {
100
123
  return Boolean(renderer.currentSelectionCoords
101
124
  || (renderer.hoveredHyperlinkId ?? 0) > 0
@@ -115,6 +138,7 @@ export class TerminalCore {
115
138
  this.renderHost = null;
116
139
  this.resizeObserver = null;
117
140
  this.resizeDebounceTimer = null;
141
+ this.resizeRaf = null;
118
142
  this.focusResizeRaf = null;
119
143
  this.presentationScaleRaf = null;
120
144
  this.state = TerminalState.IDLE;
@@ -123,6 +147,7 @@ export class TerminalCore {
123
147
  this.replayingHistoryTimer = null;
124
148
  this.logicalFontSize = 12;
125
149
  this.presentationScale = 1;
150
+ this.fixedDimensions = null;
126
151
  this.pendingPresentationScale = null;
127
152
  this.suppressResizeNotifications = false;
128
153
  this.clearResizeSuppressionRaf = null;
@@ -151,6 +176,7 @@ export class TerminalCore {
151
176
  this.responsive = TerminalCore.normalizeResponsiveConfig(config?.responsive);
152
177
  this.logicalFontSize = TerminalCore.normalizeFontSize(config?.fontSize);
153
178
  this.presentationScale = TerminalCore.normalizePresentationScale(config?.presentationScale);
179
+ this.fixedDimensions = normalizeTerminalDimensions(config?.fixedDimensions);
154
180
  }
155
181
  // initialize creates the ghostty-web terminal instance and binds addons.
156
182
  async initialize() {
@@ -188,11 +214,12 @@ export class TerminalCore {
188
214
  background: '#1a1a1a',
189
215
  foreground: '#ffffff',
190
216
  cursor: '#ffffff',
191
- selectionBackground: '#ffffff40'
217
+ selectionBackground: TERMINAL_SELECTION_BACKGROUND,
218
+ selectionForeground: TERMINAL_SELECTION_FOREGROUND
192
219
  },
193
220
  fontSize: 12,
194
221
  fontFamily: '\"SF Mono\", Monaco, \"Cascadia Code\", \"Roboto Mono\", Consolas, \"Courier New\", monospace',
195
- cursorBlink: true,
222
+ cursorBlink: false,
196
223
  scrollback: 1000,
197
224
  allowTransparency: false,
198
225
  convertEol: true,
@@ -203,9 +230,10 @@ export class TerminalCore {
203
230
  const finalConfig = { ...defaultConfig, ...this.config };
204
231
  this.logicalFontSize = TerminalCore.normalizeFontSize(finalConfig.fontSize);
205
232
  this.presentationScale = TerminalCore.normalizePresentationScale(finalConfig.presentationScale);
233
+ const initialDimensions = this.fixedDimensions;
206
234
  this.terminal = new TerminalCtor({
207
- cols: typeof finalConfig.cols === 'number' ? finalConfig.cols : undefined,
208
- rows: typeof finalConfig.rows === 'number' ? finalConfig.rows : undefined,
235
+ cols: initialDimensions?.cols ?? (typeof finalConfig.cols === 'number' ? finalConfig.cols : undefined),
236
+ rows: initialDimensions?.rows ?? (typeof finalConfig.rows === 'number' ? finalConfig.rows : undefined),
209
237
  cursorBlink: typeof finalConfig.cursorBlink === 'boolean' ? finalConfig.cursorBlink : undefined,
210
238
  cursorStyle: typeof finalConfig.cursorStyle === 'string' ? finalConfig.cursorStyle : undefined,
211
239
  theme: mapThemeToGhostty(finalConfig.theme),
@@ -241,6 +269,7 @@ export class TerminalCore {
241
269
  this.stopGhosttyRenderLoop();
242
270
  this.patchDemandRenderTriggersAfterOpen();
243
271
  this.patchSelectionManagerClipboardBehavior();
272
+ this.patchSelectionManagerRenderingBehavior();
244
273
  this.setupInputBridge();
245
274
  this.applyRegisteredLinkProviders();
246
275
  }
@@ -296,6 +325,29 @@ export class TerminalCore {
296
325
  wrapRendererInvalidation('setFontSize');
297
326
  wrapRendererInvalidation('setFontFamily');
298
327
  wrapRendererInvalidation('clear');
328
+ this.patchRendererCursorBlinkForDemandRendering(renderer);
329
+ }
330
+ patchRendererCursorBlinkForDemandRendering(renderer) {
331
+ if (!renderer || renderer.__floetermDemandCursorPatched) {
332
+ return;
333
+ }
334
+ renderer.__floetermDemandCursorPatched = true;
335
+ renderer.cursorVisible = true;
336
+ try {
337
+ renderer.setCursorBlink?.(false);
338
+ }
339
+ catch (error) {
340
+ this.logger.debug('[TerminalCore] Failed to disable cursor blink for demand rendering', { error });
341
+ }
342
+ if (this.terminal) {
343
+ this.terminal.options.cursorBlink = false;
344
+ }
345
+ }
346
+ keepDemandCursorVisible(renderer) {
347
+ if (!renderer) {
348
+ return;
349
+ }
350
+ renderer.cursorVisible = true;
299
351
  }
300
352
  installRendererRowCachePatch(renderer) {
301
353
  if (!renderer || renderer.__floetermRowRenderCachePatched) {
@@ -382,6 +434,21 @@ export class TerminalCore {
382
434
  // the selection lifecycle intact for explicit copy commands.
383
435
  };
384
436
  }
437
+ patchSelectionManagerRenderingBehavior() {
438
+ const selectionManager = (this.terminal
439
+ ?.selectionManager) ?? null;
440
+ if (!selectionManager || selectionManager.__floetermDemandRenderPatched) {
441
+ return;
442
+ }
443
+ selectionManager.__floetermDemandRenderPatched = true;
444
+ const originalRequestRender = typeof selectionManager.requestRender === 'function'
445
+ ? selectionManager.requestRender.bind(selectionManager)
446
+ : null;
447
+ selectionManager.requestRender = () => {
448
+ originalRequestRender?.();
449
+ this.requestDemandRender(false);
450
+ };
451
+ }
385
452
  setupInputBridge() {
386
453
  this.disposeInputBridge();
387
454
  const input = resolveTerminalInputElement(this.container);
@@ -526,23 +593,48 @@ export class TerminalCore {
526
593
  if (!this.container || !this.fitAddon) {
527
594
  return;
528
595
  }
596
+ if (typeof ResizeObserver === 'undefined') {
597
+ return;
598
+ }
529
599
  this.resizeObserver = new ResizeObserver(() => {
530
- this.debouncedResize();
600
+ this.scheduleObservedResize();
531
601
  });
532
- this.resizeObserver.observe(this.container);
533
- }
534
- debouncedResize() {
602
+ const observed = new Set();
603
+ const observe = (target) => {
604
+ if (!target || observed.has(target)) {
605
+ return;
606
+ }
607
+ observed.add(target);
608
+ this.resizeObserver?.observe(target);
609
+ };
610
+ observe(this.container);
611
+ observe(this.container.parentElement);
612
+ observe(this.viewportHost);
613
+ observe(this.renderHost);
614
+ }
615
+ scheduleObservedResize() {
616
+ if (this.resizeRaf === null) {
617
+ this.resizeRaf = requestAnimationFrame(() => {
618
+ this.resizeRaf = null;
619
+ this.performResize('observer');
620
+ });
621
+ }
535
622
  if (this.resizeDebounceTimer) {
536
623
  clearTimeout(this.resizeDebounceTimer);
537
624
  }
538
625
  this.resizeDebounceTimer = setTimeout(() => {
626
+ this.resizeDebounceTimer = null;
539
627
  this.performResize('observer');
540
- }, 16);
628
+ }, 80);
541
629
  }
542
630
  performResize(reason) {
543
631
  if (!this.isReady() || !this.fitAddon || !this.terminal) {
544
632
  return;
545
633
  }
634
+ if (this.fixedDimensions) {
635
+ this.applyFixedDimensions(reason);
636
+ return;
637
+ }
546
638
  if (this.container.clientWidth === 0 || this.container.clientHeight === 0) {
547
639
  return;
548
640
  }
@@ -567,6 +659,35 @@ export class TerminalCore {
567
659
  }
568
660
  this.emitResize(dims, { source: 'core' });
569
661
  }
662
+ applyFixedDimensions(reason) {
663
+ if (!this.terminal || !this.fixedDimensions) {
664
+ return;
665
+ }
666
+ const dims = this.fixedDimensions;
667
+ const startSeq = this.resizeNotifySeq;
668
+ const before = this.lastNotifiedSize;
669
+ const changed = this.terminal.cols !== dims.cols || this.terminal.rows !== dims.rows;
670
+ if (changed) {
671
+ try {
672
+ this.terminal.resize(dims.cols, dims.rows);
673
+ }
674
+ catch (error) {
675
+ this.logger.debug('[TerminalCore] Fixed-dimension resize failed', { error });
676
+ }
677
+ }
678
+ // Some ghostty-web builds may not emit onResize for programmatic resize().
679
+ if (this.resizeNotifySeq !== startSeq) {
680
+ return;
681
+ }
682
+ if (reason === 'focus' && this.responsive.emitResizeOnFocus) {
683
+ const force = Boolean(before) && before.cols === dims.cols && before.rows === dims.rows;
684
+ this.emitResize(dims, { source: 'core', force });
685
+ return;
686
+ }
687
+ if (changed) {
688
+ this.emitResize(dims, { source: 'core' });
689
+ }
690
+ }
570
691
  scheduleFocusResize() {
571
692
  if (!this.responsive.fitOnFocus && !this.responsive.emitResizeOnFocus) {
572
693
  return;
@@ -644,6 +765,7 @@ export class TerminalCore {
644
765
  return;
645
766
  }
646
767
  try {
768
+ getPerfProbe()?.onTerminalWrite?.(typeof data === 'string' ? data.length : data.byteLength);
647
769
  const shouldForce = this.needsFullRenderOnNextWrite;
648
770
  if (callback || shouldForce) {
649
771
  this.terminal.write(data, () => {
@@ -1277,6 +1399,18 @@ export class TerminalCore {
1277
1399
  this.performResize('force');
1278
1400
  this.forceFullRender();
1279
1401
  }
1402
+ setFixedDimensions(dimensions) {
1403
+ const next = normalizeTerminalDimensions(dimensions);
1404
+ if (sameTerminalDimensions(this.fixedDimensions, next) || (!this.fixedDimensions && !next)) {
1405
+ return;
1406
+ }
1407
+ this.fixedDimensions = next;
1408
+ this.config = { ...this.config, fixedDimensions: next };
1409
+ if (!this.terminal) {
1410
+ return;
1411
+ }
1412
+ this.forceResize();
1413
+ }
1280
1414
  setTheme(theme) {
1281
1415
  const mapped = mapThemeToGhostty(theme);
1282
1416
  // Persist latest theme so a future re-initialization can reuse it.
@@ -1360,6 +1494,10 @@ export class TerminalCore {
1360
1494
  cancelAnimationFrame(this.clearResizeSuppressionRaf);
1361
1495
  this.clearResizeSuppressionRaf = null;
1362
1496
  }
1497
+ if (this.resizeRaf !== null) {
1498
+ cancelAnimationFrame(this.resizeRaf);
1499
+ this.resizeRaf = null;
1500
+ }
1363
1501
  this.cancelDemandRender();
1364
1502
  this.unbindResponsiveListeners?.();
1365
1503
  this.unbindResponsiveListeners = null;
@@ -1530,12 +1668,15 @@ export class TerminalCore {
1530
1668
  return;
1531
1669
  }
1532
1670
  try {
1671
+ const startedAt = performance.now();
1672
+ this.keepDemandCursorVisible(terminalAny.renderer);
1533
1673
  terminalAny.renderer.render(terminalAny.wasmTerm, forceAll, terminalAny.viewportY ?? 0, terminalAny, terminalAny.scrollbarOpacity);
1534
1674
  const cursor = terminalAny.wasmTerm.getCursor?.();
1535
1675
  if (cursor && typeof cursor.y === 'number' && cursor.y !== terminalAny.lastCursorY) {
1536
1676
  terminalAny.lastCursorY = cursor.y;
1537
1677
  terminalAny.cursorMoveEmitter?.fire?.();
1538
1678
  }
1679
+ getPerfProbe()?.onTerminalRender?.(performance.now() - startedAt);
1539
1680
  }
1540
1681
  catch (error) {
1541
1682
  this.logger.debug('[TerminalCore] Force render failed', { error });