@tutti-os/workbench-surface 0.0.48 → 0.0.50
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/index.d.ts +4 -0
- package/dist/index.js +477 -39
- package/dist/index.js.map +1 -1
- package/dist/styles/workbench.css +7 -7
- package/dist/styles/workbenchStyle.test.ts +4 -0
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -451,6 +451,10 @@ interface WorkbenchHostLaunchResult {
|
|
|
451
451
|
payload?: unknown;
|
|
452
452
|
type: string;
|
|
453
453
|
} | null;
|
|
454
|
+
cascadeOffset?: {
|
|
455
|
+
x: number;
|
|
456
|
+
y: number;
|
|
457
|
+
};
|
|
454
458
|
defaultFrame?: WorkbenchFrame;
|
|
455
459
|
displayMode?: WorkbenchDisplayMode;
|
|
456
460
|
dockEntryId?: string;
|
package/dist/index.js
CHANGED
|
@@ -5270,7 +5270,14 @@ function createWorkbenchSnapshotFromState(state, options = {}) {
|
|
|
5270
5270
|
|
|
5271
5271
|
// src/core/placement.ts
|
|
5272
5272
|
var WORKBENCH_WINDOW_CASCADE_OFFSET = 28;
|
|
5273
|
+
var WORKBENCH_WINDOW_CASCADE_FALLBACK_LIMIT = 12;
|
|
5274
|
+
var WORKBENCH_WINDOW_CASCADE_POSITION_TOLERANCE = 4;
|
|
5273
5275
|
function resolveWorkbenchCascadedRect(input) {
|
|
5276
|
+
const hasCustomCascadeOffset = input.cascadeOffset !== void 0;
|
|
5277
|
+
const cascadeOffset = input.cascadeOffset ?? {
|
|
5278
|
+
x: WORKBENCH_WINDOW_CASCADE_OFFSET,
|
|
5279
|
+
y: WORKBENCH_WINDOW_CASCADE_OFFSET
|
|
5280
|
+
};
|
|
5274
5281
|
const activeNode = input.existingNodes.find(
|
|
5275
5282
|
(node) => node.id === input.currentNodeStack.at(-1)
|
|
5276
5283
|
) ?? input.existingNodes.at(-1);
|
|
@@ -5282,17 +5289,119 @@ function resolveWorkbenchCascadedRect(input) {
|
|
|
5282
5289
|
input.sizeConstraints
|
|
5283
5290
|
);
|
|
5284
5291
|
}
|
|
5292
|
+
const preferredCandidate = createWorkbenchCascadeCandidate({
|
|
5293
|
+
input,
|
|
5294
|
+
x: activeNode.frame.x + cascadeOffset.x,
|
|
5295
|
+
y: activeNode.frame.y + cascadeOffset.y
|
|
5296
|
+
});
|
|
5297
|
+
if ((!hasCustomCascadeOffset || input.existingNodes.length <= 1) && !workbenchCascadeCandidateMatchesExisting(preferredCandidate, input)) {
|
|
5298
|
+
return preferredCandidate;
|
|
5299
|
+
}
|
|
5300
|
+
const candidateOrigins = [
|
|
5301
|
+
{
|
|
5302
|
+
x: activeNode.frame.x + cascadeOffset.x,
|
|
5303
|
+
y: activeNode.frame.y + cascadeOffset.y
|
|
5304
|
+
},
|
|
5305
|
+
{
|
|
5306
|
+
x: activeNode.frame.x - cascadeOffset.x,
|
|
5307
|
+
y: activeNode.frame.y + cascadeOffset.y
|
|
5308
|
+
},
|
|
5309
|
+
{
|
|
5310
|
+
x: activeNode.frame.x + cascadeOffset.x,
|
|
5311
|
+
y: activeNode.frame.y - cascadeOffset.y
|
|
5312
|
+
},
|
|
5313
|
+
{
|
|
5314
|
+
x: activeNode.frame.x - cascadeOffset.x,
|
|
5315
|
+
y: activeNode.frame.y - cascadeOffset.y
|
|
5316
|
+
}
|
|
5317
|
+
];
|
|
5318
|
+
for (let index = 1; index <= WORKBENCH_WINDOW_CASCADE_FALLBACK_LIMIT; index += 1) {
|
|
5319
|
+
candidateOrigins.push(
|
|
5320
|
+
{
|
|
5321
|
+
x: input.preferredFrame.x + cascadeOffset.x * index,
|
|
5322
|
+
y: input.preferredFrame.y + cascadeOffset.y * index
|
|
5323
|
+
},
|
|
5324
|
+
{
|
|
5325
|
+
x: input.preferredFrame.x - cascadeOffset.x * index,
|
|
5326
|
+
y: input.preferredFrame.y + cascadeOffset.y * index
|
|
5327
|
+
},
|
|
5328
|
+
{
|
|
5329
|
+
x: input.preferredFrame.x + cascadeOffset.x * index,
|
|
5330
|
+
y: input.preferredFrame.y - cascadeOffset.y * index
|
|
5331
|
+
},
|
|
5332
|
+
{
|
|
5333
|
+
x: input.preferredFrame.x - cascadeOffset.x * index,
|
|
5334
|
+
y: input.preferredFrame.y - cascadeOffset.y * index
|
|
5335
|
+
}
|
|
5336
|
+
);
|
|
5337
|
+
}
|
|
5338
|
+
return resolveBestWorkbenchCascadeCandidate({
|
|
5339
|
+
candidateOrigins,
|
|
5340
|
+
fallbackFrame: preferredCandidate,
|
|
5341
|
+
input
|
|
5342
|
+
});
|
|
5343
|
+
}
|
|
5344
|
+
function createWorkbenchCascadeCandidate(input) {
|
|
5285
5345
|
return clampWorkbenchRect(
|
|
5286
5346
|
{
|
|
5287
|
-
x:
|
|
5288
|
-
y:
|
|
5289
|
-
width: input.preferredFrame.width,
|
|
5290
|
-
height: input.preferredFrame.height
|
|
5347
|
+
x: input.x,
|
|
5348
|
+
y: input.y,
|
|
5349
|
+
width: input.input.preferredFrame.width,
|
|
5350
|
+
height: input.input.preferredFrame.height
|
|
5291
5351
|
},
|
|
5292
|
-
input.surfaceSize,
|
|
5293
|
-
input.constraints,
|
|
5294
|
-
input.sizeConstraints
|
|
5352
|
+
input.input.surfaceSize,
|
|
5353
|
+
input.input.constraints,
|
|
5354
|
+
input.input.sizeConstraints
|
|
5355
|
+
);
|
|
5356
|
+
}
|
|
5357
|
+
function workbenchCascadeCandidateMatchesExisting(candidate, input) {
|
|
5358
|
+
return input.existingNodes.some((node) => {
|
|
5359
|
+
return Math.abs(node.frame.x - candidate.x) <= WORKBENCH_WINDOW_CASCADE_POSITION_TOLERANCE && Math.abs(node.frame.y - candidate.y) <= WORKBENCH_WINDOW_CASCADE_POSITION_TOLERANCE;
|
|
5360
|
+
});
|
|
5361
|
+
}
|
|
5362
|
+
function resolveBestWorkbenchCascadeCandidate(input) {
|
|
5363
|
+
let bestFrame = null;
|
|
5364
|
+
let bestScore = Number.POSITIVE_INFINITY;
|
|
5365
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5366
|
+
for (const candidate of input.candidateOrigins) {
|
|
5367
|
+
const frame = createWorkbenchCascadeCandidate({
|
|
5368
|
+
input: input.input,
|
|
5369
|
+
x: candidate.x,
|
|
5370
|
+
y: candidate.y
|
|
5371
|
+
});
|
|
5372
|
+
const key = `${frame.x}:${frame.y}:${frame.width}:${frame.height}`;
|
|
5373
|
+
if (seen.has(key)) {
|
|
5374
|
+
continue;
|
|
5375
|
+
}
|
|
5376
|
+
seen.add(key);
|
|
5377
|
+
const score = scoreWorkbenchCascadeCandidate(frame, input.input);
|
|
5378
|
+
if (score < bestScore) {
|
|
5379
|
+
bestFrame = frame;
|
|
5380
|
+
bestScore = score;
|
|
5381
|
+
}
|
|
5382
|
+
}
|
|
5383
|
+
return bestFrame ?? input.fallbackFrame;
|
|
5384
|
+
}
|
|
5385
|
+
function scoreWorkbenchCascadeCandidate(candidate, input) {
|
|
5386
|
+
const overlapArea = input.existingNodes.reduce((total, node) => {
|
|
5387
|
+
return total + workbenchFrameIntersectionArea(candidate, node.frame);
|
|
5388
|
+
}, 0);
|
|
5389
|
+
const positionCollisionPenalty = workbenchCascadeCandidateMatchesExisting(
|
|
5390
|
+
candidate,
|
|
5391
|
+
input
|
|
5392
|
+
) ? candidate.width * candidate.height : 0;
|
|
5393
|
+
return overlapArea + positionCollisionPenalty;
|
|
5394
|
+
}
|
|
5395
|
+
function workbenchFrameIntersectionArea(a, b) {
|
|
5396
|
+
const width = Math.max(
|
|
5397
|
+
0,
|
|
5398
|
+
Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x)
|
|
5399
|
+
);
|
|
5400
|
+
const height = Math.max(
|
|
5401
|
+
0,
|
|
5402
|
+
Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y)
|
|
5295
5403
|
);
|
|
5404
|
+
return width * height;
|
|
5296
5405
|
}
|
|
5297
5406
|
|
|
5298
5407
|
// src/host/nodeIdentity.ts
|
|
@@ -5405,6 +5514,7 @@ function resolveWorkbenchLaunchedHostNodeFrame(input) {
|
|
|
5405
5514
|
existingSameTypeNodes.map((node) => node.id)
|
|
5406
5515
|
);
|
|
5407
5516
|
return resolveWorkbenchCascadedRect({
|
|
5517
|
+
cascadeOffset: input.result.cascadeOffset,
|
|
5408
5518
|
currentNodeStack: input.currentState.nodeStack.filter(
|
|
5409
5519
|
(nodeId) => existingSameTypeNodeIds.has(nodeId)
|
|
5410
5520
|
),
|
|
@@ -5421,6 +5531,7 @@ function resolveWorkbenchLaunchedHostNodeFrame(input) {
|
|
|
5421
5531
|
});
|
|
5422
5532
|
}
|
|
5423
5533
|
return resolveWorkbenchCascadedRect({
|
|
5534
|
+
cascadeOffset: input.result.cascadeOffset,
|
|
5424
5535
|
currentNodeStack: input.currentState.nodeStack,
|
|
5425
5536
|
existingNodes: input.currentState.nodes,
|
|
5426
5537
|
preferredFrame: responsivePreferredFrame,
|
|
@@ -6712,7 +6823,7 @@ var WorkbenchHostSessionController = class {
|
|
|
6712
6823
|
}
|
|
6713
6824
|
applyClosedDockWindowFrame(result) {
|
|
6714
6825
|
const dockEntryId = result.dockEntryId?.trim();
|
|
6715
|
-
if (!dockEntryId) {
|
|
6826
|
+
if (!dockEntryId || result.reuseDockEntryNode === false) {
|
|
6716
6827
|
return result;
|
|
6717
6828
|
}
|
|
6718
6829
|
const entry = this.closedDockWindowFrameEntries.get(
|
|
@@ -7178,6 +7289,94 @@ function isWorkbenchDockEntryBlocked(entry) {
|
|
|
7178
7289
|
|
|
7179
7290
|
// src/host/dockMagnification.ts
|
|
7180
7291
|
import { useCallback as useCallback8, useEffect as useEffect6, useRef as useRef5 } from "react";
|
|
7292
|
+
|
|
7293
|
+
// src/host/dockMagnificationBounds.ts
|
|
7294
|
+
function resolveDockMagnificationViewportBounds(viewportRect, dockPlacement) {
|
|
7295
|
+
return dockPlacement === "left" ? {
|
|
7296
|
+
crossEnd: viewportRect.right,
|
|
7297
|
+
crossStart: viewportRect.left,
|
|
7298
|
+
mainEnd: viewportRect.bottom,
|
|
7299
|
+
mainStart: viewportRect.top
|
|
7300
|
+
} : {
|
|
7301
|
+
crossEnd: viewportRect.bottom,
|
|
7302
|
+
crossStart: viewportRect.top,
|
|
7303
|
+
mainEnd: viewportRect.right,
|
|
7304
|
+
mainStart: viewportRect.left
|
|
7305
|
+
};
|
|
7306
|
+
}
|
|
7307
|
+
function resolveDockMagnificationVisibleHitBounds({
|
|
7308
|
+
dockPlacement,
|
|
7309
|
+
hitBounds,
|
|
7310
|
+
mainAxisEdgePadding = 0,
|
|
7311
|
+
viewportRect
|
|
7312
|
+
}) {
|
|
7313
|
+
if (!hitBounds || !viewportRect) {
|
|
7314
|
+
return hitBounds;
|
|
7315
|
+
}
|
|
7316
|
+
const viewportBounds = resolveDockMagnificationViewportBounds(
|
|
7317
|
+
viewportRect,
|
|
7318
|
+
dockPlacement
|
|
7319
|
+
);
|
|
7320
|
+
const visibleBounds = {
|
|
7321
|
+
crossEnd: Math.min(hitBounds.crossEnd, viewportBounds.crossEnd),
|
|
7322
|
+
crossStart: Math.max(hitBounds.crossStart, viewportBounds.crossStart),
|
|
7323
|
+
mainEnd: Math.min(
|
|
7324
|
+
hitBounds.mainEnd + mainAxisEdgePadding,
|
|
7325
|
+
viewportBounds.mainEnd + mainAxisEdgePadding
|
|
7326
|
+
),
|
|
7327
|
+
mainStart: Math.max(
|
|
7328
|
+
hitBounds.mainStart - mainAxisEdgePadding,
|
|
7329
|
+
viewportBounds.mainStart - mainAxisEdgePadding
|
|
7330
|
+
)
|
|
7331
|
+
};
|
|
7332
|
+
if (visibleBounds.mainStart > visibleBounds.mainEnd || visibleBounds.crossStart > visibleBounds.crossEnd) {
|
|
7333
|
+
return null;
|
|
7334
|
+
}
|
|
7335
|
+
return visibleBounds;
|
|
7336
|
+
}
|
|
7337
|
+
function resolveDockMagnificationVisibleSlotRects({
|
|
7338
|
+
slotRects,
|
|
7339
|
+
viewportRect
|
|
7340
|
+
}) {
|
|
7341
|
+
if (!viewportRect) {
|
|
7342
|
+
return [...slotRects];
|
|
7343
|
+
}
|
|
7344
|
+
const visibleSlotRects = [];
|
|
7345
|
+
for (const rect of slotRects) {
|
|
7346
|
+
const visibleRect = {
|
|
7347
|
+
bottom: Math.min(rect.bottom, viewportRect.bottom),
|
|
7348
|
+
left: Math.max(rect.left, viewportRect.left),
|
|
7349
|
+
right: Math.min(rect.right, viewportRect.right),
|
|
7350
|
+
top: Math.max(rect.top, viewportRect.top)
|
|
7351
|
+
};
|
|
7352
|
+
if (visibleRect.left <= visibleRect.right && visibleRect.top <= visibleRect.bottom) {
|
|
7353
|
+
visibleSlotRects.push(visibleRect);
|
|
7354
|
+
}
|
|
7355
|
+
}
|
|
7356
|
+
return visibleSlotRects;
|
|
7357
|
+
}
|
|
7358
|
+
function isDockMagnificationPointInsideHitBounds({
|
|
7359
|
+
clientX,
|
|
7360
|
+
clientY,
|
|
7361
|
+
dockPlacement,
|
|
7362
|
+
hitBounds
|
|
7363
|
+
}) {
|
|
7364
|
+
if (!hitBounds) {
|
|
7365
|
+
return false;
|
|
7366
|
+
}
|
|
7367
|
+
const mainAxis = dockPlacement === "left" ? clientY : clientX;
|
|
7368
|
+
const crossAxis = dockPlacement === "left" ? clientX : clientY;
|
|
7369
|
+
return mainAxis >= hitBounds.mainStart && mainAxis <= hitBounds.mainEnd && crossAxis >= hitBounds.crossStart && crossAxis <= hitBounds.crossEnd;
|
|
7370
|
+
}
|
|
7371
|
+
function isDockMagnificationPointInsideSlotRect({
|
|
7372
|
+
clientX,
|
|
7373
|
+
clientY,
|
|
7374
|
+
rect
|
|
7375
|
+
}) {
|
|
7376
|
+
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
7377
|
+
}
|
|
7378
|
+
|
|
7379
|
+
// src/host/dockMagnification.ts
|
|
7181
7380
|
var DOCK_ICON_BASE_SIZE = 43.2;
|
|
7182
7381
|
var DOCK_ICON_PEAK_SIZE = DOCK_ICON_BASE_SIZE * 1.7;
|
|
7183
7382
|
var DOCK_MAGNIFICATION_HALF_RANGE = DOCK_ICON_BASE_SIZE * 2.4;
|
|
@@ -7190,7 +7389,14 @@ var MAX_MAGNIFICATION_STEP_SECONDS = 1 / 30;
|
|
|
7190
7389
|
var MAGNIFICATION_INFLUENCE_PADDING = 8;
|
|
7191
7390
|
var DOCK_MAGNIFICATION_ENTRY_RAMP_MS = 90;
|
|
7192
7391
|
var DOCK_MAGNIFICATION_CROSS_AXIS_PADDING = 8;
|
|
7392
|
+
var DOCK_MAGNIFICATION_MAIN_AXIS_EDGE_PADDING = DOCK_ICON_BASE_SIZE / 2;
|
|
7393
|
+
var DOCK_MAGNIFICATION_AMBIENT_EDGE_RANGE = 180;
|
|
7394
|
+
var DOCK_MAGNIFICATION_AMBIENT_VIEWPORT_PADDING = 8;
|
|
7193
7395
|
var dockMagnificationShellBySlot = /* @__PURE__ */ new WeakMap();
|
|
7396
|
+
var globalPointerListenerOptions = {
|
|
7397
|
+
capture: true,
|
|
7398
|
+
passive: true
|
|
7399
|
+
};
|
|
7194
7400
|
function mapDistanceToTargetSize(distance, baseSize = DOCK_ICON_BASE_SIZE, peakSize = DOCK_ICON_PEAK_SIZE, halfRange = DOCK_MAGNIFICATION_HALF_RANGE) {
|
|
7195
7401
|
const absoluteDistance = Math.abs(distance);
|
|
7196
7402
|
if (absoluteDistance >= halfRange) {
|
|
@@ -7232,18 +7438,60 @@ function resolveDockMagnificationHitBounds(slotRects, dockPlacement, crossAxisPa
|
|
|
7232
7438
|
mainStart
|
|
7233
7439
|
};
|
|
7234
7440
|
}
|
|
7235
|
-
function
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7441
|
+
function createDockMagnificationGlobalPointerTracker({
|
|
7442
|
+
blurTarget,
|
|
7443
|
+
onPointerCancel,
|
|
7444
|
+
onPointerMove,
|
|
7445
|
+
pointerTarget
|
|
7240
7446
|
}) {
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7447
|
+
let active = false;
|
|
7448
|
+
const handlePointerMove = (event) => {
|
|
7449
|
+
const pointerEvent = event;
|
|
7450
|
+
onPointerMove(pointerEvent.clientX, pointerEvent.clientY);
|
|
7451
|
+
};
|
|
7452
|
+
const handlePointerCancel = () => {
|
|
7453
|
+
stop();
|
|
7454
|
+
onPointerCancel();
|
|
7455
|
+
};
|
|
7456
|
+
const start = () => {
|
|
7457
|
+
if (active) {
|
|
7458
|
+
return;
|
|
7459
|
+
}
|
|
7460
|
+
active = true;
|
|
7461
|
+
pointerTarget.addEventListener(
|
|
7462
|
+
"pointermove",
|
|
7463
|
+
handlePointerMove,
|
|
7464
|
+
globalPointerListenerOptions
|
|
7465
|
+
);
|
|
7466
|
+
pointerTarget.addEventListener(
|
|
7467
|
+
"pointercancel",
|
|
7468
|
+
handlePointerCancel,
|
|
7469
|
+
globalPointerListenerOptions
|
|
7470
|
+
);
|
|
7471
|
+
blurTarget?.addEventListener("blur", handlePointerCancel);
|
|
7472
|
+
};
|
|
7473
|
+
const stop = () => {
|
|
7474
|
+
if (!active) {
|
|
7475
|
+
return;
|
|
7476
|
+
}
|
|
7477
|
+
active = false;
|
|
7478
|
+
pointerTarget.removeEventListener(
|
|
7479
|
+
"pointermove",
|
|
7480
|
+
handlePointerMove,
|
|
7481
|
+
globalPointerListenerOptions
|
|
7482
|
+
);
|
|
7483
|
+
pointerTarget.removeEventListener(
|
|
7484
|
+
"pointercancel",
|
|
7485
|
+
handlePointerCancel,
|
|
7486
|
+
globalPointerListenerOptions
|
|
7487
|
+
);
|
|
7488
|
+
blurTarget?.removeEventListener("blur", handlePointerCancel);
|
|
7489
|
+
};
|
|
7490
|
+
return {
|
|
7491
|
+
isActive: () => active,
|
|
7492
|
+
start,
|
|
7493
|
+
stop
|
|
7494
|
+
};
|
|
7247
7495
|
}
|
|
7248
7496
|
function resolveDockMagnificationSlotCenter(rect, dockPlacement, baseSize = DOCK_ICON_BASE_SIZE) {
|
|
7249
7497
|
return dockPlacement === "left" ? rect.top + baseSize / 2 : rect.left + baseSize / 2;
|
|
@@ -7333,9 +7581,30 @@ function clearDockSlotMagnification(slotElement, appliedStylesRef) {
|
|
|
7333
7581
|
const shell = resolveDockMagnificationShell(slotElement);
|
|
7334
7582
|
shell?.style.removeProperty("transform");
|
|
7335
7583
|
}
|
|
7584
|
+
function isPointNearDockScreenEdge({
|
|
7585
|
+
clientX,
|
|
7586
|
+
clientY,
|
|
7587
|
+
dockPlacement
|
|
7588
|
+
}) {
|
|
7589
|
+
if (typeof window === "undefined") {
|
|
7590
|
+
return true;
|
|
7591
|
+
}
|
|
7592
|
+
return dockPlacement === "left" ? clientX <= DOCK_MAGNIFICATION_AMBIENT_EDGE_RANGE : window.innerHeight - clientY <= DOCK_MAGNIFICATION_AMBIENT_EDGE_RANGE;
|
|
7593
|
+
}
|
|
7594
|
+
function isPointNearDockViewport({
|
|
7595
|
+
clientX,
|
|
7596
|
+
clientY,
|
|
7597
|
+
dockPlacement,
|
|
7598
|
+
viewportRect
|
|
7599
|
+
}) {
|
|
7600
|
+
const horizontalPadding = dockPlacement === "bottom" ? DOCK_MAGNIFICATION_MAIN_AXIS_EDGE_PADDING : DOCK_MAGNIFICATION_AMBIENT_VIEWPORT_PADDING;
|
|
7601
|
+
const verticalPadding = dockPlacement === "left" ? DOCK_MAGNIFICATION_MAIN_AXIS_EDGE_PADDING : DOCK_MAGNIFICATION_AMBIENT_VIEWPORT_PADDING;
|
|
7602
|
+
return clientX >= viewportRect.left - horizontalPadding && clientX <= viewportRect.right + horizontalPadding && clientY >= viewportRect.top - verticalPadding && clientY <= viewportRect.bottom + verticalPadding;
|
|
7603
|
+
}
|
|
7336
7604
|
function useDockMagnification({
|
|
7337
7605
|
dockPlacement,
|
|
7338
7606
|
dockRootRef,
|
|
7607
|
+
dockViewportRef,
|
|
7339
7608
|
slotRefs
|
|
7340
7609
|
}) {
|
|
7341
7610
|
const pointerAxisRef = useRef5(null);
|
|
@@ -7349,8 +7618,16 @@ function useDockMagnification({
|
|
|
7349
7618
|
const entryRampStartedAtRef = useRef5(null);
|
|
7350
7619
|
const restCentersRef = useRef5(null);
|
|
7351
7620
|
const hitBoundsRef = useRef5(null);
|
|
7621
|
+
const visibleSlotRectsRef = useRef5(null);
|
|
7352
7622
|
const slotOrderRef = useRef5([]);
|
|
7353
7623
|
const magnifyActiveRef = useRef5(false);
|
|
7624
|
+
const globalPointerTrackerRef = useRef5(null);
|
|
7625
|
+
const handleGlobalPointerMoveRef = useRef5(() => {
|
|
7626
|
+
return;
|
|
7627
|
+
});
|
|
7628
|
+
const handleGlobalPointerCancelRef = useRef5(() => {
|
|
7629
|
+
return;
|
|
7630
|
+
});
|
|
7354
7631
|
const setMagnifyActive = useCallback8(
|
|
7355
7632
|
(active) => {
|
|
7356
7633
|
if (magnifyActiveRef.current === active) {
|
|
@@ -7377,6 +7654,7 @@ function useDockMagnification({
|
|
|
7377
7654
|
const centers = /* @__PURE__ */ new Map();
|
|
7378
7655
|
const slotRects = [];
|
|
7379
7656
|
const order = [];
|
|
7657
|
+
const viewportRect = dockViewportRef.current?.getBoundingClientRect();
|
|
7380
7658
|
for (const [anchorKey, slotElement] of slots) {
|
|
7381
7659
|
order.push(anchorKey);
|
|
7382
7660
|
const rect = slotElement.getBoundingClientRect();
|
|
@@ -7390,12 +7668,53 @@ function useDockMagnification({
|
|
|
7390
7668
|
centers.set(anchorKey, center);
|
|
7391
7669
|
}
|
|
7392
7670
|
slotOrderRef.current = order;
|
|
7393
|
-
|
|
7671
|
+
const visibleViewportRect = viewportRect ? {
|
|
7672
|
+
bottom: viewportRect.bottom,
|
|
7673
|
+
left: viewportRect.left,
|
|
7674
|
+
right: viewportRect.right,
|
|
7675
|
+
top: viewportRect.top
|
|
7676
|
+
} : null;
|
|
7677
|
+
hitBoundsRef.current = resolveDockMagnificationVisibleHitBounds({
|
|
7678
|
+
dockPlacement,
|
|
7679
|
+
hitBounds: resolveDockMagnificationHitBounds(slotRects, dockPlacement),
|
|
7680
|
+
mainAxisEdgePadding: DOCK_MAGNIFICATION_MAIN_AXIS_EDGE_PADDING,
|
|
7681
|
+
viewportRect: visibleViewportRect
|
|
7682
|
+
});
|
|
7683
|
+
visibleSlotRectsRef.current = resolveDockMagnificationVisibleSlotRects({
|
|
7394
7684
|
slotRects,
|
|
7395
|
-
|
|
7396
|
-
);
|
|
7685
|
+
viewportRect: visibleViewportRect
|
|
7686
|
+
});
|
|
7397
7687
|
restCentersRef.current = centers;
|
|
7398
|
-
}, [dockPlacement, slotRefs]);
|
|
7688
|
+
}, [dockPlacement, dockViewportRef, slotRefs]);
|
|
7689
|
+
const isPointerInsideAnyVisibleDockSlot = useCallback8(
|
|
7690
|
+
(clientX, clientY) => {
|
|
7691
|
+
for (const rect of visibleSlotRectsRef.current ?? []) {
|
|
7692
|
+
if (isDockMagnificationPointInsideSlotRect({
|
|
7693
|
+
clientX,
|
|
7694
|
+
clientY,
|
|
7695
|
+
rect
|
|
7696
|
+
})) {
|
|
7697
|
+
return true;
|
|
7698
|
+
}
|
|
7699
|
+
}
|
|
7700
|
+
return false;
|
|
7701
|
+
},
|
|
7702
|
+
[]
|
|
7703
|
+
);
|
|
7704
|
+
const ensureDockMagnificationGeometry = useCallback8(() => {
|
|
7705
|
+
if (restCentersRef.current === null || hitBoundsRef.current === null || visibleSlotRectsRef.current === null) {
|
|
7706
|
+
captureRestCenters();
|
|
7707
|
+
}
|
|
7708
|
+
}, [captureRestCenters]);
|
|
7709
|
+
const isPointerInsideDockMagnificationTarget = useCallback8(
|
|
7710
|
+
(clientX, clientY) => isDockMagnificationPointInsideHitBounds({
|
|
7711
|
+
clientX,
|
|
7712
|
+
clientY,
|
|
7713
|
+
dockPlacement,
|
|
7714
|
+
hitBounds: hitBoundsRef.current
|
|
7715
|
+
}) || isPointerInsideAnyVisibleDockSlot(clientX, clientY),
|
|
7716
|
+
[dockPlacement, isPointerInsideAnyVisibleDockSlot]
|
|
7717
|
+
);
|
|
7399
7718
|
const runAnimationFrame = useCallback8(
|
|
7400
7719
|
(frameTime) => {
|
|
7401
7720
|
if (pendingPointerAxisRef.current !== null) {
|
|
@@ -7493,6 +7812,7 @@ function useDockMagnification({
|
|
|
7493
7812
|
entryRampStartedAtRef.current = null;
|
|
7494
7813
|
restCentersRef.current = null;
|
|
7495
7814
|
hitBoundsRef.current = null;
|
|
7815
|
+
visibleSlotRectsRef.current = null;
|
|
7496
7816
|
slotOrderRef.current = [];
|
|
7497
7817
|
setMagnifyActive(false);
|
|
7498
7818
|
}
|
|
@@ -7511,31 +7831,144 @@ function useDockMagnification({
|
|
|
7511
7831
|
}
|
|
7512
7832
|
animationFrameRef.current = requestAnimationFrame(runAnimationFrame);
|
|
7513
7833
|
}, [runAnimationFrame]);
|
|
7834
|
+
const stopGlobalPointerTracking = useCallback8(() => {
|
|
7835
|
+
globalPointerTrackerRef.current?.stop();
|
|
7836
|
+
}, []);
|
|
7837
|
+
const startGlobalPointerTracking = useCallback8(() => {
|
|
7838
|
+
if (typeof document === "undefined") {
|
|
7839
|
+
return;
|
|
7840
|
+
}
|
|
7841
|
+
globalPointerTrackerRef.current ??= createDockMagnificationGlobalPointerTracker({
|
|
7842
|
+
blurTarget: typeof window === "undefined" ? null : window,
|
|
7843
|
+
onPointerCancel: () => {
|
|
7844
|
+
handleGlobalPointerCancelRef.current();
|
|
7845
|
+
},
|
|
7846
|
+
onPointerMove: (clientX, clientY) => {
|
|
7847
|
+
handleGlobalPointerMoveRef.current(clientX, clientY);
|
|
7848
|
+
},
|
|
7849
|
+
pointerTarget: document
|
|
7850
|
+
});
|
|
7851
|
+
globalPointerTrackerRef.current.start();
|
|
7852
|
+
}, []);
|
|
7853
|
+
const clearTrackedPointer = useCallback8(() => {
|
|
7854
|
+
pendingPointerAxisRef.current = null;
|
|
7855
|
+
pointerAxisRef.current = null;
|
|
7856
|
+
entryRampStartedAtRef.current = null;
|
|
7857
|
+
scheduleAnimation();
|
|
7858
|
+
}, [scheduleAnimation]);
|
|
7859
|
+
const handleGlobalPointerCancel = useCallback8(() => {
|
|
7860
|
+
stopGlobalPointerTracking();
|
|
7861
|
+
clearTrackedPointer();
|
|
7862
|
+
}, [clearTrackedPointer, stopGlobalPointerTracking]);
|
|
7514
7863
|
const handlePointerMove = useCallback8(
|
|
7515
7864
|
(clientX, clientY) => {
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
clientX,
|
|
7521
|
-
clientY,
|
|
7522
|
-
dockPlacement,
|
|
7523
|
-
hitBounds: hitBoundsRef.current
|
|
7524
|
-
})) {
|
|
7525
|
-
pendingPointerAxisRef.current = null;
|
|
7526
|
-
pointerAxisRef.current = null;
|
|
7527
|
-
entryRampStartedAtRef.current = null;
|
|
7528
|
-
scheduleAnimation();
|
|
7865
|
+
ensureDockMagnificationGeometry();
|
|
7866
|
+
if (!isPointerInsideDockMagnificationTarget(clientX, clientY)) {
|
|
7867
|
+
stopGlobalPointerTracking();
|
|
7868
|
+
clearTrackedPointer();
|
|
7529
7869
|
return;
|
|
7530
7870
|
}
|
|
7531
7871
|
pendingPointerAxisRef.current = dockPlacement === "left" ? clientY : clientX;
|
|
7532
7872
|
if (!magnifyActiveRef.current) {
|
|
7533
7873
|
setMagnifyActive(true);
|
|
7534
7874
|
}
|
|
7875
|
+
startGlobalPointerTracking();
|
|
7535
7876
|
scheduleAnimation();
|
|
7536
7877
|
},
|
|
7537
|
-
[
|
|
7878
|
+
[
|
|
7879
|
+
clearTrackedPointer,
|
|
7880
|
+
dockPlacement,
|
|
7881
|
+
ensureDockMagnificationGeometry,
|
|
7882
|
+
isPointerInsideDockMagnificationTarget,
|
|
7883
|
+
scheduleAnimation,
|
|
7884
|
+
setMagnifyActive,
|
|
7885
|
+
startGlobalPointerTracking,
|
|
7886
|
+
stopGlobalPointerTracking
|
|
7887
|
+
]
|
|
7538
7888
|
);
|
|
7889
|
+
handleGlobalPointerMoveRef.current = handlePointerMove;
|
|
7890
|
+
handleGlobalPointerCancelRef.current = handleGlobalPointerCancel;
|
|
7891
|
+
useEffect6(() => {
|
|
7892
|
+
if (typeof document === "undefined") {
|
|
7893
|
+
return;
|
|
7894
|
+
}
|
|
7895
|
+
let animationFrame = null;
|
|
7896
|
+
let latestPoint = null;
|
|
7897
|
+
const clearAmbientPointerSample = () => {
|
|
7898
|
+
latestPoint = null;
|
|
7899
|
+
if (animationFrame !== null) {
|
|
7900
|
+
cancelAnimationFrame(animationFrame);
|
|
7901
|
+
animationFrame = null;
|
|
7902
|
+
}
|
|
7903
|
+
};
|
|
7904
|
+
const runAmbientPointerMove = () => {
|
|
7905
|
+
animationFrame = null;
|
|
7906
|
+
const point = latestPoint;
|
|
7907
|
+
latestPoint = null;
|
|
7908
|
+
if (!point || magnifyActiveRef.current) {
|
|
7909
|
+
return;
|
|
7910
|
+
}
|
|
7911
|
+
const viewportRect = dockViewportRef.current?.getBoundingClientRect();
|
|
7912
|
+
if (!viewportRect) {
|
|
7913
|
+
return;
|
|
7914
|
+
}
|
|
7915
|
+
const visibleViewportRect = {
|
|
7916
|
+
bottom: viewportRect.bottom,
|
|
7917
|
+
left: viewportRect.left,
|
|
7918
|
+
right: viewportRect.right,
|
|
7919
|
+
top: viewportRect.top
|
|
7920
|
+
};
|
|
7921
|
+
if (!isPointNearDockViewport({
|
|
7922
|
+
clientX: point.clientX,
|
|
7923
|
+
clientY: point.clientY,
|
|
7924
|
+
dockPlacement,
|
|
7925
|
+
viewportRect: visibleViewportRect
|
|
7926
|
+
})) {
|
|
7927
|
+
return;
|
|
7928
|
+
}
|
|
7929
|
+
ensureDockMagnificationGeometry();
|
|
7930
|
+
if (isPointerInsideDockMagnificationTarget(point.clientX, point.clientY)) {
|
|
7931
|
+
handlePointerMove(point.clientX, point.clientY);
|
|
7932
|
+
}
|
|
7933
|
+
};
|
|
7934
|
+
const handleAmbientPointerMove = (event) => {
|
|
7935
|
+
if (magnifyActiveRef.current) {
|
|
7936
|
+
clearAmbientPointerSample();
|
|
7937
|
+
return;
|
|
7938
|
+
}
|
|
7939
|
+
if (!isPointNearDockScreenEdge({
|
|
7940
|
+
clientX: event.clientX,
|
|
7941
|
+
clientY: event.clientY,
|
|
7942
|
+
dockPlacement
|
|
7943
|
+
})) {
|
|
7944
|
+
clearAmbientPointerSample();
|
|
7945
|
+
return;
|
|
7946
|
+
}
|
|
7947
|
+
latestPoint = { clientX: event.clientX, clientY: event.clientY };
|
|
7948
|
+
if (animationFrame === null) {
|
|
7949
|
+
animationFrame = requestAnimationFrame(runAmbientPointerMove);
|
|
7950
|
+
}
|
|
7951
|
+
};
|
|
7952
|
+
document.addEventListener(
|
|
7953
|
+
"pointermove",
|
|
7954
|
+
handleAmbientPointerMove,
|
|
7955
|
+
globalPointerListenerOptions
|
|
7956
|
+
);
|
|
7957
|
+
return () => {
|
|
7958
|
+
document.removeEventListener(
|
|
7959
|
+
"pointermove",
|
|
7960
|
+
handleAmbientPointerMove,
|
|
7961
|
+
globalPointerListenerOptions
|
|
7962
|
+
);
|
|
7963
|
+
clearAmbientPointerSample();
|
|
7964
|
+
};
|
|
7965
|
+
}, [
|
|
7966
|
+
dockPlacement,
|
|
7967
|
+
dockViewportRef,
|
|
7968
|
+
ensureDockMagnificationGeometry,
|
|
7969
|
+
handlePointerMove,
|
|
7970
|
+
isPointerInsideDockMagnificationTarget
|
|
7971
|
+
]);
|
|
7539
7972
|
const handlePointerLeave = useCallback8(() => {
|
|
7540
7973
|
pendingPointerAxisRef.current = null;
|
|
7541
7974
|
pointerAxisRef.current = null;
|
|
@@ -7547,6 +7980,7 @@ function useDockMagnification({
|
|
|
7547
7980
|
restCentersRef.current?.delete(anchorKey);
|
|
7548
7981
|
appliedStylesRef.current.delete(anchorKey);
|
|
7549
7982
|
hitBoundsRef.current = null;
|
|
7983
|
+
visibleSlotRectsRef.current = null;
|
|
7550
7984
|
slotOrderRef.current = slotOrderRef.current.filter(
|
|
7551
7985
|
(key) => key !== anchorKey
|
|
7552
7986
|
);
|
|
@@ -7558,13 +7992,15 @@ function useDockMagnification({
|
|
|
7558
7992
|
[slotRefs]
|
|
7559
7993
|
);
|
|
7560
7994
|
const pauseMagnification = useCallback8(() => {
|
|
7995
|
+
stopGlobalPointerTracking();
|
|
7561
7996
|
stopAnimation();
|
|
7562
7997
|
pendingPointerAxisRef.current = null;
|
|
7563
7998
|
pointerAxisRef.current = null;
|
|
7564
7999
|
entryRampStartedAtRef.current = null;
|
|
7565
8000
|
lastFrameTimeRef.current = null;
|
|
7566
|
-
}, [stopAnimation]);
|
|
8001
|
+
}, [stopAnimation, stopGlobalPointerTracking]);
|
|
7567
8002
|
const resetMagnification = useCallback8(() => {
|
|
8003
|
+
stopGlobalPointerTracking();
|
|
7568
8004
|
stopAnimation();
|
|
7569
8005
|
for (const slotElement of slotRefs.current.values()) {
|
|
7570
8006
|
clearDockSlotMagnification(slotElement, appliedStylesRef.current);
|
|
@@ -7573,12 +8009,13 @@ function useDockMagnification({
|
|
|
7573
8009
|
appliedStylesRef.current.clear();
|
|
7574
8010
|
restCentersRef.current = null;
|
|
7575
8011
|
hitBoundsRef.current = null;
|
|
8012
|
+
visibleSlotRectsRef.current = null;
|
|
7576
8013
|
slotOrderRef.current = [];
|
|
7577
8014
|
pointerAxisRef.current = null;
|
|
7578
8015
|
pendingPointerAxisRef.current = null;
|
|
7579
8016
|
entryRampStartedAtRef.current = null;
|
|
7580
8017
|
setMagnifyActive(false);
|
|
7581
|
-
}, [setMagnifyActive, slotRefs, stopAnimation]);
|
|
8018
|
+
}, [setMagnifyActive, slotRefs, stopAnimation, stopGlobalPointerTracking]);
|
|
7582
8019
|
useEffect6(
|
|
7583
8020
|
() => () => {
|
|
7584
8021
|
resetMagnification();
|
|
@@ -9316,6 +9753,7 @@ function WorkbenchHostDock({
|
|
|
9316
9753
|
} = useDockMagnification({
|
|
9317
9754
|
dockPlacement,
|
|
9318
9755
|
dockRootRef: dockMeasureRef,
|
|
9756
|
+
dockViewportRef: dockItemsRef,
|
|
9319
9757
|
slotRefs
|
|
9320
9758
|
});
|
|
9321
9759
|
const clearSlotMagnificationRef = useRef8(() => {
|