@earendil-works/pi-tui 0.79.3 → 0.79.4

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/dist/tui.js CHANGED
@@ -6,6 +6,7 @@ import * as os from "node:os";
6
6
  import * as path from "node:path";
7
7
  import { performance } from "node:perf_hooks";
8
8
  import { isKeyRelease, matchesKey } from "./keys.js";
9
+ import { isOsc11BackgroundColorResponse, parseOsc11BackgroundColor } from "./terminal-colors.js";
9
10
  import { deleteKittyImage, getCapabilities, isImageLine, setCellDimensions } from "./terminal-image.js";
10
11
  import { extractSegments, normalizeTerminalOutput, sliceByColumn, sliceWithWidth, visibleWidth } from "./utils.js";
11
12
  const KITTY_SEQUENCE_PREFIX = "\x1b_G";
@@ -128,6 +129,8 @@ export class TUI extends Container {
128
129
  previousViewportTop = 0; // Track previous viewport top for resize-aware cursor moves
129
130
  fullRedrawCount = 0;
130
131
  stopped = false;
132
+ pendingOsc11BackgroundReplies = 0;
133
+ pendingOsc11BackgroundQueries = [];
131
134
  // Overlay stack for modal components rendered on top of base content
132
135
  focusOrderCounter = 0;
133
136
  overlayStack = [];
@@ -518,6 +521,9 @@ export class TUI extends Container {
518
521
  }, delay);
519
522
  }
520
523
  handleInput(data) {
524
+ if (this.consumeOsc11BackgroundResponse(data)) {
525
+ return;
526
+ }
521
527
  if (this.inputListeners.size > 0) {
522
528
  let current = data;
523
529
  for (const listener of this.inputListeners) {
@@ -583,6 +589,27 @@ export class TUI extends Container {
583
589
  this.requestRender();
584
590
  }
585
591
  }
592
+ consumeOsc11BackgroundResponse(data) {
593
+ if (this.pendingOsc11BackgroundReplies <= 0) {
594
+ return false;
595
+ }
596
+ if (!isOsc11BackgroundColorResponse(data)) {
597
+ return false;
598
+ }
599
+ const rgb = parseOsc11BackgroundColor(data);
600
+ this.pendingOsc11BackgroundReplies -= 1;
601
+ const query = this.pendingOsc11BackgroundQueries.shift();
602
+ if (query && !query.settled) {
603
+ query.settled = true;
604
+ if (query.timer) {
605
+ clearTimeout(query.timer);
606
+ query.timer = undefined;
607
+ }
608
+ query.resolve?.(rgb);
609
+ query.resolve = undefined;
610
+ }
611
+ return true;
612
+ }
586
613
  consumeCellSizeResponse(data) {
587
614
  // Response format: ESC [ 6 ; height ; width t
588
615
  const match = data.match(/^\x1b\[6;(\d+);(\d+)t$/);
@@ -946,7 +973,20 @@ export class TUI extends Container {
946
973
  for (let i = 0; i < newLines.length; i++) {
947
974
  if (i > 0)
948
975
  buffer += "\r\n";
949
- buffer += newLines[i];
976
+ const line = newLines[i];
977
+ const isImage = isImageLine(line);
978
+ const imageReservedRows = isImage ? this.getKittyImageReservedRows(newLines, i) : 1;
979
+ if (imageReservedRows > 1 && imageReservedRows <= height) {
980
+ for (let row = 1; row < imageReservedRows; row++) {
981
+ buffer += "\r\n";
982
+ }
983
+ buffer += `\x1b[${imageReservedRows - 1}A`;
984
+ buffer += line;
985
+ buffer += `\x1b[${imageReservedRows - 1}B`;
986
+ i += imageReservedRows - 1;
987
+ continue;
988
+ }
989
+ buffer += line;
950
990
  }
951
991
  buffer += "\x1b[?2026l"; // End synchronized output
952
992
  this.terminal.write(buffer);
@@ -1275,5 +1315,31 @@ export class TUI extends Container {
1275
1315
  this.terminal.hideCursor();
1276
1316
  }
1277
1317
  }
1318
+ /**
1319
+ * Query the terminal's default background color with OSC 11 (`ESC ] 11 ; ? BEL`).
1320
+ * @param timeoutMs Query timeout in milliseconds.
1321
+ * @returns Promise containing the parsed RGB color, or undefined if it times out or fails to parse.
1322
+ */
1323
+ queryTerminalBackgroundColor({ timeoutMs }) {
1324
+ return new Promise((resolve) => {
1325
+ const query = {
1326
+ settled: false,
1327
+ resolve,
1328
+ timer: undefined,
1329
+ };
1330
+ query.timer = setTimeout(() => {
1331
+ if (query.settled) {
1332
+ return;
1333
+ }
1334
+ query.settled = true;
1335
+ query.timer = undefined;
1336
+ query.resolve?.(undefined);
1337
+ query.resolve = undefined;
1338
+ }, timeoutMs);
1339
+ this.pendingOsc11BackgroundQueries.push(query);
1340
+ this.pendingOsc11BackgroundReplies += 1;
1341
+ this.terminal.write("\x1b]11;?\x07");
1342
+ });
1343
+ }
1278
1344
  }
1279
1345
  //# sourceMappingURL=tui.js.map