gloomberb 0.9.4 → 0.9.5
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/package.json +3 -2
- package/patches/@opentui%2Fcore@0.3.2.patch +231 -29
- package/patches/react-reconciler@0.33.0.patch +10 -0
- package/src/cli/entry.ts +8 -1
- package/src/cli/native-smoke.ts +5 -0
- package/src/components/chart/native/bitmap-support.test.ts +27 -0
- package/src/components/chart/native/bitmap-support.ts +55 -0
- package/src/components/chart/native/kitty/index.test.ts +47 -0
- package/src/components/chart/native/surface/visibility.ts +8 -1
- package/src/components/chart/static/chart/bitmap.ts +16 -9
- package/src/components/command-bar/list/view.tsx +1 -1
- package/src/components/command-bar/theme-picker.tsx +1 -1
- package/src/components/data-table/view.tsx +0 -12
- package/src/components/layout/floating-pane.tsx +3 -3
- package/src/components/layout/pane/header.tsx +5 -0
- package/src/components/layout/pane/index.tsx +3 -3
- package/src/components/layout/shell/action-menu-overlay.tsx +1 -1
- package/src/components/layout/shell/cursor-occlusion.ts +9 -1
- package/src/components/layout/shell/index.tsx +8 -1
- package/src/components/layout/shell/pane/layers.tsx +2 -2
- package/src/components/layout/status-bar.tsx +5 -5
- package/src/components/pane-settings-dialog/desktop.tsx +1 -1
- package/src/components/price-performance.tsx +1 -1
- package/src/components/price-sparkline/view.tsx +15 -14
- package/src/components/speedometer-gauge/terminal.tsx +18 -15
- package/src/components/table-view-shared.tsx +0 -10
- package/src/components/ticker/list-table-view.tsx +1 -7
- package/src/components/ticker/list-table.test.tsx +0 -4
- package/src/components/ui/data-table/opentui/index.tsx +4 -10
- package/src/components/ui/data-table/types.ts +6 -4
- package/src/components/ui/list-view.tsx +1 -1
- package/src/components/ui/tabs.tsx +1 -2
- package/src/components/ui/ui.test.tsx +0 -9
- package/src/plugins/builtin/account-management/form-components.tsx +2 -2
- package/src/plugins/builtin/alerts/pane.tsx +1 -1
- package/src/plugins/builtin/buildout/cells.tsx +1 -1
- package/src/plugins/builtin/buildout/pane/index.tsx +1 -1
- package/src/plugins/builtin/chat/message/desktop.tsx +1 -1
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +1 -1
- package/src/plugins/builtin/chat/message/terminal.tsx +2 -2
- package/src/plugins/builtin/chat/sidebar.tsx +1 -1
- package/src/plugins/builtin/chat/status-widget.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-actions.tsx +2 -2
- package/src/plugins/builtin/correlation/matrix/symbol-cell.tsx +1 -1
- package/src/plugins/builtin/debug/index.tsx +3 -4
- package/src/plugins/builtin/help/components.tsx +1 -1
- package/src/plugins/builtin/holders/treemap.tsx +1 -1
- package/src/plugins/builtin/options/table.ts +5 -5
- package/src/plugins/ibkr/trade/ticket-panel.tsx +1 -1
- package/src/renderers/electrobun/view/data-table/index.tsx +0 -8
- package/src/renderers/electrobun/view/data-table/row.tsx +2 -12
- package/src/renderers/electrobun/view/host/box.tsx +6 -1
- package/src/renderers/electrobun/view/host/style.ts +1 -0
- package/src/renderers/electrobun/view/styles.css +7 -0
- package/src/renderers/opentui/native-smoke.ts +1 -0
- package/src/version.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gloomberb",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"description": "Market research and portfolio tracker for the terminal",
|
|
5
5
|
"module": "src/index.tsx",
|
|
6
6
|
"type": "module",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
},
|
|
64
64
|
"patchedDependencies": {
|
|
65
65
|
"@opentui/core@0.3.2": "patches/@opentui%2Fcore@0.3.2.patch",
|
|
66
|
-
"electrobun@1.18.1": "patches/electrobun@1.18.1.patch"
|
|
66
|
+
"electrobun@1.18.1": "patches/electrobun@1.18.1.patch",
|
|
67
|
+
"react-reconciler@0.33.0": "patches/react-reconciler@0.33.0.patch"
|
|
67
68
|
}
|
|
68
69
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
diff --git a/index-218h9p3f.js b/index-218h9p3f.js
|
|
2
|
-
index b9445d2cca9477dfe06026da451b6d19268fcbdd..
|
|
2
|
+
index b9445d2cca9477dfe06026da451b6d19268fcbdd..da790c31da185325405227329dad2ac12f5329e7 100644
|
|
3
3
|
--- a/index-218h9p3f.js
|
|
4
4
|
+++ b/index-218h9p3f.js
|
|
5
5
|
@@ -6487,17 +6487,27 @@ class MouseParser {
|
|
@@ -210,7 +210,101 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
210
210
|
}
|
|
211
211
|
throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`);
|
|
212
212
|
}
|
|
213
|
-
@@ -
|
|
213
|
+
@@ -17996,5 +18031,7 @@ function isGapType(value) {
|
|
214
|
+
class BoxRenderable extends Renderable {
|
|
215
|
+
_backgroundColor;
|
|
216
|
+
+ _hoverBackgroundColor;
|
|
217
|
+
+ _isHovered = false;
|
|
218
|
+
_border;
|
|
219
|
+
_borderStyle;
|
|
220
|
+
_borderColor;
|
|
221
|
+
@@ -18023,6 +18060,7 @@ class BoxRenderable extends Renderable {
|
|
222
|
+
this._focusable = true;
|
|
223
|
+
}
|
|
224
|
+
this._backgroundColor = parseColor(options.backgroundColor || this._defaultOptions.backgroundColor);
|
|
225
|
+
+ this._hoverBackgroundColor = options.hoverBackgroundColor === undefined ? undefined : parseColor(options.hoverBackgroundColor);
|
|
226
|
+
this._border = options.border ?? this._defaultOptions.border;
|
|
227
|
+
if (!options.border && (options.borderStyle || options.borderColor || options.focusedBorderColor || options.customBorderChars)) {
|
|
228
|
+
this._border = true;
|
|
229
|
+
@@ -18064,11 +18102,26 @@ class BoxRenderable extends Renderable {
|
|
230
|
+
}
|
|
231
|
+
set backgroundColor(value) {
|
|
232
|
+
const newColor = parseColor(value ?? this._defaultOptions.backgroundColor);
|
|
233
|
+
- if (this._backgroundColor !== newColor) {
|
|
234
|
+
+ if (!this._backgroundColor.equals(newColor)) {
|
|
235
|
+
this._backgroundColor = newColor;
|
|
236
|
+
this.requestRender();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
+ get hoverBackgroundColor() {
|
|
240
|
+
+ return this._hoverBackgroundColor;
|
|
241
|
+
+ }
|
|
242
|
+
+ set hoverBackgroundColor(value) {
|
|
243
|
+
+ const newColor = value === undefined || value === null ? undefined : parseColor(value);
|
|
244
|
+
+ const changed = newColor === undefined
|
|
245
|
+
+ ? this._hoverBackgroundColor !== undefined
|
|
246
|
+
+ : !this._hoverBackgroundColor?.equals(newColor);
|
|
247
|
+
+ if (changed) {
|
|
248
|
+
+ this._hoverBackgroundColor = newColor;
|
|
249
|
+
+ if (this._isHovered) {
|
|
250
|
+
+ this.requestRender();
|
|
251
|
+
+ }
|
|
252
|
+
+ }
|
|
253
|
+
+ }
|
|
254
|
+
get border() {
|
|
255
|
+
return this._border;
|
|
256
|
+
}
|
|
257
|
+
@@ -18152,9 +18205,39 @@ class BoxRenderable extends Renderable {
|
|
258
|
+
this.requestRender();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
+ onMouseEvent(event) {
|
|
262
|
+
+ if (!this._hoverBackgroundColor) {
|
|
263
|
+
+ if (this._isHovered) {
|
|
264
|
+
+ this._isHovered = false;
|
|
265
|
+
+ this.requestRender();
|
|
266
|
+
+ }
|
|
267
|
+
+ return;
|
|
268
|
+
+ }
|
|
269
|
+
+ if (event.type === "over" && !this._isHovered) {
|
|
270
|
+
+ this._isHovered = true;
|
|
271
|
+
+ this.requestRender();
|
|
272
|
+
+ } else if (event.type === "out" && this._isHovered) {
|
|
273
|
+
+ this._isHovered = false;
|
|
274
|
+
+ this.requestRender();
|
|
275
|
+
+ }
|
|
276
|
+
+ }
|
|
277
|
+
+ getActiveHoverBackgroundColor() {
|
|
278
|
+
+ if (this._isHovered && this._hoverBackgroundColor) {
|
|
279
|
+
+ return this._hoverBackgroundColor;
|
|
280
|
+
+ }
|
|
281
|
+
+ let parent = this.parent;
|
|
282
|
+
+ while (parent) {
|
|
283
|
+
+ if (parent instanceof BoxRenderable && parent._isHovered && parent._hoverBackgroundColor) {
|
|
284
|
+
+ return parent._hoverBackgroundColor;
|
|
285
|
+
+ }
|
|
286
|
+
+ parent = parent.parent;
|
|
287
|
+
+ }
|
|
288
|
+
+ return undefined;
|
|
289
|
+
+ }
|
|
290
|
+
renderSelf(buffer) {
|
|
291
|
+
const hasBorder = this.borderSides.top || this.borderSides.right || this.borderSides.bottom || this.borderSides.left;
|
|
292
|
+
- const hasVisibleFill = this.shouldFill && this._backgroundColor.a > 0;
|
|
293
|
+
+ const backgroundColor = this.getActiveHoverBackgroundColor() ?? this._backgroundColor;
|
|
294
|
+
+ const hasVisibleFill = this.shouldFill && backgroundColor.a > 0;
|
|
295
|
+
if (!hasBorder && !hasVisibleFill) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
@@ -18171,7 +18254,7 @@ class BoxRenderable extends Renderable {
|
|
299
|
+
customBorderChars: this._customBorderChars,
|
|
300
|
+
border: this._border,
|
|
301
|
+
borderColor: currentBorderColor,
|
|
302
|
+
- backgroundColor: this._backgroundColor,
|
|
303
|
+
+ backgroundColor,
|
|
304
|
+
shouldFill: this.shouldFill,
|
|
305
|
+
title: this._title,
|
|
306
|
+
titleAlignment: this._titleAlignment,
|
|
307
|
+
@@ -22288,6 +22371,8 @@ class MouseEvent {
|
|
214
308
|
button;
|
|
215
309
|
x;
|
|
216
310
|
y;
|
|
@@ -219,7 +313,7 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
219
313
|
source;
|
|
220
314
|
modifiers;
|
|
221
315
|
scroll;
|
|
222
|
-
@@ -22307,6 +
|
|
316
|
+
@@ -22307,6 +22392,8 @@ class MouseEvent {
|
|
223
317
|
this.button = attributes.button;
|
|
224
318
|
this.x = attributes.x;
|
|
225
319
|
this.y = attributes.y;
|
|
@@ -228,16 +322,18 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
228
322
|
this.modifiers = attributes.modifiers;
|
|
229
323
|
this.scroll = attributes.scroll;
|
|
230
324
|
this.source = attributes.source;
|
|
231
|
-
@@ -22457,6 +
|
|
325
|
+
@@ -22457,6 +22544,10 @@ class CliRenderer extends EventEmitter9 {
|
|
232
326
|
resizeDebounceDelay = 100;
|
|
233
327
|
enableMouseMovement = false;
|
|
234
328
|
_useMouse = true;
|
|
235
329
|
+ _mouseProtocolSignature = "disabled";
|
|
236
330
|
+ _pixelMouseEnabled = false;
|
|
331
|
+
+ _pendingMouseMoveEvent = null;
|
|
332
|
+
+ _pendingMouseMoveTimer = null;
|
|
237
333
|
autoFocus = true;
|
|
238
334
|
_screenMode = "alternate-screen";
|
|
239
335
|
_footerHeight = DEFAULT_FOOTER_HEIGHT;
|
|
240
|
-
@@ -22491,7 +
|
|
336
|
+
@@ -22491,7 +22582,7 @@ class CliRenderer extends EventEmitter9 {
|
|
241
337
|
this.handleResize(width, height);
|
|
242
338
|
}).bind(this);
|
|
243
339
|
_capabilities = null;
|
|
@@ -246,7 +342,7 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
246
342
|
_hasPointer = false;
|
|
247
343
|
_lastPointerModifiers = {
|
|
248
344
|
shift: false,
|
|
249
|
-
@@ -22738,7 +
|
|
345
|
+
@@ -22738,7 +22829,13 @@ Captured external output:
|
|
250
346
|
privateCapabilityRepliesActive: false,
|
|
251
347
|
pixelResolutionQueryActive: false,
|
|
252
348
|
explicitWidthCprActive: false,
|
|
@@ -261,7 +357,7 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
261
357
|
},
|
|
262
358
|
clock: this.clock
|
|
263
359
|
});
|
|
264
|
-
@@ -24021,12 +
|
|
360
|
+
@@ -24021,12 +24118,14 @@ Captured external output:
|
|
265
361
|
enableMouse() {
|
|
266
362
|
this._useMouse = true;
|
|
267
363
|
this.lib.enableMouse(this.rendererPtr, this.enableMouseMovement);
|
|
@@ -276,7 +372,7 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
276
372
|
}
|
|
277
373
|
enableKittyKeyboard(flags = 3) {
|
|
278
374
|
this.lib.enableKittyKeyboard(this.rendererPtr, flags);
|
|
279
|
-
@@ -24036,6 +
|
|
375
|
+
@@ -24036,6 +24135,52 @@ Captured external output:
|
|
280
376
|
this.lib.disableKittyKeyboard(this.rendererPtr);
|
|
281
377
|
this.updateStdinParserProtocolContext({ kittyKeyboardEnabled: false }, true);
|
|
282
378
|
}
|
|
@@ -329,7 +425,7 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
329
425
|
set useThread(useThread) {
|
|
330
426
|
this._useThread = useThread;
|
|
331
427
|
this.lib.setUseThread(this.rendererPtr, useThread);
|
|
332
|
-
@@ -24141,6 +
|
|
428
|
+
@@ -24141,6 +24286,7 @@ Captured external output:
|
|
333
429
|
}
|
|
334
430
|
this.lib.processCapabilityResponse(this.rendererPtr, sequence);
|
|
335
431
|
this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
|
|
@@ -337,7 +433,7 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
337
433
|
if (this._capabilities?.terminal?.from_xtversion) {
|
|
338
434
|
this.resolveXtVersionWaiters();
|
|
339
435
|
}
|
|
340
|
-
@@ -24170,6 +
|
|
436
|
+
@@ -24170,6 +24316,7 @@ Captured external output:
|
|
341
437
|
if (sequence === "\x1B[I") {
|
|
342
438
|
if (this.shouldRestoreModesOnNextFocus) {
|
|
343
439
|
this.lib.restoreTerminalModes(this.rendererPtr);
|
|
@@ -345,7 +441,16 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
345
441
|
this.shouldRestoreModesOnNextFocus = false;
|
|
346
442
|
}
|
|
347
443
|
if (this._terminalFocusState !== true) {
|
|
348
|
-
@@ -
|
|
444
|
+
@@ -24218,7 +24365,7 @@ Captured external output:
|
|
445
|
+
this._keyHandler.processParsedKey(event.key);
|
|
446
|
+
return;
|
|
447
|
+
case "mouse":
|
|
448
|
+
- if (this._useMouse && this.processSingleMouseEvent(event.event)) {
|
|
449
|
+
+ if (this._useMouse && this.processMouseEvent(event.event)) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
this.dispatchSequenceHandlers(event.raw);
|
|
453
|
+
@@ -24264,6 +24411,7 @@ Captured external output:
|
|
349
454
|
}
|
|
350
455
|
this.waitingForPixelResolution = false;
|
|
351
456
|
this.updateStdinParserProtocolContext({ pixelResolutionQueryActive: false }, true);
|
|
@@ -353,7 +458,54 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
353
458
|
return true;
|
|
354
459
|
}
|
|
355
460
|
return false;
|
|
356
|
-
@@ -
|
|
461
|
+
@@ -24292,15 +24440,62 @@ Captured external output:
|
|
462
|
+
}
|
|
463
|
+
return event;
|
|
464
|
+
}
|
|
465
|
+
+ cloneMouseEventAttributes(mouseEvent) {
|
|
466
|
+
+ return {
|
|
467
|
+
+ ...mouseEvent,
|
|
468
|
+
+ modifiers: { ...mouseEvent.modifiers }
|
|
469
|
+
+ };
|
|
470
|
+
+ }
|
|
471
|
+
+ processMouseEvent(mouseEvent) {
|
|
472
|
+
+ if (mouseEvent.type !== "move") {
|
|
473
|
+
+ this.flushPendingMouseMove();
|
|
474
|
+
+ return this.processSingleMouseEvent(mouseEvent);
|
|
475
|
+
+ }
|
|
476
|
+
+ if (this._pendingMouseMoveTimer === null) {
|
|
477
|
+
+ const handled = this.processSingleMouseEvent(mouseEvent);
|
|
478
|
+
+ this.schedulePendingMouseMove();
|
|
479
|
+
+ return handled;
|
|
480
|
+
+ }
|
|
481
|
+
+ this._pendingMouseMoveEvent = this.cloneMouseEventAttributes(mouseEvent);
|
|
482
|
+
+ return true;
|
|
483
|
+
+ }
|
|
484
|
+
+ schedulePendingMouseMove() {
|
|
485
|
+
+ if (this._pendingMouseMoveTimer !== null || this._isDestroyed) {
|
|
486
|
+
+ return;
|
|
487
|
+
+ }
|
|
488
|
+
+ const delay = Math.max(100, Math.floor(this.targetFrameTime));
|
|
489
|
+
+ this._pendingMouseMoveTimer = this.clock.setTimeout(() => {
|
|
490
|
+
+ this._pendingMouseMoveTimer = null;
|
|
491
|
+
+ this.flushPendingMouseMove();
|
|
492
|
+
+ }, delay);
|
|
493
|
+
+ }
|
|
494
|
+
+ flushPendingMouseMove() {
|
|
495
|
+
+ if (this._pendingMouseMoveTimer !== null) {
|
|
496
|
+
+ this.clock.clearTimeout(this._pendingMouseMoveTimer);
|
|
497
|
+
+ this._pendingMouseMoveTimer = null;
|
|
498
|
+
+ }
|
|
499
|
+
+ const pending = this._pendingMouseMoveEvent;
|
|
500
|
+
+ this._pendingMouseMoveEvent = null;
|
|
501
|
+
+ if (!pending || this._isDestroyed) {
|
|
502
|
+
+ return false;
|
|
503
|
+
+ }
|
|
504
|
+
+ return this.processSingleMouseEvent(pending);
|
|
505
|
+
+ }
|
|
506
|
+
processSingleMouseEvent(mouseEvent) {
|
|
507
|
+
if (this._splitHeight > 0) {
|
|
508
|
+
if (mouseEvent.y < this.renderOffset) {
|
|
357
509
|
return false;
|
|
358
510
|
}
|
|
359
511
|
mouseEvent.y -= this.renderOffset;
|
|
@@ -369,31 +521,43 @@ index b9445d2cca9477dfe06026da451b6d19268fcbdd..3efd05fa41eb713ac6e539764b15c346
|
|
|
369
521
|
this._hasPointer = true;
|
|
370
522
|
this._lastPointerModifiers = mouseEvent.modifiers;
|
|
371
523
|
if (this._console.visible) {
|
|
372
|
-
@@ -
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
524
|
+
@@ -24437,6 +24632,8 @@ Captured external output:
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
const baseEvent = {
|
|
376
528
|
+ pixelX: this._latestPointer.pixelX,
|
|
377
529
|
+ pixelY: this._latestPointer.pixelY,
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
@@ -
|
|
530
|
+
type: "move",
|
|
531
|
+
button: 0,
|
|
532
|
+
x: this._latestPointer.x,
|
|
533
|
+
@@ -24527,6 +24724,7 @@ Captured external output:
|
|
534
|
+
const pendingSplitFooterTransition = this.pendingSplitFooterTransition;
|
|
535
|
+
const previousGeometry = calculateRenderGeometry(this._screenMode, this._terminalWidth, this._terminalHeight, this._footerHeight);
|
|
536
|
+
const prevWidth = this._terminalWidth;
|
|
537
|
+
+ this.syncPixelMouseMode();
|
|
538
|
+
const previousTerminalHeight = this._terminalHeight;
|
|
382
539
|
const visiblePreviousSplitHeight = pendingSplitFooterTransition?.sourceHeight ?? previousGeometry.effectiveFooterHeight;
|
|
383
540
|
this._terminalWidth = width;
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
541
|
+
@@ -24832,6 +25030,11 @@ Captured external output:
|
|
542
|
+
this.clock.clearTimeout(this.resizeTimeoutId);
|
|
543
|
+
this.resizeTimeoutId = null;
|
|
544
|
+
}
|
|
545
|
+
+ if (this._pendingMouseMoveTimer !== null) {
|
|
546
|
+
+ this.clock.clearTimeout(this._pendingMouseMoveTimer);
|
|
547
|
+
+ this._pendingMouseMoveTimer = null;
|
|
548
|
+
+ }
|
|
549
|
+
+ this._pendingMouseMoveEvent = null;
|
|
550
|
+
if (this.capabilityTimeoutId !== null) {
|
|
551
|
+
this.clock.clearTimeout(this.capabilityTimeoutId);
|
|
552
|
+
this.capabilityTimeoutId = null;
|
|
553
|
+
@@ -24847,6 +25050,7 @@ Captured external output:
|
|
554
|
+
this.renderTimeout = null;
|
|
555
|
+
}
|
|
390
556
|
this.themeModeState.cancelRefresh();
|
|
557
|
+
+ this.disablePixelMouseMode();
|
|
391
558
|
this._isRunning = false;
|
|
392
559
|
this.waitingForPixelResolution = false;
|
|
393
|
-
+ this.disablePixelMouseMode();
|
|
394
560
|
this.updateStdinParserProtocolContext({
|
|
395
|
-
privateCapabilityRepliesActive: false,
|
|
396
|
-
pixelResolutionQueryActive: false,
|
|
397
561
|
diff --git a/lib/parse.mouse.d.ts b/lib/parse.mouse.d.ts
|
|
398
562
|
index c29f953fde0b78f09d2ec7a830e5a72452c1fe7e..04613b921bd9b4a9a7a1a4fbd0234d4012df67a1 100644
|
|
399
563
|
--- a/lib/parse.mouse.d.ts
|
|
@@ -450,6 +614,44 @@ index 6b733d534d8e9b77c5c2773f93c7a22063c18d84..a5c318d591e9f3775e276e555c15052c
|
|
|
450
614
|
}
|
|
451
615
|
export interface StdinParserOptions {
|
|
452
616
|
timeoutMs?: number;
|
|
617
|
+
diff --git a/renderables/Box.d.ts b/renderables/Box.d.ts
|
|
618
|
+
index 7ecb70d38ca41d1afdc078780985827e8f10e3a7..0845141e20ebd71a163dba67880d494a05b27d9a 100644
|
|
619
|
+
--- a/renderables/Box.d.ts
|
|
620
|
+
+++ b/renderables/Box.d.ts
|
|
621
|
+
@@ -5,6 +5,7 @@ import { type ColorInput, RGBA } from "../lib/RGBA.js";
|
|
622
|
+
import type { RenderContext } from "../types.js";
|
|
623
|
+
export interface BoxOptions<TRenderable extends Renderable = BoxRenderable> extends RenderableOptions<TRenderable> {
|
|
624
|
+
backgroundColor?: string | RGBA;
|
|
625
|
+
+ hoverBackgroundColor?: string | RGBA;
|
|
626
|
+
borderStyle?: BorderStyle;
|
|
627
|
+
border?: boolean | BorderSides[];
|
|
628
|
+
borderColor?: string | RGBA;
|
|
629
|
+
@@ -22,6 +23,8 @@ export interface BoxOptions<TRenderable extends Renderable = BoxRenderable> exte
|
|
630
|
+
}
|
|
631
|
+
export declare class BoxRenderable extends Renderable {
|
|
632
|
+
protected _backgroundColor: RGBA;
|
|
633
|
+
+ protected _hoverBackgroundColor?: RGBA;
|
|
634
|
+
+ protected _isHovered: boolean;
|
|
635
|
+
protected _border: boolean | BorderSides[];
|
|
636
|
+
protected _borderStyle: BorderStyle;
|
|
637
|
+
protected _borderColor: RGBA;
|
|
638
|
+
@@ -50,6 +53,8 @@ export declare class BoxRenderable extends Renderable {
|
|
639
|
+
set customBorderChars(value: BorderCharacters | undefined);
|
|
640
|
+
get backgroundColor(): RGBA;
|
|
641
|
+
set backgroundColor(value: RGBA | string | undefined);
|
|
642
|
+
+ get hoverBackgroundColor(): RGBA | undefined;
|
|
643
|
+
+ set hoverBackgroundColor(value: RGBA | string | undefined);
|
|
644
|
+
get border(): boolean | BorderSides[];
|
|
645
|
+
set border(value: boolean | BorderSides[]);
|
|
646
|
+
get borderStyle(): BorderStyle;
|
|
647
|
+
@@ -66,6 +71,7 @@ export declare class BoxRenderable extends Renderable {
|
|
648
|
+
set bottomTitle(value: string | undefined);
|
|
649
|
+
get bottomTitleAlignment(): "left" | "center" | "right";
|
|
650
|
+
set bottomTitleAlignment(value: "left" | "center" | "right");
|
|
651
|
+
+ protected getActiveHoverBackgroundColor(): RGBA | undefined;
|
|
652
|
+
protected renderSelf(buffer: OptimizedBuffer): void;
|
|
653
|
+
protected getScissorRect(): {
|
|
654
|
+
x: number;
|
|
453
655
|
diff --git a/renderer.d.ts b/renderer.d.ts
|
|
454
656
|
index 96189246f423809fc52d2ad182d57ed2e80ac098..7dd0baf1697041cf8ad556b115cd13ad2e18bc65 100644
|
|
455
657
|
--- a/renderer.d.ts
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
diff --git a/cjs/react-reconciler.development.js b/cjs/react-reconciler.development.js
|
|
2
|
+
--- a/cjs/react-reconciler.development.js
|
|
3
|
+
+++ b/cjs/react-reconciler.development.js
|
|
4
|
+
@@ -17213,5 +17213,6 @@
|
|
5
|
+
hasOwnProperty = Object.prototype.hasOwnProperty,
|
|
6
|
+
supportsUserTiming =
|
|
7
|
+
+ "undefined" !== typeof window &&
|
|
8
|
+
"undefined" !== typeof console &&
|
|
9
|
+
"function" === typeof console.timeStamp &&
|
|
10
|
+
"undefined" !== typeof performance &&
|
package/src/cli/entry.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { dispatchCli } from "./index";
|
|
|
2
2
|
import { fail, inferCliErrorOptions, printCliError } from "./errors";
|
|
3
3
|
import { loadExternalPlugins } from "../plugins/loader";
|
|
4
4
|
import type { CliLaunchRequest } from "../types/plugin";
|
|
5
|
+
import { OPEN_TUI_NATIVE_SMOKE_COMMAND, smokeOpenTuiNative } from "./native-smoke";
|
|
5
6
|
|
|
6
7
|
async function launchOpenTuiApp(options: {
|
|
7
8
|
externalPlugins: Awaited<ReturnType<typeof loadExternalPlugins>>;
|
|
@@ -18,9 +19,15 @@ async function launchOpenTuiApp(options: {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export async function runCliEntrypoint(rawArgs = process.argv.slice(2)): Promise<void> {
|
|
21
|
-
const externalPlugins = await loadExternalPlugins();
|
|
22
22
|
const command = rawArgs[0];
|
|
23
23
|
|
|
24
|
+
if (command === OPEN_TUI_NATIVE_SMOKE_COMMAND) {
|
|
25
|
+
await smokeOpenTuiNative();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const externalPlugins = await loadExternalPlugins();
|
|
30
|
+
|
|
24
31
|
if (!command) {
|
|
25
32
|
await launchOpenTuiApp({ externalPlugins });
|
|
26
33
|
return;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import type { NativeRendererHost } from "../../../ui";
|
|
3
|
+
import { shouldRenderNativeBitmap } from "./bitmap-support";
|
|
4
|
+
|
|
5
|
+
function rendererWithCapabilities(capabilities: unknown): NativeRendererHost {
|
|
6
|
+
return {
|
|
7
|
+
terminalWidth: 80,
|
|
8
|
+
terminalHeight: 24,
|
|
9
|
+
resolution: null,
|
|
10
|
+
capabilities,
|
|
11
|
+
on() {},
|
|
12
|
+
off() {},
|
|
13
|
+
requestRender() {},
|
|
14
|
+
registerLifecyclePass() {},
|
|
15
|
+
unregisterLifecyclePass() {},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe("shouldRenderNativeBitmap", () => {
|
|
20
|
+
test("skips native bitmaps only when kitty graphics are known unsupported", () => {
|
|
21
|
+
expect(shouldRenderNativeBitmap(rendererWithCapabilities({ kitty_graphics: false }), true)).toBe(false);
|
|
22
|
+
expect(shouldRenderNativeBitmap(rendererWithCapabilities({ kitty_graphics: true }), true)).toBe(true);
|
|
23
|
+
expect(shouldRenderNativeBitmap(rendererWithCapabilities(null), true)).toBe(true);
|
|
24
|
+
expect(shouldRenderNativeBitmap(rendererWithCapabilities({}), true)).toBe(true);
|
|
25
|
+
expect(shouldRenderNativeBitmap(rendererWithCapabilities({ kitty_graphics: true }), false)).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { NativeRendererHost, PixelResolution } from "../../../ui";
|
|
2
|
+
import { computeBitmapSize } from "./chart-rasterizer";
|
|
3
|
+
|
|
4
|
+
interface NativeBitmapRendererCapabilities {
|
|
5
|
+
kitty_graphics?: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface NativeBitmapSize {
|
|
9
|
+
pixelWidth: number;
|
|
10
|
+
pixelHeight: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function hasKnownUnsupportedKittyGraphics(renderer: NativeRendererHost): boolean {
|
|
14
|
+
const capabilities = renderer.capabilities as NativeBitmapRendererCapabilities | null | undefined;
|
|
15
|
+
return capabilities?.kitty_graphics === false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function shouldRenderNativeBitmap(renderer: NativeRendererHost, nativeCharts: boolean): boolean {
|
|
19
|
+
return nativeCharts && !hasKnownUnsupportedKittyGraphics(renderer);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function resolveNativeBitmapSize({
|
|
23
|
+
width,
|
|
24
|
+
height,
|
|
25
|
+
resolution,
|
|
26
|
+
terminalWidth,
|
|
27
|
+
terminalHeight,
|
|
28
|
+
cellWidthPx,
|
|
29
|
+
cellHeightPx,
|
|
30
|
+
pixelRatio,
|
|
31
|
+
}: {
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
resolution: PixelResolution | null;
|
|
35
|
+
terminalWidth: number;
|
|
36
|
+
terminalHeight: number;
|
|
37
|
+
cellWidthPx: number;
|
|
38
|
+
cellHeightPx: number;
|
|
39
|
+
pixelRatio: number;
|
|
40
|
+
}): NativeBitmapSize {
|
|
41
|
+
if (resolution && terminalWidth > 0 && terminalHeight > 0) {
|
|
42
|
+
return computeBitmapSize(
|
|
43
|
+
{ x: 0, y: 0, width, height },
|
|
44
|
+
resolution,
|
|
45
|
+
terminalWidth,
|
|
46
|
+
terminalHeight,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const scale = Math.max(1, pixelRatio);
|
|
51
|
+
return {
|
|
52
|
+
pixelWidth: Math.max(1, Math.round(width * cellWidthPx * scale)),
|
|
53
|
+
pixelHeight: Math.max(1, Math.round(height * cellHeightPx * scale)),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -143,6 +143,53 @@ describe("resolveNativeSurfaceVisibleRect", () => {
|
|
|
143
143
|
|
|
144
144
|
expect(resolveNativeSurfaceVisibleRect(child, 100, 30)).toBeNull();
|
|
145
145
|
});
|
|
146
|
+
|
|
147
|
+
test("stops at repeated ancestors in cyclic native renderable trees", () => {
|
|
148
|
+
const root: NativeSurfaceRenderableNode = {
|
|
149
|
+
x: 0,
|
|
150
|
+
y: 0,
|
|
151
|
+
width: 100,
|
|
152
|
+
height: 30,
|
|
153
|
+
parent: null,
|
|
154
|
+
};
|
|
155
|
+
const child: NativeSurfaceRenderableNode = {
|
|
156
|
+
x: 2,
|
|
157
|
+
y: 3,
|
|
158
|
+
width: 20,
|
|
159
|
+
height: 8,
|
|
160
|
+
parent: root,
|
|
161
|
+
};
|
|
162
|
+
root.parent = child;
|
|
163
|
+
|
|
164
|
+
expect(resolveNativeSurfaceVisibleRect(child, 100, 30)).toEqual({
|
|
165
|
+
x: 2,
|
|
166
|
+
y: 3,
|
|
167
|
+
width: 20,
|
|
168
|
+
height: 8,
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
test("fails closed when native renderable ancestors exceed a sane depth", () => {
|
|
173
|
+
let node: NativeSurfaceRenderableNode = {
|
|
174
|
+
x: 0,
|
|
175
|
+
y: 0,
|
|
176
|
+
width: 100,
|
|
177
|
+
height: 30,
|
|
178
|
+
parent: null,
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
for (let index = 0; index < 300; index += 1) {
|
|
182
|
+
node = {
|
|
183
|
+
x: 0,
|
|
184
|
+
y: 0,
|
|
185
|
+
width: 100,
|
|
186
|
+
height: 30,
|
|
187
|
+
parent: node,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
expect(resolveNativeSurfaceVisibleRect(node, 100, 30)).toBeNull();
|
|
192
|
+
});
|
|
146
193
|
});
|
|
147
194
|
|
|
148
195
|
describe("renderNativeChartBase", () => {
|
|
@@ -9,6 +9,8 @@ export interface NativeSurfaceRenderableNode {
|
|
|
9
9
|
parent: NativeSurfaceRenderableNode | null;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
const MAX_RENDERABLE_ANCESTOR_DEPTH = 256;
|
|
13
|
+
|
|
12
14
|
export function getRenderableCellRect(
|
|
13
15
|
renderable: Pick<NativeSurfaceRenderableNode, "x" | "y" | "width" | "height">,
|
|
14
16
|
): CellRect {
|
|
@@ -34,8 +36,13 @@ export function resolveNativeSurfaceVisibleRect(
|
|
|
34
36
|
height: terminalHeight,
|
|
35
37
|
};
|
|
36
38
|
let current: NativeSurfaceRenderableNode | null = renderable;
|
|
39
|
+
const seen = new Set<NativeSurfaceRenderableNode>();
|
|
40
|
+
let depth = 0;
|
|
37
41
|
|
|
38
|
-
while (current) {
|
|
42
|
+
while (current && !seen.has(current)) {
|
|
43
|
+
if (depth >= MAX_RENDERABLE_ANCESTOR_DEPTH) return null;
|
|
44
|
+
seen.add(current);
|
|
45
|
+
depth += 1;
|
|
39
46
|
if (current.visible === false) return null;
|
|
40
47
|
|
|
41
48
|
const nextVisible = intersectCellRects(visible, getRenderableCellRect(current));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import { useNativeRenderer, useUiCapabilities } from "../../../../ui";
|
|
3
|
-
import {
|
|
3
|
+
import { resolveNativeBitmapSize, shouldRenderNativeBitmap } from "../../native/bitmap-support";
|
|
4
4
|
|
|
5
5
|
export interface StaticChartBitmapSize {
|
|
6
6
|
pixelWidth: number;
|
|
@@ -16,20 +16,25 @@ export function useStaticChartBitmapSize(width: number, height: number): StaticC
|
|
|
16
16
|
pixelRatio = 1,
|
|
17
17
|
} = useUiCapabilities();
|
|
18
18
|
const nativeRenderer = useNativeRenderer();
|
|
19
|
+
const rendererCapabilities = nativeRenderer.capabilities;
|
|
19
20
|
const rendererResolution = nativeRenderer.resolution;
|
|
20
21
|
const rendererTerminalWidth = nativeRenderer.terminalWidth;
|
|
21
22
|
const rendererTerminalHeight = nativeRenderer.terminalHeight;
|
|
22
23
|
|
|
23
24
|
return useMemo(() => {
|
|
24
|
-
if (nativeCharts
|
|
25
|
-
return
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
if (shouldRenderNativeBitmap(nativeRenderer, nativeCharts === true)) {
|
|
26
|
+
return resolveNativeBitmapSize({
|
|
27
|
+
width,
|
|
28
|
+
height,
|
|
29
|
+
resolution: rendererResolution,
|
|
30
|
+
terminalWidth: rendererTerminalWidth,
|
|
31
|
+
terminalHeight: rendererTerminalHeight,
|
|
32
|
+
cellWidthPx,
|
|
33
|
+
cellHeightPx,
|
|
34
|
+
pixelRatio,
|
|
35
|
+
});
|
|
31
36
|
}
|
|
32
|
-
if (!canvasCharts
|
|
37
|
+
if (!canvasCharts) return null;
|
|
33
38
|
const scale = Math.max(1, pixelRatio);
|
|
34
39
|
return {
|
|
35
40
|
pixelWidth: Math.max(1, Math.round(width * cellWidthPx * scale)),
|
|
@@ -41,7 +46,9 @@ export function useStaticChartBitmapSize(width: number, height: number): StaticC
|
|
|
41
46
|
cellWidthPx,
|
|
42
47
|
height,
|
|
43
48
|
nativeCharts,
|
|
49
|
+
nativeRenderer,
|
|
44
50
|
pixelRatio,
|
|
51
|
+
rendererCapabilities,
|
|
45
52
|
rendererResolution,
|
|
46
53
|
rendererTerminalHeight,
|
|
47
54
|
rendererTerminalWidth,
|
|
@@ -165,7 +165,7 @@ const CommandBarListItemRow = memo(function CommandBarListItemRow({
|
|
|
165
165
|
: isHovered
|
|
166
166
|
? paletteHoverBg
|
|
167
167
|
: (nativePaneChrome ? panelBg : paletteBg)}
|
|
168
|
-
|
|
168
|
+
onMouseOver={() => onHoverIndex(globalIdx)}
|
|
169
169
|
onMouseOut={() => onHoverIndex(null)}
|
|
170
170
|
{...(!nativePaneChrome ? { onMouseScroll: onListScroll } : {})}
|
|
171
171
|
onMouseDown={(event: any) => onRowMouseDown(event, item, globalIdx)}
|
|
@@ -219,7 +219,7 @@ export const ThemePicker = memo(forwardRef<ThemePickerHandle, ThemePickerProps>(
|
|
|
219
219
|
: hovered
|
|
220
220
|
? paletteHoverBg
|
|
221
221
|
: (nativePaneChrome ? panelBg : paletteBg)}
|
|
222
|
-
|
|
222
|
+
onMouseOver={() => setHoveredIndex(index)}
|
|
223
223
|
onMouseOut={() => setHoveredIndex(null)}
|
|
224
224
|
onMouseDown={(event: any) => {
|
|
225
225
|
event.stopPropagation?.();
|