@surdeddd/wmkit 0.1.0 → 0.2.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 +14 -2
- package/README.ru.md +8 -2
- package/dist/{controller-D5zIriLg.d.ts → binder-BY-saDUB.d.cts} +9 -3
- package/dist/{controller-B0bogK9N.d.cts → binder-D9UEE1SM.d.ts} +9 -3
- package/dist/{chunk-7HHDQEBI.js → chunk-2TVOEDRG.js} +368 -247
- package/dist/chunk-2TVOEDRG.js.map +1 -0
- package/dist/{chunk-KWLI7JIY.cjs → chunk-KQCVZ2W7.cjs} +368 -247
- package/dist/chunk-KQCVZ2W7.cjs.map +1 -0
- package/dist/index.cjs +15 -15
- package/dist/index.d.cts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +1 -1
- package/dist/persist.cjs +1 -1
- package/dist/persist.cjs.map +1 -1
- package/dist/persist.d.cts +1 -1
- package/dist/persist.d.ts +1 -1
- package/dist/persist.js +1 -1
- package/dist/persist.js.map +1 -1
- package/dist/popout.cjs +1 -1
- package/dist/popout.cjs.map +1 -1
- package/dist/popout.d.cts +1 -1
- package/dist/popout.d.ts +1 -1
- package/dist/popout.js +1 -1
- package/dist/popout.js.map +1 -1
- package/dist/react.cjs +3 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/solid.cjs +3 -3
- package/dist/solid.cjs.map +1 -1
- package/dist/solid.d.cts +2 -2
- package/dist/solid.d.ts +2 -2
- package/dist/solid.js +1 -1
- package/dist/solid.js.map +1 -1
- package/dist/svelte.cjs +4 -4
- package/dist/svelte.cjs.map +1 -1
- package/dist/svelte.d.cts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +2 -2
- package/dist/svelte.js.map +1 -1
- package/dist/themes/glass.css +0 -1
- package/dist/{types-CtFzL_oA.d.cts → types-Bkrq2djr.d.cts} +9 -2
- package/dist/{types-CtFzL_oA.d.ts → types-Bkrq2djr.d.ts} +9 -2
- package/dist/vue.cjs +3 -3
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.d.cts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +1 -1
- package/dist/vue.js.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-7HHDQEBI.js.map +0 -1
- package/dist/chunk-KWLI7JIY.cjs.map +0 -1
|
@@ -139,12 +139,7 @@ function createWindowManager(options = {}) {
|
|
|
139
139
|
}
|
|
140
140
|
function commit() {
|
|
141
141
|
snapshot = null;
|
|
142
|
-
|
|
143
|
-
batchDirty = true;
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
flushEvents();
|
|
147
|
-
emitter.emit("change", { state: getState() });
|
|
142
|
+
batchDirty = true;
|
|
148
143
|
}
|
|
149
144
|
function flushEvents() {
|
|
150
145
|
while (pendingEvents.length > 0) {
|
|
@@ -153,7 +148,6 @@ function createWindowManager(options = {}) {
|
|
|
153
148
|
}
|
|
154
149
|
function queueEvent(emit) {
|
|
155
150
|
pendingEvents.push(emit);
|
|
156
|
-
if (batchDepth === 0) flushEvents();
|
|
157
151
|
}
|
|
158
152
|
function setWindow(next) {
|
|
159
153
|
windows = { ...windows, [next.id]: next };
|
|
@@ -217,7 +211,12 @@ function createWindowManager(options = {}) {
|
|
|
217
211
|
return { x: init.x ?? base.x, y: init.y ?? base.y };
|
|
218
212
|
}
|
|
219
213
|
function open(init = {}) {
|
|
220
|
-
|
|
214
|
+
let id = init.id;
|
|
215
|
+
if (id === void 0) {
|
|
216
|
+
do {
|
|
217
|
+
id = `${idPrefix}-${++idCounter}`;
|
|
218
|
+
} while (windows[id]);
|
|
219
|
+
}
|
|
221
220
|
if (windows[id]) throw new Error(`wmkit: window id "${id}" already exists`);
|
|
222
221
|
const minSize = { width: init.minWidth ?? 160, height: init.minHeight ?? 100 };
|
|
223
222
|
const maxSize = init.maxWidth !== void 0 || init.maxHeight !== void 0 ? {
|
|
@@ -295,9 +294,7 @@ function createWindowManager(options = {}) {
|
|
|
295
294
|
return true;
|
|
296
295
|
}
|
|
297
296
|
function closeAll() {
|
|
298
|
-
|
|
299
|
-
for (const id of [...order]) close(id);
|
|
300
|
-
});
|
|
297
|
+
for (const id of [...order]) close(id);
|
|
301
298
|
}
|
|
302
299
|
function focus(id) {
|
|
303
300
|
const win = windows[id];
|
|
@@ -504,6 +501,11 @@ function createWindowManager(options = {}) {
|
|
|
504
501
|
if (patch.layer && patch.layer !== win.layer) {
|
|
505
502
|
order = sortByLayer(order);
|
|
506
503
|
queueEvent(() => emitter.emit("order", { order }));
|
|
504
|
+
if (patch.layer === "modal" && topModalId() === id && focusedId !== id) {
|
|
505
|
+
const previous = focusedId;
|
|
506
|
+
focusedId = id;
|
|
507
|
+
emitFocus(finalWin, previous);
|
|
508
|
+
}
|
|
507
509
|
}
|
|
508
510
|
queueEvent(() => emitter.emit("update", { window: finalWin }));
|
|
509
511
|
if (resized) queueEvent(() => emitter.emit("resize", { window: finalWin }));
|
|
@@ -513,7 +515,7 @@ function createWindowManager(options = {}) {
|
|
|
513
515
|
function setViewport(next) {
|
|
514
516
|
if (next.width === viewport.width && next.height === viewport.height) return;
|
|
515
517
|
viewport = { ...next };
|
|
516
|
-
|
|
518
|
+
transact(() => {
|
|
517
519
|
for (const id of order) {
|
|
518
520
|
const win = windows[id];
|
|
519
521
|
if (win.stage === "maximized") {
|
|
@@ -540,10 +542,10 @@ function createWindowManager(options = {}) {
|
|
|
540
542
|
function minimized() {
|
|
541
543
|
return Object.values(windows).filter((win) => win.stage === "minimized").sort((a, b) => a.openedSeq - b.openedSeq);
|
|
542
544
|
}
|
|
543
|
-
function
|
|
545
|
+
function transact(run) {
|
|
544
546
|
batchDepth += 1;
|
|
545
547
|
try {
|
|
546
|
-
run();
|
|
548
|
+
return run();
|
|
547
549
|
} finally {
|
|
548
550
|
batchDepth -= 1;
|
|
549
551
|
if (batchDepth === 0 && batchDirty) {
|
|
@@ -562,7 +564,10 @@ function createWindowManager(options = {}) {
|
|
|
562
564
|
bounds: { ...win.bounds },
|
|
563
565
|
restoreBounds: win.restoreBounds ? { ...win.restoreBounds } : null,
|
|
564
566
|
minSize: { ...win.minSize },
|
|
565
|
-
maxSize: win.maxSize ? {
|
|
567
|
+
maxSize: win.maxSize ? {
|
|
568
|
+
width: Number.isFinite(win.maxSize.width) ? win.maxSize.width : null,
|
|
569
|
+
height: Number.isFinite(win.maxSize.height) ? win.maxSize.height : null
|
|
570
|
+
} : null,
|
|
566
571
|
meta: { ...win.meta }
|
|
567
572
|
})),
|
|
568
573
|
order: [...order],
|
|
@@ -579,6 +584,19 @@ function createWindowManager(options = {}) {
|
|
|
579
584
|
const size = value;
|
|
580
585
|
return typeof size.width === "number" && typeof size.height === "number";
|
|
581
586
|
}
|
|
587
|
+
function isSizeAxis(value) {
|
|
588
|
+
return value === null || typeof value === "number";
|
|
589
|
+
}
|
|
590
|
+
function readMaxSize(value) {
|
|
591
|
+
if (typeof value !== "object" || value === null) return null;
|
|
592
|
+
const size = value;
|
|
593
|
+
if (!isSizeAxis(size.width) || !isSizeAxis(size.height)) return null;
|
|
594
|
+
if (size.width === null && size.height === null) return null;
|
|
595
|
+
return {
|
|
596
|
+
width: size.width ?? Number.POSITIVE_INFINITY,
|
|
597
|
+
height: size.height ?? Number.POSITIVE_INFINITY
|
|
598
|
+
};
|
|
599
|
+
}
|
|
582
600
|
function isSerializedWindow(value) {
|
|
583
601
|
if (typeof value !== "object" || value === null) return false;
|
|
584
602
|
const win = value;
|
|
@@ -602,7 +620,7 @@ function createWindowManager(options = {}) {
|
|
|
602
620
|
snapZone: ZONES.includes(raw.snapZone) ? raw.snapZone : null,
|
|
603
621
|
layer: raw.layer,
|
|
604
622
|
minSize: isSize(raw.minSize) ? { ...raw.minSize } : { width: 160, height: 100 },
|
|
605
|
-
maxSize:
|
|
623
|
+
maxSize: readMaxSize(raw.maxSize),
|
|
606
624
|
openedSeq: typeof raw.openedSeq === "number" ? raw.openedSeq : ++maxSeq,
|
|
607
625
|
draggable: raw.draggable !== false,
|
|
608
626
|
resizable: raw.resizable !== false,
|
|
@@ -634,6 +652,11 @@ function createWindowManager(options = {}) {
|
|
|
634
652
|
focusedId = data.focusedId && windows[data.focusedId] ? data.focusedId : null;
|
|
635
653
|
if (focusedId && windows[focusedId]?.stage === "minimized") focusedId = null;
|
|
636
654
|
if (!focusedId) focusTop();
|
|
655
|
+
const modal = topModalId();
|
|
656
|
+
if (modal) {
|
|
657
|
+
const focusedWin = focusedId ? windows[focusedId] : null;
|
|
658
|
+
if (focusedWin?.layer !== "modal") focusedId = modal;
|
|
659
|
+
}
|
|
637
660
|
commit();
|
|
638
661
|
return true;
|
|
639
662
|
}
|
|
@@ -641,29 +664,29 @@ function createWindowManager(options = {}) {
|
|
|
641
664
|
emitter.clear();
|
|
642
665
|
}
|
|
643
666
|
return {
|
|
644
|
-
open,
|
|
645
|
-
close,
|
|
646
|
-
closeAll,
|
|
647
|
-
focus,
|
|
648
|
-
blur,
|
|
649
|
-
cycleFocus,
|
|
650
|
-
minimize,
|
|
651
|
-
maximize,
|
|
652
|
-
toggleMaximize,
|
|
653
|
-
restore,
|
|
654
|
-
restoreTo,
|
|
655
|
-
snap,
|
|
656
|
-
move,
|
|
657
|
-
moveBy,
|
|
658
|
-
resize,
|
|
659
|
-
update,
|
|
667
|
+
open: (init) => transact(() => open(init)),
|
|
668
|
+
close: (id) => transact(() => close(id)),
|
|
669
|
+
closeAll: () => transact(closeAll),
|
|
670
|
+
focus: (id) => transact(() => focus(id)),
|
|
671
|
+
blur: () => transact(blur),
|
|
672
|
+
cycleFocus: (direction) => transact(() => cycleFocus(direction)),
|
|
673
|
+
minimize: (id) => transact(() => minimize(id)),
|
|
674
|
+
maximize: (id) => transact(() => maximize(id)),
|
|
675
|
+
toggleMaximize: (id) => transact(() => toggleMaximize(id)),
|
|
676
|
+
restore: (id) => transact(() => restore(id)),
|
|
677
|
+
restoreTo: (id, bounds) => transact(() => restoreTo(id, bounds)),
|
|
678
|
+
snap: (id, zone) => transact(() => snap(id, zone)),
|
|
679
|
+
move: (id, x, y) => transact(() => move(id, x, y)),
|
|
680
|
+
moveBy: (id, dx, dy) => transact(() => moveBy(id, dx, dy)),
|
|
681
|
+
resize: (id, patch) => transact(() => resize(id, patch)),
|
|
682
|
+
update: (id, patch) => transact(() => update(id, patch)),
|
|
660
683
|
get: (id) => windows[id],
|
|
661
684
|
getState,
|
|
662
685
|
minimized,
|
|
663
|
-
setViewport,
|
|
664
|
-
batch,
|
|
686
|
+
setViewport: (next) => transact(() => setViewport(next)),
|
|
687
|
+
batch: (run) => transact(run),
|
|
665
688
|
serialize,
|
|
666
|
-
hydrate,
|
|
689
|
+
hydrate: (data) => transact(() => hydrate(data)),
|
|
667
690
|
subscribe: (listener) => emitter.on("change", ({ state }) => listener(state)),
|
|
668
691
|
on: (event, listener) => emitter.on(event, listener),
|
|
669
692
|
destroy
|
|
@@ -751,175 +774,25 @@ function createAnnouncer(wm, container, messages = {}) {
|
|
|
751
774
|
};
|
|
752
775
|
}
|
|
753
776
|
|
|
754
|
-
// src/dom/
|
|
755
|
-
var RESIZE_DIRECTIONS = ["n", "e", "s", "w", "ne", "nw", "se", "sw"];
|
|
756
|
-
var RESIZE_CURSORS = {
|
|
757
|
-
n: "ns-resize",
|
|
758
|
-
s: "ns-resize",
|
|
759
|
-
e: "ew-resize",
|
|
760
|
-
w: "ew-resize",
|
|
761
|
-
ne: "nesw-resize",
|
|
762
|
-
sw: "nesw-resize",
|
|
763
|
-
nw: "nwse-resize",
|
|
764
|
-
se: "nwse-resize"
|
|
765
|
-
};
|
|
777
|
+
// src/dom/shared.ts
|
|
766
778
|
var INTERACTIVE_SELECTOR = "button, input, select, textarea, a[href], [contenteditable], [data-wm-close], [data-wm-minimize], [data-wm-maximize]";
|
|
767
779
|
function windowOf(element) {
|
|
768
780
|
const view = element.ownerDocument.defaultView;
|
|
769
781
|
if (!view) throw new Error("wmkit: desktop element is not attached to a document");
|
|
770
782
|
return view;
|
|
771
783
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
const snapPreviewEnabled = snapOptions.preview !== false;
|
|
778
|
-
const topEdge = snapOptions.topEdge ?? "maximize";
|
|
779
|
-
const keyboardEnabled = options.keyboard !== false;
|
|
780
|
-
const keyboardOptions = typeof options.keyboard === "object" ? options.keyboard : {};
|
|
781
|
-
const moveStep = keyboardOptions.moveStep ?? 16;
|
|
782
|
-
const cycleEnabled = keyboardOptions.cycle !== false;
|
|
783
|
-
element.dataset.wmDesktop = "";
|
|
784
|
-
if (view.getComputedStyle(element).position === "static") {
|
|
785
|
-
element.style.position = "relative";
|
|
786
|
-
}
|
|
787
|
-
const registry = /* @__PURE__ */ new Map();
|
|
788
|
-
const cleanup = [];
|
|
789
|
-
let lastOrder = null;
|
|
790
|
-
let lastFocused = null;
|
|
791
|
-
let drag = null;
|
|
792
|
-
let announcer = null;
|
|
793
|
-
if (options.announce !== false) {
|
|
794
|
-
announcer = createAnnouncer(
|
|
795
|
-
wm,
|
|
796
|
-
element,
|
|
797
|
-
typeof options.announce === "object" ? options.announce : {}
|
|
798
|
-
);
|
|
799
|
-
cleanup.push(() => announcer?.destroy());
|
|
800
|
-
}
|
|
801
|
-
let preview = null;
|
|
802
|
-
function showPreview(bounds) {
|
|
803
|
-
if (!snapPreviewEnabled) return;
|
|
804
|
-
if (!preview) {
|
|
805
|
-
preview = doc.createElement("div");
|
|
806
|
-
preview.dataset.wmSnapPreview = "";
|
|
807
|
-
preview.style.cssText = "position:absolute;left:0;top:0;pointer-events:none;display:none;z-index:2147483646";
|
|
808
|
-
element.append(preview);
|
|
809
|
-
}
|
|
810
|
-
preview.style.display = "block";
|
|
811
|
-
preview.style.transform = `translate3d(${bounds.x}px, ${bounds.y}px, 0)`;
|
|
812
|
-
preview.style.width = `${bounds.width}px`;
|
|
813
|
-
preview.style.height = `${bounds.height}px`;
|
|
814
|
-
}
|
|
815
|
-
function hidePreview() {
|
|
816
|
-
if (preview) preview.style.display = "none";
|
|
817
|
-
}
|
|
818
|
-
if (options.autoViewport !== false) {
|
|
819
|
-
const applyViewport = () => wm.setViewport({ width: element.clientWidth, height: element.clientHeight });
|
|
820
|
-
applyViewport();
|
|
821
|
-
const observer = new ResizeObserver(applyViewport);
|
|
822
|
-
observer.observe(element);
|
|
823
|
-
cleanup.push(() => observer.disconnect());
|
|
824
|
-
}
|
|
825
|
-
function syncWindow(attached, win, zIndex) {
|
|
826
|
-
const el = attached.element;
|
|
827
|
-
const firstSync = attached.lastState === null;
|
|
828
|
-
if (firstSync) el.style.transition = "none";
|
|
829
|
-
if (attached.lastState !== win) {
|
|
830
|
-
el.style.transform = `translate3d(${win.bounds.x}px, ${win.bounds.y}px, 0)`;
|
|
831
|
-
el.style.width = `${win.bounds.width}px`;
|
|
832
|
-
el.style.height = `${win.bounds.height}px`;
|
|
833
|
-
el.dataset.wmStage = win.stage;
|
|
834
|
-
el.dataset.wmLayer = win.layer;
|
|
835
|
-
el.hidden = win.stage === "minimized";
|
|
836
|
-
el.setAttribute("aria-label", win.title);
|
|
837
|
-
if (win.layer === "modal") el.setAttribute("aria-modal", "true");
|
|
838
|
-
else el.removeAttribute("aria-modal");
|
|
839
|
-
for (const handle of attached.handles) {
|
|
840
|
-
handle.style.display = win.resizable && win.stage === "normal" ? "" : "none";
|
|
841
|
-
}
|
|
842
|
-
attached.lastState = win;
|
|
843
|
-
}
|
|
844
|
-
el.style.zIndex = String(zIndex + 1);
|
|
845
|
-
if (firstSync) {
|
|
846
|
-
void el.offsetWidth;
|
|
847
|
-
el.style.transition = "";
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
function syncAll() {
|
|
851
|
-
const state = wm.getState();
|
|
852
|
-
const orderChanged = state.order !== lastOrder;
|
|
853
|
-
state.order.forEach((id, index) => {
|
|
854
|
-
const attached = registry.get(id);
|
|
855
|
-
const win = state.windows[id];
|
|
856
|
-
if (!attached || !win) return;
|
|
857
|
-
if (orderChanged || attached.lastState !== win) syncWindow(attached, win, index);
|
|
858
|
-
});
|
|
859
|
-
if (state.focusedId !== lastFocused) {
|
|
860
|
-
if (lastFocused) {
|
|
861
|
-
const prev = registry.get(lastFocused);
|
|
862
|
-
if (prev) delete prev.element.dataset.wmFocused;
|
|
863
|
-
}
|
|
864
|
-
if (state.focusedId) {
|
|
865
|
-
const next = registry.get(state.focusedId);
|
|
866
|
-
if (next) next.element.dataset.wmFocused = "";
|
|
867
|
-
}
|
|
868
|
-
lastFocused = state.focusedId;
|
|
869
|
-
}
|
|
870
|
-
lastOrder = state.order;
|
|
871
|
-
}
|
|
872
|
-
cleanup.push(wm.subscribe(syncAll));
|
|
873
|
-
cleanup.push(
|
|
874
|
-
wm.on("focus", ({ window: win }) => {
|
|
875
|
-
const attached = registry.get(win.id);
|
|
876
|
-
if (!attached) return;
|
|
877
|
-
if (!attached.element.contains(doc.activeElement)) {
|
|
878
|
-
attached.element.focus({ preventScroll: true });
|
|
879
|
-
}
|
|
880
|
-
})
|
|
881
|
-
);
|
|
882
|
-
cleanup.push(
|
|
883
|
-
wm.on("modalblocked", ({ window: win }) => {
|
|
884
|
-
const attached = registry.get(win.id);
|
|
885
|
-
if (!attached) return;
|
|
886
|
-
delete attached.element.dataset.wmFlash;
|
|
887
|
-
void attached.element.offsetWidth;
|
|
888
|
-
attached.element.dataset.wmFlash = "";
|
|
889
|
-
})
|
|
890
|
-
);
|
|
891
|
-
cleanup.push(
|
|
892
|
-
wm.on("stage", ({ window: win, previous }) => {
|
|
893
|
-
if (win.stage !== "minimized" || previous === "minimized") return;
|
|
894
|
-
const attached = registry.get(win.id);
|
|
895
|
-
const target = options.minimizeTarget?.(win);
|
|
896
|
-
if (attached && target) flipToTarget(attached.element, target);
|
|
897
|
-
})
|
|
898
|
-
);
|
|
899
|
-
if (keyboardEnabled && cycleEnabled) {
|
|
900
|
-
const onDesktopKeydown = (event) => {
|
|
901
|
-
if (event.key === "F6") {
|
|
902
|
-
event.preventDefault();
|
|
903
|
-
wm.cycleFocus(event.shiftKey ? -1 : 1);
|
|
904
|
-
}
|
|
905
|
-
};
|
|
906
|
-
element.addEventListener("keydown", onDesktopKeydown);
|
|
907
|
-
cleanup.push(() => element.removeEventListener("keydown", onDesktopKeydown));
|
|
908
|
-
}
|
|
909
|
-
function desktopPoint(event) {
|
|
910
|
-
const rect = element.getBoundingClientRect();
|
|
911
|
-
return { x: event.clientX - rect.left, y: event.clientY - rect.top };
|
|
912
|
-
}
|
|
913
|
-
function endDrag(cancelled) {
|
|
914
|
-
if (drag) drag.finish(cancelled);
|
|
915
|
-
}
|
|
916
|
-
function startDrag(id, handle, event) {
|
|
784
|
+
|
|
785
|
+
// src/dom/drag.ts
|
|
786
|
+
function createDragStarter(ctx) {
|
|
787
|
+
const { wm, doc, view } = ctx;
|
|
788
|
+
return function startDrag(id, handle, event) {
|
|
917
789
|
const win = wm.get(id);
|
|
918
|
-
if (!win?.draggable || event.button !== 0 ||
|
|
790
|
+
if (!win?.draggable || event.button !== 0 || ctx.currentDrag()) return;
|
|
919
791
|
const target = event.target;
|
|
920
792
|
if (target?.closest(INTERACTIVE_SELECTOR)) return;
|
|
921
793
|
event.preventDefault();
|
|
922
|
-
const
|
|
794
|
+
const releaseRect = ctx.trackRect();
|
|
795
|
+
const point = ctx.toLocal(event);
|
|
923
796
|
const startBounds = win.bounds;
|
|
924
797
|
const session = {
|
|
925
798
|
id,
|
|
@@ -928,6 +801,9 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
928
801
|
grabDY: point.y - startBounds.y,
|
|
929
802
|
grabRatio: clamp((point.x - startBounds.x) / startBounds.width, 0.05, 0.95),
|
|
930
803
|
startBounds,
|
|
804
|
+
startStage: win.stage,
|
|
805
|
+
startZone: win.snapZone,
|
|
806
|
+
startRestoreBounds: win.restoreBounds,
|
|
931
807
|
restored: win.stage === "normal",
|
|
932
808
|
moved: false,
|
|
933
809
|
zone: null,
|
|
@@ -938,10 +814,9 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
938
814
|
finish: () => {
|
|
939
815
|
}
|
|
940
816
|
};
|
|
941
|
-
const
|
|
942
|
-
const el = attached?.element;
|
|
817
|
+
const el = ctx.windowElement(id);
|
|
943
818
|
function flush() {
|
|
944
|
-
if (!session.hasPending ||
|
|
819
|
+
if (!session.hasPending || ctx.currentDrag() !== session) return;
|
|
945
820
|
session.hasPending = false;
|
|
946
821
|
session.raf = 0;
|
|
947
822
|
const current = wm.get(id);
|
|
@@ -965,32 +840,35 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
965
840
|
return;
|
|
966
841
|
}
|
|
967
842
|
wm.move(id, session.pendingX - session.grabDX, session.pendingY - session.grabDY);
|
|
968
|
-
if (snapEnabled && current.snappable) {
|
|
843
|
+
if (ctx.snapEnabled && current.snappable) {
|
|
969
844
|
const viewport = wm.getState().viewport;
|
|
970
|
-
const rawZone = detectSnapZone(session.pendingX, session.pendingY, viewport,
|
|
845
|
+
const rawZone = detectSnapZone(session.pendingX, session.pendingY, viewport, ctx.snapDetect);
|
|
971
846
|
let zone = rawZone;
|
|
972
847
|
if (rawZone === "top") {
|
|
973
|
-
if (topEdge === "maximize") zone = current.maximizable ? "maximize" : null;
|
|
974
|
-
else if (topEdge === "none") zone = null;
|
|
848
|
+
if (ctx.topEdge === "maximize") zone = current.maximizable ? "maximize" : null;
|
|
849
|
+
else if (ctx.topEdge === "none") zone = null;
|
|
975
850
|
}
|
|
976
851
|
session.zone = zone;
|
|
977
852
|
if (zone) {
|
|
978
|
-
showPreview(
|
|
853
|
+
ctx.showPreview(
|
|
979
854
|
zone === "maximize" ? { x: 0, y: 0, width: viewport.width, height: viewport.height } : zoneBounds(zone, viewport)
|
|
980
855
|
);
|
|
981
856
|
} else {
|
|
982
|
-
hidePreview();
|
|
857
|
+
ctx.hidePreview();
|
|
983
858
|
}
|
|
984
859
|
}
|
|
985
860
|
}
|
|
986
861
|
function onMove(moveEvent) {
|
|
987
862
|
if (moveEvent.pointerId !== session.pointerId) return;
|
|
988
|
-
const movePoint =
|
|
863
|
+
const movePoint = ctx.toLocal(moveEvent);
|
|
989
864
|
if (!session.moved) {
|
|
990
865
|
const travelled = Math.abs(movePoint.x - (session.startBounds.x + session.grabDX)) + Math.abs(movePoint.y - (session.startBounds.y + session.grabDY));
|
|
991
866
|
if (travelled < 3 && session.restored) return;
|
|
992
867
|
session.moved = true;
|
|
993
|
-
if (el)
|
|
868
|
+
if (el) {
|
|
869
|
+
el.dataset.wmDragging = "";
|
|
870
|
+
el.style.willChange = "transform";
|
|
871
|
+
}
|
|
994
872
|
}
|
|
995
873
|
session.pendingX = movePoint.x;
|
|
996
874
|
session.pendingY = movePoint.y;
|
|
@@ -1012,10 +890,11 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1012
890
|
}
|
|
1013
891
|
}
|
|
1014
892
|
function finish(cancelled) {
|
|
1015
|
-
if (
|
|
1016
|
-
if (session.raf !== 0) view
|
|
893
|
+
if (ctx.currentDrag() !== session) return;
|
|
894
|
+
if (session.raf !== 0) view.cancelAnimationFrame(session.raf);
|
|
1017
895
|
if (session.hasPending && !cancelled) flush();
|
|
1018
|
-
|
|
896
|
+
ctx.releaseDrag(session);
|
|
897
|
+
releaseRect();
|
|
1019
898
|
handle.removeEventListener("pointermove", onMove);
|
|
1020
899
|
handle.removeEventListener("pointerup", onUp);
|
|
1021
900
|
handle.removeEventListener("pointercancel", onCancel);
|
|
@@ -1023,11 +902,22 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1023
902
|
if (handle.hasPointerCapture(session.pointerId)) {
|
|
1024
903
|
handle.releasePointerCapture(session.pointerId);
|
|
1025
904
|
}
|
|
1026
|
-
if (el)
|
|
1027
|
-
|
|
905
|
+
if (el) {
|
|
906
|
+
delete el.dataset.wmDragging;
|
|
907
|
+
el.style.willChange = "";
|
|
908
|
+
}
|
|
909
|
+
ctx.hidePreview();
|
|
1028
910
|
if (cancelled) {
|
|
1029
911
|
if (session.moved && session.restored) {
|
|
1030
|
-
|
|
912
|
+
if (session.startStage === "maximized") {
|
|
913
|
+
wm.restoreTo(id, session.startRestoreBounds ?? session.startBounds);
|
|
914
|
+
wm.maximize(id);
|
|
915
|
+
} else if (session.startStage === "snapped" && session.startZone) {
|
|
916
|
+
wm.restoreTo(id, session.startRestoreBounds ?? session.startBounds);
|
|
917
|
+
wm.snap(id, session.startZone);
|
|
918
|
+
} else {
|
|
919
|
+
wm.move(id, session.startBounds.x, session.startBounds.y);
|
|
920
|
+
}
|
|
1031
921
|
}
|
|
1032
922
|
return;
|
|
1033
923
|
}
|
|
@@ -1037,20 +927,37 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1037
927
|
}
|
|
1038
928
|
}
|
|
1039
929
|
session.finish = finish;
|
|
1040
|
-
|
|
930
|
+
ctx.claimDrag(session);
|
|
1041
931
|
handle.setPointerCapture(event.pointerId);
|
|
1042
932
|
handle.addEventListener("pointermove", onMove);
|
|
1043
933
|
handle.addEventListener("pointerup", onUp);
|
|
1044
934
|
handle.addEventListener("pointercancel", onCancel);
|
|
1045
935
|
doc.addEventListener("keydown", onKeydown, true);
|
|
1046
|
-
}
|
|
1047
|
-
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
// src/dom/resize.ts
|
|
940
|
+
var RESIZE_DIRECTIONS = ["n", "e", "s", "w", "ne", "nw", "se", "sw"];
|
|
941
|
+
var RESIZE_CURSORS = {
|
|
942
|
+
n: "ns-resize",
|
|
943
|
+
s: "ns-resize",
|
|
944
|
+
e: "ew-resize",
|
|
945
|
+
w: "ew-resize",
|
|
946
|
+
ne: "nesw-resize",
|
|
947
|
+
sw: "nesw-resize",
|
|
948
|
+
nw: "nwse-resize",
|
|
949
|
+
se: "nwse-resize"
|
|
950
|
+
};
|
|
951
|
+
function createResizeStarter(ctx) {
|
|
952
|
+
const { wm, doc, view } = ctx;
|
|
953
|
+
return function startResize(id, direction, event) {
|
|
1048
954
|
const win = wm.get(id);
|
|
1049
|
-
if (!win?.resizable || event.button !== 0 ||
|
|
955
|
+
if (!win?.resizable || event.button !== 0 || ctx.currentDrag()) return;
|
|
1050
956
|
event.preventDefault();
|
|
1051
957
|
event.stopPropagation();
|
|
1052
958
|
const handleEl = event.currentTarget;
|
|
1053
|
-
const
|
|
959
|
+
const releaseRect = ctx.trackRect();
|
|
960
|
+
const startPoint = ctx.toLocal(event);
|
|
1054
961
|
const start = win.bounds;
|
|
1055
962
|
const minSize = win.minSize;
|
|
1056
963
|
const maxSize = win.maxSize;
|
|
@@ -1058,8 +965,8 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1058
965
|
let pendingX = 0;
|
|
1059
966
|
let pendingY = 0;
|
|
1060
967
|
let hasPending = false;
|
|
1061
|
-
const
|
|
1062
|
-
if (
|
|
968
|
+
const el = ctx.windowElement(id);
|
|
969
|
+
if (el) el.dataset.wmResizing = direction;
|
|
1063
970
|
function clampWidth(width) {
|
|
1064
971
|
return clamp(width, minSize.width, maxSize ? maxSize.width : Number.POSITIVE_INFINITY);
|
|
1065
972
|
}
|
|
@@ -1087,15 +994,16 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1087
994
|
}
|
|
1088
995
|
function onMove(moveEvent) {
|
|
1089
996
|
if (moveEvent.pointerId !== event.pointerId) return;
|
|
1090
|
-
const movePoint =
|
|
997
|
+
const movePoint = ctx.toLocal(moveEvent);
|
|
1091
998
|
pendingX = movePoint.x;
|
|
1092
999
|
pendingY = movePoint.y;
|
|
1093
1000
|
hasPending = true;
|
|
1094
|
-
if (raf === 0) raf = view
|
|
1001
|
+
if (raf === 0) raf = view.requestAnimationFrame(flush);
|
|
1095
1002
|
}
|
|
1096
1003
|
function finish(cancelled) {
|
|
1097
|
-
if (raf !== 0) view
|
|
1004
|
+
if (raf !== 0) view.cancelAnimationFrame(raf);
|
|
1098
1005
|
if (hasPending && !cancelled) flush();
|
|
1006
|
+
releaseRect();
|
|
1099
1007
|
handleEl.removeEventListener("pointermove", onMove);
|
|
1100
1008
|
handleEl.removeEventListener("pointerup", onUp);
|
|
1101
1009
|
handleEl.removeEventListener("pointercancel", onCancelPointer);
|
|
@@ -1103,7 +1011,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1103
1011
|
if (handleEl.hasPointerCapture(event.pointerId)) {
|
|
1104
1012
|
handleEl.releasePointerCapture(event.pointerId);
|
|
1105
1013
|
}
|
|
1106
|
-
if (
|
|
1014
|
+
if (el) delete el.dataset.wmResizing;
|
|
1107
1015
|
if (cancelled) wm.resize(id, start);
|
|
1108
1016
|
}
|
|
1109
1017
|
function onUp(upEvent) {
|
|
@@ -1125,6 +1033,220 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1125
1033
|
handleEl.addEventListener("pointerup", onUp);
|
|
1126
1034
|
handleEl.addEventListener("pointercancel", onCancelPointer);
|
|
1127
1035
|
doc.addEventListener("keydown", onKeydown, true);
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
function createResizeHandles(doc, edge, corner) {
|
|
1039
|
+
const base = "position:absolute;touch-action:none;user-select:none;-webkit-user-select:none;";
|
|
1040
|
+
const styles = {
|
|
1041
|
+
n: `top:${-edge / 2}px;left:${corner}px;right:${corner}px;height:${edge}px`,
|
|
1042
|
+
s: `bottom:${-edge / 2}px;left:${corner}px;right:${corner}px;height:${edge}px`,
|
|
1043
|
+
e: `right:${-edge / 2}px;top:${corner}px;bottom:${corner}px;width:${edge}px`,
|
|
1044
|
+
w: `left:${-edge / 2}px;top:${corner}px;bottom:${corner}px;width:${edge}px`,
|
|
1045
|
+
ne: `top:${-edge / 2}px;right:${-edge / 2}px;width:${corner}px;height:${corner}px`,
|
|
1046
|
+
nw: `top:${-edge / 2}px;left:${-edge / 2}px;width:${corner}px;height:${corner}px`,
|
|
1047
|
+
se: `bottom:${-edge / 2}px;right:${-edge / 2}px;width:${corner}px;height:${corner}px`,
|
|
1048
|
+
sw: `bottom:${-edge / 2}px;left:${-edge / 2}px;width:${corner}px;height:${corner}px`
|
|
1049
|
+
};
|
|
1050
|
+
return RESIZE_DIRECTIONS.map((direction) => {
|
|
1051
|
+
const element = doc.createElement("div");
|
|
1052
|
+
element.dataset.wmResize = direction;
|
|
1053
|
+
element.setAttribute("aria-hidden", "true");
|
|
1054
|
+
element.style.cssText = `${base}${styles[direction]};cursor:${RESIZE_CURSORS[direction]}`;
|
|
1055
|
+
return { element, direction };
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// src/dom/controller.ts
|
|
1060
|
+
function attachDesktop(wm, element, options = {}) {
|
|
1061
|
+
const doc = element.ownerDocument;
|
|
1062
|
+
const view = windowOf(element);
|
|
1063
|
+
const coarsePointer = typeof view.matchMedia === "function" && view.matchMedia("(pointer: coarse)").matches;
|
|
1064
|
+
const snapEnabled = options.snap !== false;
|
|
1065
|
+
const snapOptions = typeof options.snap === "object" ? options.snap : {};
|
|
1066
|
+
const snapPreviewEnabled = snapOptions.preview !== false;
|
|
1067
|
+
const topEdge = snapOptions.topEdge ?? "maximize";
|
|
1068
|
+
const keyboardEnabled = options.keyboard !== false;
|
|
1069
|
+
const keyboardOptions = typeof options.keyboard === "object" ? options.keyboard : {};
|
|
1070
|
+
const moveStep = keyboardOptions.moveStep ?? 16;
|
|
1071
|
+
const cycleEnabled = keyboardOptions.cycle !== false;
|
|
1072
|
+
const hitEdge = options.hitAreas?.edge ?? (coarsePointer ? 16 : 8);
|
|
1073
|
+
const hitCorner = options.hitAreas?.corner ?? (coarsePointer ? 24 : 12);
|
|
1074
|
+
element.dataset.wmDesktop = "";
|
|
1075
|
+
if (view.getComputedStyle(element).position === "static") {
|
|
1076
|
+
element.style.position = "relative";
|
|
1077
|
+
}
|
|
1078
|
+
const registry = /* @__PURE__ */ new Map();
|
|
1079
|
+
const cleanup = [];
|
|
1080
|
+
let lastOrder = null;
|
|
1081
|
+
let lastFocused = null;
|
|
1082
|
+
let drag = null;
|
|
1083
|
+
let cachedRect = null;
|
|
1084
|
+
let rectUsers = 0;
|
|
1085
|
+
let announcer = null;
|
|
1086
|
+
if (options.announce !== false) {
|
|
1087
|
+
announcer = createAnnouncer(
|
|
1088
|
+
wm,
|
|
1089
|
+
element,
|
|
1090
|
+
typeof options.announce === "object" ? options.announce : {}
|
|
1091
|
+
);
|
|
1092
|
+
cleanup.push(() => announcer?.destroy());
|
|
1093
|
+
}
|
|
1094
|
+
let preview = null;
|
|
1095
|
+
function showPreview(bounds) {
|
|
1096
|
+
if (!snapPreviewEnabled) return;
|
|
1097
|
+
if (!preview) {
|
|
1098
|
+
preview = doc.createElement("div");
|
|
1099
|
+
preview.dataset.wmSnapPreview = "";
|
|
1100
|
+
preview.style.cssText = "position:absolute;left:0;top:0;pointer-events:none;display:none;z-index:2147483646";
|
|
1101
|
+
element.append(preview);
|
|
1102
|
+
}
|
|
1103
|
+
preview.style.display = "block";
|
|
1104
|
+
preview.style.transform = `translate3d(${bounds.x}px, ${bounds.y}px, 0)`;
|
|
1105
|
+
preview.style.width = `${bounds.width}px`;
|
|
1106
|
+
preview.style.height = `${bounds.height}px`;
|
|
1107
|
+
}
|
|
1108
|
+
function hidePreview() {
|
|
1109
|
+
if (preview) preview.style.display = "none";
|
|
1110
|
+
}
|
|
1111
|
+
const ctx = {
|
|
1112
|
+
wm,
|
|
1113
|
+
doc,
|
|
1114
|
+
view,
|
|
1115
|
+
toLocal(event) {
|
|
1116
|
+
const rect = cachedRect ?? element.getBoundingClientRect();
|
|
1117
|
+
return { x: event.clientX - rect.left, y: event.clientY - rect.top };
|
|
1118
|
+
},
|
|
1119
|
+
trackRect() {
|
|
1120
|
+
if (rectUsers === 0) {
|
|
1121
|
+
const rect = element.getBoundingClientRect();
|
|
1122
|
+
cachedRect = { left: rect.left, top: rect.top };
|
|
1123
|
+
}
|
|
1124
|
+
rectUsers += 1;
|
|
1125
|
+
let released = false;
|
|
1126
|
+
return () => {
|
|
1127
|
+
if (released) return;
|
|
1128
|
+
released = true;
|
|
1129
|
+
rectUsers -= 1;
|
|
1130
|
+
if (rectUsers === 0) cachedRect = null;
|
|
1131
|
+
};
|
|
1132
|
+
},
|
|
1133
|
+
windowElement: (id) => registry.get(id)?.element,
|
|
1134
|
+
showPreview,
|
|
1135
|
+
hidePreview,
|
|
1136
|
+
snapEnabled,
|
|
1137
|
+
snapDetect: {
|
|
1138
|
+
threshold: snapOptions.threshold ?? (coarsePointer ? 20 : 12),
|
|
1139
|
+
cornerSize: snapOptions.cornerSize ?? (coarsePointer ? 96 : 64)
|
|
1140
|
+
},
|
|
1141
|
+
topEdge,
|
|
1142
|
+
hitEdge,
|
|
1143
|
+
hitCorner,
|
|
1144
|
+
currentDrag: () => drag,
|
|
1145
|
+
claimDrag(session) {
|
|
1146
|
+
drag = session;
|
|
1147
|
+
},
|
|
1148
|
+
releaseDrag(session) {
|
|
1149
|
+
if (drag === session) drag = null;
|
|
1150
|
+
}
|
|
1151
|
+
};
|
|
1152
|
+
const startDrag = createDragStarter(ctx);
|
|
1153
|
+
const startResize = createResizeStarter(ctx);
|
|
1154
|
+
if (options.autoViewport !== false) {
|
|
1155
|
+
const applyViewport = () => wm.setViewport({ width: element.clientWidth, height: element.clientHeight });
|
|
1156
|
+
applyViewport();
|
|
1157
|
+
const observer = new ResizeObserver(applyViewport);
|
|
1158
|
+
observer.observe(element);
|
|
1159
|
+
cleanup.push(() => observer.disconnect());
|
|
1160
|
+
}
|
|
1161
|
+
function syncWindow(attached, win, zIndex) {
|
|
1162
|
+
const el = attached.element;
|
|
1163
|
+
const firstSync = attached.lastState === null;
|
|
1164
|
+
if (firstSync) el.style.transition = "none";
|
|
1165
|
+
if (attached.lastState !== win) {
|
|
1166
|
+
el.style.transform = `translate3d(${win.bounds.x}px, ${win.bounds.y}px, 0)`;
|
|
1167
|
+
el.style.width = `${win.bounds.width}px`;
|
|
1168
|
+
el.style.height = `${win.bounds.height}px`;
|
|
1169
|
+
el.dataset.wmStage = win.stage;
|
|
1170
|
+
el.dataset.wmLayer = win.layer;
|
|
1171
|
+
el.hidden = win.stage === "minimized";
|
|
1172
|
+
el.setAttribute("aria-label", win.title);
|
|
1173
|
+
if (win.layer === "modal") el.setAttribute("aria-modal", "true");
|
|
1174
|
+
else el.removeAttribute("aria-modal");
|
|
1175
|
+
for (const handle of attached.handles) {
|
|
1176
|
+
handle.style.display = win.resizable && win.stage === "normal" ? "" : "none";
|
|
1177
|
+
}
|
|
1178
|
+
attached.lastState = win;
|
|
1179
|
+
}
|
|
1180
|
+
if (attached.lastZ !== zIndex) {
|
|
1181
|
+
el.style.zIndex = String(zIndex + 1);
|
|
1182
|
+
attached.lastZ = zIndex;
|
|
1183
|
+
}
|
|
1184
|
+
if (firstSync) {
|
|
1185
|
+
void el.offsetWidth;
|
|
1186
|
+
el.style.transition = "";
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
function syncAll() {
|
|
1190
|
+
const state = wm.getState();
|
|
1191
|
+
const orderChanged = state.order !== lastOrder;
|
|
1192
|
+
state.order.forEach((id, index) => {
|
|
1193
|
+
const attached = registry.get(id);
|
|
1194
|
+
const win = state.windows[id];
|
|
1195
|
+
if (!attached || !win) return;
|
|
1196
|
+
if (orderChanged || attached.lastState !== win) syncWindow(attached, win, index);
|
|
1197
|
+
});
|
|
1198
|
+
if (state.focusedId !== lastFocused) {
|
|
1199
|
+
if (lastFocused) {
|
|
1200
|
+
const prev = registry.get(lastFocused);
|
|
1201
|
+
if (prev) delete prev.element.dataset.wmFocused;
|
|
1202
|
+
}
|
|
1203
|
+
if (state.focusedId) {
|
|
1204
|
+
const next = registry.get(state.focusedId);
|
|
1205
|
+
if (next) next.element.dataset.wmFocused = "";
|
|
1206
|
+
}
|
|
1207
|
+
lastFocused = state.focusedId;
|
|
1208
|
+
}
|
|
1209
|
+
lastOrder = state.order;
|
|
1210
|
+
}
|
|
1211
|
+
cleanup.push(wm.subscribe(syncAll));
|
|
1212
|
+
cleanup.push(
|
|
1213
|
+
wm.on("focus", ({ window: win }) => {
|
|
1214
|
+
const attached = registry.get(win.id);
|
|
1215
|
+
if (!attached) return;
|
|
1216
|
+
if (!attached.element.contains(doc.activeElement)) {
|
|
1217
|
+
attached.element.focus({ preventScroll: true });
|
|
1218
|
+
}
|
|
1219
|
+
})
|
|
1220
|
+
);
|
|
1221
|
+
cleanup.push(
|
|
1222
|
+
wm.on("modalblocked", ({ window: win }) => {
|
|
1223
|
+
const attached = registry.get(win.id);
|
|
1224
|
+
if (!attached) return;
|
|
1225
|
+
delete attached.element.dataset.wmFlash;
|
|
1226
|
+
void attached.element.offsetWidth;
|
|
1227
|
+
attached.element.dataset.wmFlash = "";
|
|
1228
|
+
})
|
|
1229
|
+
);
|
|
1230
|
+
cleanup.push(
|
|
1231
|
+
wm.on("stage", ({ window: win, previous }) => {
|
|
1232
|
+
if (win.stage !== "minimized" || previous === "minimized") return;
|
|
1233
|
+
const attached = registry.get(win.id);
|
|
1234
|
+
const target = options.minimizeTarget?.(win);
|
|
1235
|
+
if (attached && target) flipToTarget(attached.element, target);
|
|
1236
|
+
})
|
|
1237
|
+
);
|
|
1238
|
+
if (keyboardEnabled && cycleEnabled) {
|
|
1239
|
+
const onDesktopKeydown = (event) => {
|
|
1240
|
+
if (event.key === "F6") {
|
|
1241
|
+
event.preventDefault();
|
|
1242
|
+
wm.cycleFocus(event.shiftKey ? -1 : 1);
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1245
|
+
element.addEventListener("keydown", onDesktopKeydown);
|
|
1246
|
+
cleanup.push(() => element.removeEventListener("keydown", onDesktopKeydown));
|
|
1247
|
+
}
|
|
1248
|
+
function endDrag(cancelled) {
|
|
1249
|
+
if (drag) drag.finish(cancelled);
|
|
1128
1250
|
}
|
|
1129
1251
|
function attachWindow(id, windowElement, windowOptions = {}) {
|
|
1130
1252
|
const win = wm.get(id);
|
|
@@ -1135,6 +1257,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1135
1257
|
handle: null,
|
|
1136
1258
|
handles: [],
|
|
1137
1259
|
lastState: null,
|
|
1260
|
+
lastZ: -1,
|
|
1138
1261
|
cleanup: []
|
|
1139
1262
|
};
|
|
1140
1263
|
windowElement.dataset.wmWindow = id;
|
|
@@ -1187,24 +1310,11 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1187
1310
|
attached.cleanup.push(() => handle.removeEventListener("dblclick", onDoubleClick));
|
|
1188
1311
|
}
|
|
1189
1312
|
if (windowOptions.resizeHandles !== false) {
|
|
1190
|
-
for (const direction of
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
const size = 8;
|
|
1196
|
-
const corner = 12;
|
|
1197
|
-
const styles = {
|
|
1198
|
-
n: `top:${-size / 2}px;left:${corner}px;right:${corner}px;height:${size}px`,
|
|
1199
|
-
s: `bottom:${-size / 2}px;left:${corner}px;right:${corner}px;height:${size}px`,
|
|
1200
|
-
e: `right:${-size / 2}px;top:${corner}px;bottom:${corner}px;width:${size}px`,
|
|
1201
|
-
w: `left:${-size / 2}px;top:${corner}px;bottom:${corner}px;width:${size}px`,
|
|
1202
|
-
ne: `top:${-size / 2}px;right:${-size / 2}px;width:${corner}px;height:${corner}px`,
|
|
1203
|
-
nw: `top:${-size / 2}px;left:${-size / 2}px;width:${corner}px;height:${corner}px`,
|
|
1204
|
-
se: `bottom:${-size / 2}px;right:${-size / 2}px;width:${corner}px;height:${corner}px`,
|
|
1205
|
-
sw: `bottom:${-size / 2}px;left:${-size / 2}px;width:${corner}px;height:${corner}px`
|
|
1206
|
-
};
|
|
1207
|
-
resizeHandle.style.cssText = `${base}${styles[direction]};cursor:${RESIZE_CURSORS[direction]}`;
|
|
1313
|
+
for (const { element: resizeHandle, direction } of createResizeHandles(
|
|
1314
|
+
doc,
|
|
1315
|
+
hitEdge,
|
|
1316
|
+
hitCorner
|
|
1317
|
+
)) {
|
|
1208
1318
|
const onResizeDown = (event) => startResize(id, direction, event);
|
|
1209
1319
|
resizeHandle.addEventListener("pointerdown", onResizeDown);
|
|
1210
1320
|
attached.cleanup.push(() => resizeHandle.removeEventListener("pointerdown", onResizeDown));
|
|
@@ -1262,16 +1372,25 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1262
1372
|
};
|
|
1263
1373
|
windowElement.addEventListener("keydown", onModalTrap);
|
|
1264
1374
|
attached.cleanup.push(() => windowElement.removeEventListener("keydown", onModalTrap));
|
|
1265
|
-
|
|
1266
|
-
lastOrder = null;
|
|
1267
|
-
lastFocused = null;
|
|
1268
|
-
syncAll();
|
|
1269
|
-
return () => {
|
|
1375
|
+
const detach = () => {
|
|
1270
1376
|
if (drag?.id === id) endDrag(true);
|
|
1271
1377
|
for (const dispose of attached.cleanup) dispose();
|
|
1272
1378
|
for (const resizeHandle of attached.handles) resizeHandle.remove();
|
|
1273
1379
|
registry.delete(id);
|
|
1274
1380
|
};
|
|
1381
|
+
if (windowOptions.removeOnClose) {
|
|
1382
|
+
const stopOnClose = wm.on("close", ({ window: closed }) => {
|
|
1383
|
+
if (closed.id !== id) return;
|
|
1384
|
+
detach();
|
|
1385
|
+
windowElement.remove();
|
|
1386
|
+
});
|
|
1387
|
+
attached.cleanup.push(stopOnClose);
|
|
1388
|
+
}
|
|
1389
|
+
registry.set(id, attached);
|
|
1390
|
+
lastOrder = null;
|
|
1391
|
+
lastFocused = null;
|
|
1392
|
+
syncAll();
|
|
1393
|
+
return detach;
|
|
1275
1394
|
}
|
|
1276
1395
|
return {
|
|
1277
1396
|
element,
|
|
@@ -1290,6 +1409,8 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1290
1409
|
}
|
|
1291
1410
|
};
|
|
1292
1411
|
}
|
|
1412
|
+
|
|
1413
|
+
// src/dom/binder.ts
|
|
1293
1414
|
function createDesktopBinder(wm, options = {}) {
|
|
1294
1415
|
let controller = null;
|
|
1295
1416
|
const entries = /* @__PURE__ */ new Set();
|
|
@@ -1330,5 +1451,5 @@ function createDesktopBinder(wm, options = {}) {
|
|
|
1330
1451
|
}
|
|
1331
1452
|
|
|
1332
1453
|
export { attachDesktop, boundsEqual, clamp, clampSize, clampToViewport, createAnnouncer, createDesktopBinder, createEmitter, createWindowManager, defaultMessages, detectSnapZone, flipToTarget, prefersReducedMotion, zoneBounds };
|
|
1333
|
-
//# sourceMappingURL=chunk-
|
|
1334
|
-
//# sourceMappingURL=chunk-
|
|
1454
|
+
//# sourceMappingURL=chunk-2TVOEDRG.js.map
|
|
1455
|
+
//# sourceMappingURL=chunk-2TVOEDRG.js.map
|