@surdeddd/wmkit 0.2.0 → 0.3.0
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 +55 -5
- package/README.ru.md +18 -5
- package/dist/angular.cjs +52 -0
- package/dist/angular.cjs.map +1 -0
- package/dist/angular.d.cts +15 -0
- package/dist/angular.d.ts +15 -0
- package/dist/angular.js +47 -0
- package/dist/angular.js.map +1 -0
- package/dist/{binder-BY-saDUB.d.cts → binder-0Oku22Nc.d.ts} +14 -2
- package/dist/{binder-D9UEE1SM.d.ts → binder-Dq_AZRbo.d.cts} +14 -2
- package/dist/{chunk-KQCVZ2W7.cjs → chunk-B35DANTX.cjs} +303 -35
- package/dist/chunk-B35DANTX.cjs.map +1 -0
- package/dist/{chunk-2TVOEDRG.js → chunk-YCHJXSTC.js} +303 -36
- package/dist/chunk-YCHJXSTC.js.map +1 -0
- package/dist/index.cjs +19 -15
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/persist.d.cts +1 -1
- package/dist/persist.d.ts +1 -1
- package/dist/popout.d.cts +1 -1
- package/dist/popout.d.ts +1 -1
- package/dist/react.cjs +3 -3
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/solid.cjs +3 -3
- package/dist/solid.d.cts +2 -2
- package/dist/solid.d.ts +2 -2
- package/dist/solid.js +1 -1
- package/dist/svelte.cjs +3 -3
- package/dist/svelte.d.cts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +1 -1
- package/dist/themes/light.css +202 -0
- package/dist/themes/retro.css +152 -0
- package/dist/{types-Bkrq2djr.d.cts → types-DdCtDHgt.d.cts} +23 -1
- package/dist/{types-Bkrq2djr.d.ts → types-DdCtDHgt.d.ts} +23 -1
- package/dist/vue.cjs +3 -3
- package/dist/vue.d.cts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +1 -1
- package/package.json +34 -7
- package/dist/chunk-2TVOEDRG.js.map +0 -1
- package/dist/chunk-KQCVZ2W7.cjs.map +0 -1
|
@@ -97,6 +97,42 @@ function detectSnapZone(x, y, viewport, options = {}) {
|
|
|
97
97
|
}
|
|
98
98
|
return null;
|
|
99
99
|
}
|
|
100
|
+
function nearestEdge(low, high, targetLow, targetHigh) {
|
|
101
|
+
return [targetLow - low, targetHigh - low, targetLow - high, targetHigh - high];
|
|
102
|
+
}
|
|
103
|
+
function magnetize(bounds, targets, threshold) {
|
|
104
|
+
const result = { x: bounds.x, y: bounds.y, snappedX: false, snappedY: false };
|
|
105
|
+
if (threshold <= 0 || targets.length === 0) return result;
|
|
106
|
+
let bestX = threshold + 1;
|
|
107
|
+
let bestY = threshold + 1;
|
|
108
|
+
for (const target of targets) {
|
|
109
|
+
for (const delta of nearestEdge(
|
|
110
|
+
bounds.x,
|
|
111
|
+
bounds.x + bounds.width,
|
|
112
|
+
target.x,
|
|
113
|
+
target.x + target.width
|
|
114
|
+
)) {
|
|
115
|
+
if (Math.abs(delta) <= threshold && Math.abs(delta) < Math.abs(bestX)) bestX = delta;
|
|
116
|
+
}
|
|
117
|
+
for (const delta of nearestEdge(
|
|
118
|
+
bounds.y,
|
|
119
|
+
bounds.y + bounds.height,
|
|
120
|
+
target.y,
|
|
121
|
+
target.y + target.height
|
|
122
|
+
)) {
|
|
123
|
+
if (Math.abs(delta) <= threshold && Math.abs(delta) < Math.abs(bestY)) bestY = delta;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (Math.abs(bestX) <= threshold) {
|
|
127
|
+
result.x = bounds.x + bestX;
|
|
128
|
+
result.snappedX = true;
|
|
129
|
+
}
|
|
130
|
+
if (Math.abs(bestY) <= threshold) {
|
|
131
|
+
result.y = bounds.y + bestY;
|
|
132
|
+
result.snappedY = true;
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
100
136
|
|
|
101
137
|
// src/core/manager.ts
|
|
102
138
|
var LAYER_RANK = { normal: 0, floating: 1, modal: 2 };
|
|
@@ -120,6 +156,7 @@ function createWindowManager(options = {}) {
|
|
|
120
156
|
const cascadeOffset = options.cascadeOffset ?? 32;
|
|
121
157
|
const cascadeOrigin = options.cascadeOrigin ?? { x: 32, y: 32 };
|
|
122
158
|
const idPrefix = options.idPrefix ?? "wm";
|
|
159
|
+
const historyLimit = options.historyLimit ?? 50;
|
|
123
160
|
let windows = {};
|
|
124
161
|
let order = [];
|
|
125
162
|
let focusedId = null;
|
|
@@ -131,6 +168,13 @@ function createWindowManager(options = {}) {
|
|
|
131
168
|
let batchDepth = 0;
|
|
132
169
|
let batchDirty = false;
|
|
133
170
|
const pendingEvents = [];
|
|
171
|
+
const past = [];
|
|
172
|
+
let future = [];
|
|
173
|
+
let interactionDepth = 0;
|
|
174
|
+
let interactionRecorded = false;
|
|
175
|
+
let skipNextHistory = false;
|
|
176
|
+
let pendingHistory = null;
|
|
177
|
+
const layouts = /* @__PURE__ */ new Map();
|
|
134
178
|
function getState() {
|
|
135
179
|
if (!snapshot) {
|
|
136
180
|
snapshot = { windows, order, focusedId, viewport };
|
|
@@ -515,47 +559,164 @@ function createWindowManager(options = {}) {
|
|
|
515
559
|
function setViewport(next) {
|
|
516
560
|
if (next.width === viewport.width && next.height === viewport.height) return;
|
|
517
561
|
viewport = { ...next };
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
if (win.stage === "maximized") {
|
|
522
|
-
const updated = { ...win, bounds: fullBounds() };
|
|
523
|
-
setWindow(updated);
|
|
524
|
-
queueEvent(() => emitter.emit("resize", { window: updated }));
|
|
525
|
-
} else if (win.stage === "snapped" && win.snapZone) {
|
|
526
|
-
const updated = { ...win, bounds: zoneBounds(win.snapZone, viewport) };
|
|
527
|
-
setWindow(updated);
|
|
528
|
-
queueEvent(() => emitter.emit("resize", { window: updated }));
|
|
529
|
-
} else if (win.stage === "normal" && keepInViewport) {
|
|
530
|
-
const bounds = clampToViewport(win.bounds, viewport, minVisible);
|
|
531
|
-
if (!boundsEqual(bounds, win.bounds)) {
|
|
532
|
-
const updated = { ...win, bounds };
|
|
533
|
-
setWindow(updated);
|
|
534
|
-
queueEvent(() => emitter.emit("move", { window: updated }));
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
snapshot = null;
|
|
539
|
-
batchDirty = true;
|
|
540
|
-
});
|
|
562
|
+
reflowViewport();
|
|
563
|
+
snapshot = null;
|
|
564
|
+
batchDirty = true;
|
|
541
565
|
}
|
|
542
566
|
function minimized() {
|
|
543
567
|
return Object.values(windows).filter((win) => win.stage === "minimized").sort((a, b) => a.openedSeq - b.openedSeq);
|
|
544
568
|
}
|
|
569
|
+
function captureEntry() {
|
|
570
|
+
return { windows, order, focusedId };
|
|
571
|
+
}
|
|
572
|
+
function recordHistory() {
|
|
573
|
+
if (skipNextHistory) {
|
|
574
|
+
skipNextHistory = false;
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
if (historyLimit <= 0) return;
|
|
578
|
+
if (interactionDepth > 0) {
|
|
579
|
+
if (interactionRecorded) return;
|
|
580
|
+
interactionRecorded = true;
|
|
581
|
+
}
|
|
582
|
+
past.push(pendingHistory);
|
|
583
|
+
if (past.length > historyLimit) past.shift();
|
|
584
|
+
future = [];
|
|
585
|
+
}
|
|
545
586
|
function transact(run) {
|
|
587
|
+
if (batchDepth === 0) pendingHistory = captureEntry();
|
|
546
588
|
batchDepth += 1;
|
|
547
589
|
try {
|
|
548
590
|
return run();
|
|
549
591
|
} finally {
|
|
550
592
|
batchDepth -= 1;
|
|
551
|
-
if (batchDepth === 0
|
|
552
|
-
batchDirty
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
593
|
+
if (batchDepth === 0) {
|
|
594
|
+
if (batchDirty) {
|
|
595
|
+
batchDirty = false;
|
|
596
|
+
recordHistory();
|
|
597
|
+
snapshot = null;
|
|
598
|
+
flushEvents();
|
|
599
|
+
emitter.emit("change", { state: getState() });
|
|
600
|
+
}
|
|
601
|
+
pendingHistory = null;
|
|
556
602
|
}
|
|
557
603
|
}
|
|
558
604
|
}
|
|
605
|
+
function reflowViewport() {
|
|
606
|
+
for (const id of order) {
|
|
607
|
+
const win = windows[id];
|
|
608
|
+
if (win.stage === "maximized") {
|
|
609
|
+
const updated = { ...win, bounds: fullBounds() };
|
|
610
|
+
setWindow(updated);
|
|
611
|
+
queueEvent(() => emitter.emit("resize", { window: updated }));
|
|
612
|
+
} else if (win.stage === "snapped" && win.snapZone) {
|
|
613
|
+
const updated = { ...win, bounds: zoneBounds(win.snapZone, viewport) };
|
|
614
|
+
setWindow(updated);
|
|
615
|
+
queueEvent(() => emitter.emit("resize", { window: updated }));
|
|
616
|
+
} else if (win.stage === "normal" && keepInViewport) {
|
|
617
|
+
const bounds = clampToViewport(win.bounds, viewport, minVisible);
|
|
618
|
+
if (!boundsEqual(bounds, win.bounds)) {
|
|
619
|
+
const updated = { ...win, bounds };
|
|
620
|
+
setWindow(updated);
|
|
621
|
+
queueEvent(() => emitter.emit("move", { window: updated }));
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
function applyEntry(entry) {
|
|
627
|
+
windows = entry.windows;
|
|
628
|
+
order = [...entry.order];
|
|
629
|
+
focusedId = entry.focusedId;
|
|
630
|
+
reflowViewport();
|
|
631
|
+
commit();
|
|
632
|
+
}
|
|
633
|
+
function undo() {
|
|
634
|
+
const entry = past.pop();
|
|
635
|
+
if (!entry) return false;
|
|
636
|
+
future.push(captureEntry());
|
|
637
|
+
skipNextHistory = true;
|
|
638
|
+
applyEntry(entry);
|
|
639
|
+
return true;
|
|
640
|
+
}
|
|
641
|
+
function redo() {
|
|
642
|
+
const entry = future.pop();
|
|
643
|
+
if (!entry) return false;
|
|
644
|
+
past.push(captureEntry());
|
|
645
|
+
skipNextHistory = true;
|
|
646
|
+
applyEntry(entry);
|
|
647
|
+
return true;
|
|
648
|
+
}
|
|
649
|
+
function beginInteraction() {
|
|
650
|
+
interactionDepth += 1;
|
|
651
|
+
if (interactionDepth === 1) interactionRecorded = false;
|
|
652
|
+
}
|
|
653
|
+
function endInteraction() {
|
|
654
|
+
if (interactionDepth > 0) interactionDepth -= 1;
|
|
655
|
+
}
|
|
656
|
+
function clearHistory() {
|
|
657
|
+
past.length = 0;
|
|
658
|
+
future = [];
|
|
659
|
+
}
|
|
660
|
+
function saveLayout(name) {
|
|
661
|
+
const data = serialize();
|
|
662
|
+
layouts.set(name, structuredClone(data));
|
|
663
|
+
return data;
|
|
664
|
+
}
|
|
665
|
+
function loadLayout(name) {
|
|
666
|
+
const data = layouts.get(name);
|
|
667
|
+
if (!data) return false;
|
|
668
|
+
return hydrate(structuredClone(data));
|
|
669
|
+
}
|
|
670
|
+
function getLayout(name) {
|
|
671
|
+
const data = layouts.get(name);
|
|
672
|
+
return data ? structuredClone(data) : void 0;
|
|
673
|
+
}
|
|
674
|
+
function setLayout(name, data) {
|
|
675
|
+
if (!isValidSerialized(data)) return false;
|
|
676
|
+
layouts.set(name, structuredClone(data));
|
|
677
|
+
return true;
|
|
678
|
+
}
|
|
679
|
+
function deleteLayout(name) {
|
|
680
|
+
return layouts.delete(name);
|
|
681
|
+
}
|
|
682
|
+
function layoutNames() {
|
|
683
|
+
return [...layouts.keys()];
|
|
684
|
+
}
|
|
685
|
+
function arrange(mode) {
|
|
686
|
+
const ids = order.filter((id) => windows[id].stage !== "minimized");
|
|
687
|
+
if (ids.length === 0) return;
|
|
688
|
+
if (mode === "cascade") {
|
|
689
|
+
ids.forEach((id, index) => {
|
|
690
|
+
const win = windows[id];
|
|
691
|
+
const size = win.restoreBounds ?? win.bounds;
|
|
692
|
+
restoreTo(id, {
|
|
693
|
+
x: cascadeOrigin.x + index % 10 * cascadeOffset,
|
|
694
|
+
y: cascadeOrigin.y + index % 10 * cascadeOffset,
|
|
695
|
+
width: size.width,
|
|
696
|
+
height: size.height
|
|
697
|
+
});
|
|
698
|
+
});
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
const cols = Math.ceil(Math.sqrt(ids.length));
|
|
702
|
+
const rows = Math.ceil(ids.length / cols);
|
|
703
|
+
const cellWidth = Math.floor(viewport.width / cols);
|
|
704
|
+
const cellHeight = Math.floor(viewport.height / rows);
|
|
705
|
+
ids.forEach((id, index) => {
|
|
706
|
+
restoreTo(id, {
|
|
707
|
+
x: index % cols * cellWidth,
|
|
708
|
+
y: Math.floor(index / cols) * cellHeight,
|
|
709
|
+
width: cellWidth,
|
|
710
|
+
height: cellHeight
|
|
711
|
+
});
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
function minimizeAll() {
|
|
715
|
+
for (const id of [...order]) minimize(id);
|
|
716
|
+
}
|
|
717
|
+
function restoreAll() {
|
|
718
|
+
for (const win of minimized()) restore(win.id);
|
|
719
|
+
}
|
|
559
720
|
function serialize() {
|
|
560
721
|
return {
|
|
561
722
|
version: 1,
|
|
@@ -602,10 +763,16 @@ function createWindowManager(options = {}) {
|
|
|
602
763
|
const win = value;
|
|
603
764
|
return typeof win.id === "string" && win.id.length > 0 && isBounds(win.bounds) && STAGES.includes(win.stage) && LAYERS.includes(win.layer);
|
|
604
765
|
}
|
|
605
|
-
function
|
|
766
|
+
function isValidSerialized(data) {
|
|
606
767
|
if (typeof data !== "object" || data === null) return false;
|
|
607
768
|
if (data.version !== 1 || !Array.isArray(data.windows)) return false;
|
|
608
769
|
if (!data.windows.every(isSerializedWindow)) return false;
|
|
770
|
+
const ids = new Set(data.windows.map((win) => win.id));
|
|
771
|
+
return ids.size === data.windows.length;
|
|
772
|
+
}
|
|
773
|
+
function hydrate(data) {
|
|
774
|
+
if (!isValidSerialized(data)) return false;
|
|
775
|
+
const previousWindows = windows;
|
|
609
776
|
const nextWindows = {};
|
|
610
777
|
let maxSeq = 0;
|
|
611
778
|
for (const raw of data.windows) {
|
|
@@ -657,6 +824,21 @@ function createWindowManager(options = {}) {
|
|
|
657
824
|
const focusedWin = focusedId ? windows[focusedId] : null;
|
|
658
825
|
if (focusedWin?.layer !== "modal") focusedId = modal;
|
|
659
826
|
}
|
|
827
|
+
for (const id of Object.keys(previousWindows)) {
|
|
828
|
+
if (!windows[id]) {
|
|
829
|
+
const closed = previousWindows[id];
|
|
830
|
+
queueEvent(() => emitter.emit("close", { window: closed }));
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
for (const id of order) {
|
|
834
|
+
if (!previousWindows[id]) {
|
|
835
|
+
const opened = windows[id];
|
|
836
|
+
queueEvent(() => emitter.emit("open", { window: opened }));
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
queueEvent(() => emitter.emit("order", { order }));
|
|
840
|
+
clearHistory();
|
|
841
|
+
skipNextHistory = true;
|
|
660
842
|
commit();
|
|
661
843
|
return true;
|
|
662
844
|
}
|
|
@@ -687,6 +869,21 @@ function createWindowManager(options = {}) {
|
|
|
687
869
|
batch: (run) => transact(run),
|
|
688
870
|
serialize,
|
|
689
871
|
hydrate: (data) => transact(() => hydrate(data)),
|
|
872
|
+
undo: () => transact(undo),
|
|
873
|
+
redo: () => transact(redo),
|
|
874
|
+
canUndo: () => past.length > 0,
|
|
875
|
+
canRedo: () => future.length > 0,
|
|
876
|
+
beginInteraction,
|
|
877
|
+
endInteraction,
|
|
878
|
+
saveLayout,
|
|
879
|
+
loadLayout: (name) => transact(() => loadLayout(name)),
|
|
880
|
+
getLayout,
|
|
881
|
+
setLayout,
|
|
882
|
+
deleteLayout,
|
|
883
|
+
layoutNames,
|
|
884
|
+
arrange: (mode) => transact(() => arrange(mode)),
|
|
885
|
+
minimizeAll: () => transact(minimizeAll),
|
|
886
|
+
restoreAll: () => transact(restoreAll),
|
|
690
887
|
subscribe: (listener) => emitter.on("change", ({ state }) => listener(state)),
|
|
691
888
|
on: (event, listener) => emitter.on(event, listener),
|
|
692
889
|
destroy
|
|
@@ -697,6 +894,34 @@ function createWindowManager(options = {}) {
|
|
|
697
894
|
function prefersReducedMotion(win) {
|
|
698
895
|
return win.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
699
896
|
}
|
|
897
|
+
function flipFromTarget(source, target, options = {}) {
|
|
898
|
+
const view = source.ownerDocument.defaultView;
|
|
899
|
+
if (!view || prefersReducedMotion(view)) return;
|
|
900
|
+
if (typeof source.animate !== "function") return;
|
|
901
|
+
const from = target.getBoundingClientRect();
|
|
902
|
+
const to = source.getBoundingClientRect();
|
|
903
|
+
if (from.width === 0 || to.width === 0) return;
|
|
904
|
+
const ghost = source.ownerDocument.createElement("div");
|
|
905
|
+
const style = view.getComputedStyle(source);
|
|
906
|
+
ghost.style.cssText = `position:fixed;left:${to.left}px;top:${to.top}px;width:${to.width}px;height:${to.height}px;margin:0;pointer-events:none;z-index:2147483647;border-radius:${style.borderRadius};background:${style.backgroundColor};box-shadow:${style.boxShadow};transform-origin:top left;will-change:transform,opacity`;
|
|
907
|
+
source.ownerDocument.body.append(ghost);
|
|
908
|
+
const dx = from.left + from.width / 2 - (to.left + to.width / 2);
|
|
909
|
+
const dy = from.top + from.height / 2 - (to.top + to.height / 2);
|
|
910
|
+
const scaleX = Math.max(from.width / to.width, 0.05);
|
|
911
|
+
const scaleY = Math.max(from.height / to.height, 0.05);
|
|
912
|
+
const animation = ghost.animate(
|
|
913
|
+
[
|
|
914
|
+
{ transform: `translate(${dx}px, ${dy}px) scale(${scaleX}, ${scaleY})`, opacity: 0.2 },
|
|
915
|
+
{ transform: "translate(0, 0) scale(1, 1)", opacity: 0.9 }
|
|
916
|
+
],
|
|
917
|
+
{
|
|
918
|
+
duration: options.duration ?? 260,
|
|
919
|
+
easing: options.easing ?? "cubic-bezier(0.32, 0.72, 0, 1)"
|
|
920
|
+
}
|
|
921
|
+
);
|
|
922
|
+
animation.onfinish = () => ghost.remove();
|
|
923
|
+
animation.oncancel = () => ghost.remove();
|
|
924
|
+
}
|
|
700
925
|
function flipToTarget(source, target, options = {}) {
|
|
701
926
|
const view = source.ownerDocument.defaultView;
|
|
702
927
|
if (!view || prefersReducedMotion(view)) return;
|
|
@@ -839,7 +1064,27 @@ function createDragStarter(ctx) {
|
|
|
839
1064
|
}
|
|
840
1065
|
return;
|
|
841
1066
|
}
|
|
842
|
-
|
|
1067
|
+
let nextX = session.pendingX - session.grabDX;
|
|
1068
|
+
let nextY = session.pendingY - session.grabDY;
|
|
1069
|
+
if (ctx.magnetThreshold > 0) {
|
|
1070
|
+
const state = wm.getState();
|
|
1071
|
+
const targets = [
|
|
1072
|
+
{ x: 0, y: 0, width: state.viewport.width, height: state.viewport.height }
|
|
1073
|
+
];
|
|
1074
|
+
for (const otherId of state.order) {
|
|
1075
|
+
if (otherId === id) continue;
|
|
1076
|
+
const other = state.windows[otherId];
|
|
1077
|
+
if (other && other.stage !== "minimized") targets.push(other.bounds);
|
|
1078
|
+
}
|
|
1079
|
+
const magnet = magnetize(
|
|
1080
|
+
{ x: nextX, y: nextY, width: current.bounds.width, height: current.bounds.height },
|
|
1081
|
+
targets,
|
|
1082
|
+
ctx.magnetThreshold
|
|
1083
|
+
);
|
|
1084
|
+
nextX = magnet.x;
|
|
1085
|
+
nextY = magnet.y;
|
|
1086
|
+
}
|
|
1087
|
+
wm.move(id, nextX, nextY);
|
|
843
1088
|
if (ctx.snapEnabled && current.snappable) {
|
|
844
1089
|
const viewport = wm.getState().viewport;
|
|
845
1090
|
const rawZone = detectSnapZone(session.pendingX, session.pendingY, viewport, ctx.snapDetect);
|
|
@@ -919,14 +1164,17 @@ function createDragStarter(ctx) {
|
|
|
919
1164
|
wm.move(id, session.startBounds.x, session.startBounds.y);
|
|
920
1165
|
}
|
|
921
1166
|
}
|
|
1167
|
+
wm.endInteraction();
|
|
922
1168
|
return;
|
|
923
1169
|
}
|
|
924
1170
|
if (session.moved && session.zone) {
|
|
925
1171
|
if (session.zone === "maximize") wm.maximize(id);
|
|
926
1172
|
else wm.snap(id, session.zone);
|
|
927
1173
|
}
|
|
1174
|
+
wm.endInteraction();
|
|
928
1175
|
}
|
|
929
1176
|
session.finish = finish;
|
|
1177
|
+
wm.beginInteraction();
|
|
930
1178
|
ctx.claimDrag(session);
|
|
931
1179
|
handle.setPointerCapture(event.pointerId);
|
|
932
1180
|
handle.addEventListener("pointermove", onMove);
|
|
@@ -956,6 +1204,7 @@ function createResizeStarter(ctx) {
|
|
|
956
1204
|
event.preventDefault();
|
|
957
1205
|
event.stopPropagation();
|
|
958
1206
|
const handleEl = event.currentTarget;
|
|
1207
|
+
wm.beginInteraction();
|
|
959
1208
|
const releaseRect = ctx.trackRect();
|
|
960
1209
|
const startPoint = ctx.toLocal(event);
|
|
961
1210
|
const start = win.bounds;
|
|
@@ -1013,6 +1262,7 @@ function createResizeStarter(ctx) {
|
|
|
1013
1262
|
}
|
|
1014
1263
|
if (el) delete el.dataset.wmResizing;
|
|
1015
1264
|
if (cancelled) wm.resize(id, start);
|
|
1265
|
+
wm.endInteraction();
|
|
1016
1266
|
}
|
|
1017
1267
|
function onUp(upEvent) {
|
|
1018
1268
|
if (upEvent.pointerId !== event.pointerId) return;
|
|
@@ -1071,6 +1321,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1071
1321
|
const cycleEnabled = keyboardOptions.cycle !== false;
|
|
1072
1322
|
const hitEdge = options.hitAreas?.edge ?? (coarsePointer ? 16 : 8);
|
|
1073
1323
|
const hitCorner = options.hitAreas?.corner ?? (coarsePointer ? 24 : 12);
|
|
1324
|
+
const magnetThreshold = options.magnetism === false ? 0 : (typeof options.magnetism === "object" ? options.magnetism.threshold : void 0) ?? (coarsePointer ? 12 : 8);
|
|
1074
1325
|
element.dataset.wmDesktop = "";
|
|
1075
1326
|
if (view.getComputedStyle(element).position === "static") {
|
|
1076
1327
|
element.style.position = "relative";
|
|
@@ -1141,6 +1392,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1141
1392
|
topEdge,
|
|
1142
1393
|
hitEdge,
|
|
1143
1394
|
hitCorner,
|
|
1395
|
+
magnetThreshold,
|
|
1144
1396
|
currentDrag: () => drag,
|
|
1145
1397
|
claimDrag(session) {
|
|
1146
1398
|
drag = session;
|
|
@@ -1229,10 +1481,15 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1229
1481
|
);
|
|
1230
1482
|
cleanup.push(
|
|
1231
1483
|
wm.on("stage", ({ window: win, previous }) => {
|
|
1232
|
-
if (win.stage !== "minimized" || previous === "minimized") return;
|
|
1233
1484
|
const attached = registry.get(win.id);
|
|
1234
|
-
|
|
1235
|
-
if (
|
|
1485
|
+
if (!attached) return;
|
|
1486
|
+
if (win.stage === "minimized" && previous !== "minimized") {
|
|
1487
|
+
const target = options.minimizeTarget?.(win);
|
|
1488
|
+
if (target) flipToTarget(attached.element, target);
|
|
1489
|
+
} else if (previous === "minimized" && win.stage !== "minimized") {
|
|
1490
|
+
const target = options.minimizeTarget?.(win);
|
|
1491
|
+
if (target) flipFromTarget(attached.element, target);
|
|
1492
|
+
}
|
|
1236
1493
|
})
|
|
1237
1494
|
);
|
|
1238
1495
|
if (keyboardEnabled && cycleEnabled) {
|
|
@@ -1308,6 +1565,16 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1308
1565
|
};
|
|
1309
1566
|
handle.addEventListener("dblclick", onDoubleClick);
|
|
1310
1567
|
attached.cleanup.push(() => handle.removeEventListener("dblclick", onDoubleClick));
|
|
1568
|
+
if (options.onTitlebarContextMenu) {
|
|
1569
|
+
const onContextMenu = (event) => {
|
|
1570
|
+
const current = wm.get(id);
|
|
1571
|
+
if (!current) return;
|
|
1572
|
+
event.preventDefault();
|
|
1573
|
+
options.onTitlebarContextMenu?.(current, event);
|
|
1574
|
+
};
|
|
1575
|
+
handle.addEventListener("contextmenu", onContextMenu);
|
|
1576
|
+
attached.cleanup.push(() => handle.removeEventListener("contextmenu", onContextMenu));
|
|
1577
|
+
}
|
|
1311
1578
|
}
|
|
1312
1579
|
if (windowOptions.resizeHandles !== false) {
|
|
1313
1580
|
for (const { element: resizeHandle, direction } of createResizeHandles(
|
|
@@ -1450,6 +1717,6 @@ function createDesktopBinder(wm, options = {}) {
|
|
|
1450
1717
|
};
|
|
1451
1718
|
}
|
|
1452
1719
|
|
|
1453
|
-
export { attachDesktop, boundsEqual, clamp, clampSize, clampToViewport, createAnnouncer, createDesktopBinder, createEmitter, createWindowManager, defaultMessages, detectSnapZone, flipToTarget, prefersReducedMotion, zoneBounds };
|
|
1454
|
-
//# sourceMappingURL=chunk-
|
|
1455
|
-
//# sourceMappingURL=chunk-
|
|
1720
|
+
export { attachDesktop, boundsEqual, clamp, clampSize, clampToViewport, createAnnouncer, createDesktopBinder, createEmitter, createWindowManager, defaultMessages, detectSnapZone, flipToTarget, magnetize, prefersReducedMotion, zoneBounds };
|
|
1721
|
+
//# sourceMappingURL=chunk-YCHJXSTC.js.map
|
|
1722
|
+
//# sourceMappingURL=chunk-YCHJXSTC.js.map
|