@surdeddd/wmkit 0.5.0 → 0.6.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/dist/angular.cjs +3 -3
- package/dist/angular.d.cts +1 -1
- package/dist/angular.d.ts +1 -1
- package/dist/angular.js +1 -1
- package/dist/{binder-EBroZTRw.d.cts → binder-CQzQJdVj.d.cts} +13 -0
- package/dist/{binder-Ca3GOfZX.d.ts → binder-CkmOoo1U.d.ts} +13 -0
- package/dist/{chunk-L43XBN44.js → chunk-3HLKVOSI.js} +301 -80
- package/dist/chunk-3HLKVOSI.js.map +1 -0
- package/dist/{chunk-RXAMUBUJ.cjs → chunk-DYZQY3BE.cjs} +301 -80
- package/dist/chunk-DYZQY3BE.cjs.map +1 -0
- package/dist/index.cjs +18 -18
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/react.cjs +3 -3
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/solid.cjs +3 -3
- package/dist/solid.d.cts +1 -1
- package/dist/solid.d.ts +1 -1
- package/dist/solid.js +1 -1
- package/dist/svelte.cjs +3 -3
- package/dist/svelte.d.cts +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/svelte.js +1 -1
- package/dist/themes/glass.css +68 -2
- package/dist/themes/light.css +68 -2
- package/dist/themes/retro.css +46 -1
- package/dist/vue.cjs +3 -3
- package/dist/vue.d.cts +1 -1
- package/dist/vue.d.ts +1 -1
- package/dist/vue.js +1 -1
- package/package.json +7 -7
- package/dist/chunk-L43XBN44.js.map +0 -1
- package/dist/chunk-RXAMUBUJ.cjs.map +0 -1
|
@@ -195,6 +195,12 @@ function createWindowManager(options = {}) {
|
|
|
195
195
|
const idPrefix = options.idPrefix ?? "wm";
|
|
196
196
|
const historyLimit = options.historyLimit ?? 50;
|
|
197
197
|
let windows = {};
|
|
198
|
+
let windowsShared = false;
|
|
199
|
+
let modalCount = 0;
|
|
200
|
+
let cachedGroups = null;
|
|
201
|
+
let cachedOrder = null;
|
|
202
|
+
let cachedTabs = null;
|
|
203
|
+
let groupsDirty = false;
|
|
198
204
|
let order = [];
|
|
199
205
|
let focusedId = null;
|
|
200
206
|
let viewport = options.viewport ?? { width: 0, height: 0 };
|
|
@@ -219,6 +225,7 @@ function createWindowManager(options = {}) {
|
|
|
219
225
|
const layouts = /* @__PURE__ */ new Map();
|
|
220
226
|
function getState() {
|
|
221
227
|
if (!snapshot) {
|
|
228
|
+
windowsShared = true;
|
|
222
229
|
snapshot = { windows, order, focusedId, viewport, workspace, groups: buildGroups() };
|
|
223
230
|
}
|
|
224
231
|
return snapshot;
|
|
@@ -240,30 +247,58 @@ function createWindowManager(options = {}) {
|
|
|
240
247
|
function queueEvent(emit) {
|
|
241
248
|
pendingEvents.push(emit);
|
|
242
249
|
}
|
|
250
|
+
function ownWindows() {
|
|
251
|
+
if (windowsShared) {
|
|
252
|
+
windows = { ...windows };
|
|
253
|
+
windowsShared = false;
|
|
254
|
+
}
|
|
255
|
+
return windows;
|
|
256
|
+
}
|
|
243
257
|
function setWindow(next) {
|
|
244
|
-
|
|
258
|
+
const map = ownWindows();
|
|
259
|
+
const previous = map[next.id];
|
|
260
|
+
const wasModal = previous?.layer === "modal";
|
|
261
|
+
if (wasModal !== (next.layer === "modal")) modalCount += wasModal ? -1 : 1;
|
|
262
|
+
if (previous?.groupId !== next.groupId) groupsDirty = true;
|
|
263
|
+
map[next.id] = next;
|
|
245
264
|
}
|
|
246
265
|
function removeWindow(id) {
|
|
247
|
-
const
|
|
248
|
-
|
|
266
|
+
const map = ownWindows();
|
|
267
|
+
const previous = map[id];
|
|
268
|
+
if (previous?.layer === "modal") modalCount -= 1;
|
|
269
|
+
if (previous?.groupId != null) groupsDirty = true;
|
|
270
|
+
delete map[id];
|
|
249
271
|
order = order.filter((entry) => entry !== id);
|
|
250
272
|
}
|
|
273
|
+
function countModals() {
|
|
274
|
+
let total = 0;
|
|
275
|
+
for (const id of order) {
|
|
276
|
+
if (windows[id].layer === "modal") total += 1;
|
|
277
|
+
}
|
|
278
|
+
return total;
|
|
279
|
+
}
|
|
251
280
|
function layerRankOf(id) {
|
|
252
281
|
return LAYER_RANK[windows[id].layer];
|
|
253
282
|
}
|
|
254
283
|
function sortByLayer(ids) {
|
|
255
284
|
return ids.map((id, index) => ({ id, index, rank: layerRankOf(id) })).sort((a, b) => a.rank !== b.rank ? a.rank - b.rank : a.index - b.index).map((entry) => entry.id);
|
|
256
285
|
}
|
|
286
|
+
function blockOf(id) {
|
|
287
|
+
const win = windows[id];
|
|
288
|
+
if (win.groupId === null) return [id];
|
|
289
|
+
return [...membersOf(win.groupId).filter((entry) => entry !== id), id];
|
|
290
|
+
}
|
|
257
291
|
function raise(id) {
|
|
258
292
|
const win = windows[id];
|
|
259
|
-
const
|
|
293
|
+
const block = blockOf(id);
|
|
294
|
+
const without = order.filter((entry) => !block.includes(entry));
|
|
260
295
|
const rank = LAYER_RANK[win.layer];
|
|
261
296
|
let insertAt = without.length;
|
|
262
297
|
for (let i = without.length - 1; i >= 0; i -= 1) {
|
|
263
298
|
if (layerRankOf(without[i]) > rank) insertAt = i;
|
|
264
299
|
else break;
|
|
265
300
|
}
|
|
266
|
-
const next = [...without.slice(0, insertAt),
|
|
301
|
+
const next = [...without.slice(0, insertAt), ...block, ...without.slice(insertAt)];
|
|
267
302
|
const changed = next.length !== order.length || next.some((entry, i) => entry !== order[i]);
|
|
268
303
|
order = next;
|
|
269
304
|
return changed;
|
|
@@ -278,31 +313,57 @@ function createWindowManager(options = {}) {
|
|
|
278
313
|
return win.groupId === null || activeTabs[win.groupId] === win.id;
|
|
279
314
|
}
|
|
280
315
|
function buildGroups() {
|
|
281
|
-
|
|
316
|
+
if (cachedGroups && !groupsDirty && cachedOrder === order && cachedTabs === activeTabs) {
|
|
317
|
+
return cachedGroups;
|
|
318
|
+
}
|
|
319
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
282
320
|
for (const [groupId, activeId] of Object.entries(activeTabs)) {
|
|
283
321
|
result[groupId] = { id: groupId, activeId, members: membersOf(groupId) };
|
|
284
322
|
}
|
|
323
|
+
cachedGroups = result;
|
|
324
|
+
cachedOrder = order;
|
|
325
|
+
cachedTabs = activeTabs;
|
|
326
|
+
groupsDirty = false;
|
|
285
327
|
return result;
|
|
286
328
|
}
|
|
329
|
+
function sharedSize(ids, size) {
|
|
330
|
+
let shared = size;
|
|
331
|
+
for (const id of ids) {
|
|
332
|
+
const fit = normalizeSize(shared, windows[id]);
|
|
333
|
+
shared = {
|
|
334
|
+
width: Math.max(shared.width, fit.width),
|
|
335
|
+
height: Math.max(shared.height, fit.height)
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
return shared;
|
|
339
|
+
}
|
|
287
340
|
function syncGroup(source) {
|
|
288
|
-
if (source.groupId === null) return;
|
|
289
|
-
|
|
290
|
-
|
|
341
|
+
if (source.groupId === null) return source;
|
|
342
|
+
const members = membersOf(source.groupId);
|
|
343
|
+
const fitted = sharedSize(members, source.bounds);
|
|
344
|
+
let effective = source;
|
|
345
|
+
if (fitted.width !== source.bounds.width || fitted.height !== source.bounds.height) {
|
|
346
|
+
effective = { ...source, bounds: { ...source.bounds, ...fitted } };
|
|
347
|
+
setWindow(effective);
|
|
348
|
+
}
|
|
349
|
+
for (const id of members) {
|
|
350
|
+
if (id === effective.id) continue;
|
|
291
351
|
const member = windows[id];
|
|
292
|
-
if (boundsEqual(member.bounds,
|
|
352
|
+
if (boundsEqual(member.bounds, effective.bounds) && member.stage === effective.stage && member.snapZone === effective.snapZone && member.layer === effective.layer && member.workspace === effective.workspace) {
|
|
293
353
|
continue;
|
|
294
354
|
}
|
|
295
355
|
setWindow({
|
|
296
356
|
...member,
|
|
297
|
-
bounds:
|
|
298
|
-
stage:
|
|
299
|
-
snapZone:
|
|
300
|
-
restoreBounds:
|
|
301
|
-
restoreStage:
|
|
302
|
-
layer:
|
|
303
|
-
workspace:
|
|
357
|
+
bounds: effective.bounds,
|
|
358
|
+
stage: effective.stage,
|
|
359
|
+
snapZone: effective.snapZone,
|
|
360
|
+
restoreBounds: effective.restoreBounds,
|
|
361
|
+
restoreStage: effective.restoreStage,
|
|
362
|
+
layer: effective.layer,
|
|
363
|
+
workspace: effective.workspace
|
|
304
364
|
});
|
|
305
365
|
}
|
|
366
|
+
return effective;
|
|
306
367
|
}
|
|
307
368
|
function dissolveIfOrphaned(groupId) {
|
|
308
369
|
const members = membersOf(groupId);
|
|
@@ -314,6 +375,7 @@ function createWindowManager(options = {}) {
|
|
|
314
375
|
activeTabs = rest;
|
|
315
376
|
}
|
|
316
377
|
function topModalId() {
|
|
378
|
+
if (modalCount === 0) return null;
|
|
317
379
|
for (let i = order.length - 1; i >= 0; i -= 1) {
|
|
318
380
|
const win = windows[order[i]];
|
|
319
381
|
if (win.layer === "modal" && win.stage !== "minimized" && onActiveWorkspace(win) && isVisibleTab(win)) {
|
|
@@ -332,8 +394,21 @@ function createWindowManager(options = {}) {
|
|
|
332
394
|
});
|
|
333
395
|
}
|
|
334
396
|
function focusTop() {
|
|
335
|
-
|
|
336
|
-
|
|
397
|
+
for (let i = order.length - 1; i >= 0; i -= 1) {
|
|
398
|
+
const win = windows[order[i]];
|
|
399
|
+
if (win.stage === "minimized" || !onActiveWorkspace(win) || !isVisibleTab(win)) continue;
|
|
400
|
+
focusedId = win.id;
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
focusedId = null;
|
|
404
|
+
}
|
|
405
|
+
function reconcileFocus() {
|
|
406
|
+
if (focusedId === null) return;
|
|
407
|
+
const win = windows[focusedId];
|
|
408
|
+
if (win && win.stage !== "minimized" && onActiveWorkspace(win) && isVisibleTab(win)) return;
|
|
409
|
+
const previous = focusedId;
|
|
410
|
+
focusTop();
|
|
411
|
+
if (focusedId) emitFocus(windows[focusedId], previous);
|
|
337
412
|
}
|
|
338
413
|
function emitFocus(win, previous) {
|
|
339
414
|
queueEvent(() => emitter.emit("focus", { window: win, previous }));
|
|
@@ -456,7 +531,6 @@ function createWindowManager(options = {}) {
|
|
|
456
531
|
const win = windows[id];
|
|
457
532
|
if (!win) return false;
|
|
458
533
|
if (!onActiveWorkspace(win)) setWorkspace(win.workspace);
|
|
459
|
-
if (!isVisibleTab(win)) activateTab(id);
|
|
460
534
|
const modal = topModalId();
|
|
461
535
|
if (modal && modal !== id && win.layer !== "modal") {
|
|
462
536
|
const modalWin = windows[modal];
|
|
@@ -464,6 +538,7 @@ function createWindowManager(options = {}) {
|
|
|
464
538
|
commitQuiet();
|
|
465
539
|
return false;
|
|
466
540
|
}
|
|
541
|
+
if (!isVisibleTab(win)) activateTab(id);
|
|
467
542
|
if (win.stage === "minimized") {
|
|
468
543
|
restore(id);
|
|
469
544
|
return focusedId === id;
|
|
@@ -516,8 +591,9 @@ function createWindowManager(options = {}) {
|
|
|
516
591
|
const next = build(win);
|
|
517
592
|
if (!next) return false;
|
|
518
593
|
setWindow(next);
|
|
519
|
-
syncGroup(next);
|
|
520
|
-
queueEvent(() => emitter.emit("stage", { window:
|
|
594
|
+
const synced = syncGroup(next);
|
|
595
|
+
queueEvent(() => emitter.emit("stage", { window: synced, previous: win.stage }));
|
|
596
|
+
if (next.groupId !== null) reconcileFocus();
|
|
521
597
|
commit();
|
|
522
598
|
return true;
|
|
523
599
|
}
|
|
@@ -648,9 +724,11 @@ function createWindowManager(options = {}) {
|
|
|
648
724
|
if (boundsEqual(bounds, win.bounds) && !becameNormal) return true;
|
|
649
725
|
const next = becameNormal ? { ...win, stage: "normal", snapZone: null, restoreBounds: null, bounds } : { ...win, bounds };
|
|
650
726
|
setWindow(next);
|
|
651
|
-
syncGroup(next);
|
|
652
|
-
if (becameNormal)
|
|
653
|
-
|
|
727
|
+
const synced = syncGroup(next);
|
|
728
|
+
if (becameNormal) {
|
|
729
|
+
queueEvent(() => emitter.emit("stage", { window: synced, previous: "snapped" }));
|
|
730
|
+
}
|
|
731
|
+
queueEvent(() => emitter.emit("resize", { window: synced }));
|
|
654
732
|
commit();
|
|
655
733
|
return true;
|
|
656
734
|
}
|
|
@@ -676,18 +754,18 @@ function createWindowManager(options = {}) {
|
|
|
676
754
|
const resized = size.width !== next.bounds.width || size.height !== next.bounds.height;
|
|
677
755
|
const finalWin = resized ? { ...next, bounds: { ...next.bounds, ...size } } : next;
|
|
678
756
|
setWindow(finalWin);
|
|
679
|
-
syncGroup(finalWin);
|
|
757
|
+
const synced = syncGroup(finalWin);
|
|
680
758
|
if (patch.layer && patch.layer !== win.layer) {
|
|
681
759
|
order = sortByLayer(order);
|
|
682
760
|
queueEvent(() => emitter.emit("order", { order }));
|
|
683
761
|
if (patch.layer === "modal" && topModalId() === id && focusedId !== id) {
|
|
684
762
|
const previous = focusedId;
|
|
685
763
|
focusedId = id;
|
|
686
|
-
emitFocus(
|
|
764
|
+
emitFocus(synced, previous);
|
|
687
765
|
}
|
|
688
766
|
}
|
|
689
|
-
queueEvent(() => emitter.emit("update", { window:
|
|
690
|
-
if (resized) queueEvent(() => emitter.emit("resize", { window:
|
|
767
|
+
queueEvent(() => emitter.emit("update", { window: synced }));
|
|
768
|
+
if (resized) queueEvent(() => emitter.emit("resize", { window: synced }));
|
|
691
769
|
commit();
|
|
692
770
|
return true;
|
|
693
771
|
}
|
|
@@ -722,6 +800,8 @@ function createWindowManager(options = {}) {
|
|
|
722
800
|
if (!onActiveWorkspace(updated) && focusedId === id) {
|
|
723
801
|
focusTop();
|
|
724
802
|
if (focusedId) emitFocus(windows[focusedId], id);
|
|
803
|
+
} else if (updated.groupId !== null && !onActiveWorkspace(updated)) {
|
|
804
|
+
reconcileFocus();
|
|
725
805
|
} else if (onActiveWorkspace(updated) && topModalId() === id && focusedId !== id) {
|
|
726
806
|
const previous = focusedId;
|
|
727
807
|
focusedId = id;
|
|
@@ -747,7 +827,16 @@ function createWindowManager(options = {}) {
|
|
|
747
827
|
for (const entry of siblings) if (!expanded.includes(entry)) expanded.push(entry);
|
|
748
828
|
}
|
|
749
829
|
if (expanded.length < 2) return null;
|
|
750
|
-
|
|
830
|
+
let groupId = `${idPrefix}-group-${++groupCounter}`;
|
|
831
|
+
while (activeTabs[groupId]) groupId = `${idPrefix}-group-${++groupCounter}`;
|
|
832
|
+
const shared = expanded.reduce(
|
|
833
|
+
(size, id) => {
|
|
834
|
+
const fit = normalizeSize(size, windows[id]);
|
|
835
|
+
return { width: Math.max(size.width, fit.width), height: Math.max(size.height, fit.height) };
|
|
836
|
+
},
|
|
837
|
+
{ width: host.bounds.width, height: host.bounds.height }
|
|
838
|
+
);
|
|
839
|
+
const bounds = { x: host.bounds.x, y: host.bounds.y, ...shared };
|
|
751
840
|
const retired = /* @__PURE__ */ new Set();
|
|
752
841
|
for (const id of expanded) {
|
|
753
842
|
const win = windows[id];
|
|
@@ -755,7 +844,7 @@ function createWindowManager(options = {}) {
|
|
|
755
844
|
setWindow({
|
|
756
845
|
...win,
|
|
757
846
|
groupId,
|
|
758
|
-
bounds
|
|
847
|
+
bounds,
|
|
759
848
|
stage: host.stage,
|
|
760
849
|
snapZone: host.snapZone,
|
|
761
850
|
restoreBounds: host.restoreBounds,
|
|
@@ -770,8 +859,11 @@ function createWindowManager(options = {}) {
|
|
|
770
859
|
raise(host.id);
|
|
771
860
|
emitGroup(groupId, null);
|
|
772
861
|
queueEvent(() => emitter.emit("order", { order }));
|
|
862
|
+
const hostVisible = onActiveWorkspace(host) && host.stage !== "minimized";
|
|
863
|
+
commit();
|
|
864
|
+
if (hostVisible) focus(host.id);
|
|
865
|
+
reconcileFocus();
|
|
773
866
|
commit();
|
|
774
|
-
if (onActiveWorkspace(host) && host.stage !== "minimized") focus(host.id);
|
|
775
867
|
return groupId;
|
|
776
868
|
}
|
|
777
869
|
function ungroup(id) {
|
|
@@ -785,7 +877,7 @@ function createWindowManager(options = {}) {
|
|
|
785
877
|
dissolveIfOrphaned(groupId);
|
|
786
878
|
if (membersOf(groupId).length >= 2) emitGroup(groupId, wasActive ? id : null);
|
|
787
879
|
commit();
|
|
788
|
-
focus(id);
|
|
880
|
+
if (onActiveWorkspace(win) && win.stage !== "minimized") focus(id);
|
|
789
881
|
return true;
|
|
790
882
|
}
|
|
791
883
|
function activateTab(id) {
|
|
@@ -795,6 +887,10 @@ function createWindowManager(options = {}) {
|
|
|
795
887
|
const previous = activeTabs[groupId];
|
|
796
888
|
if (previous === id) return false;
|
|
797
889
|
activeTabs = { ...activeTabs, [groupId]: id };
|
|
890
|
+
if (focusedId === previous) {
|
|
891
|
+
focusedId = id;
|
|
892
|
+
emitFocus(win, previous);
|
|
893
|
+
}
|
|
798
894
|
emitGroup(groupId, previous);
|
|
799
895
|
commit();
|
|
800
896
|
return true;
|
|
@@ -805,14 +901,15 @@ function createWindowManager(options = {}) {
|
|
|
805
901
|
function sendToBack(id) {
|
|
806
902
|
const win = windows[id];
|
|
807
903
|
if (!win) return false;
|
|
808
|
-
const
|
|
904
|
+
const block = blockOf(id);
|
|
905
|
+
const without = order.filter((entry) => !block.includes(entry));
|
|
809
906
|
const rank = LAYER_RANK[win.layer];
|
|
810
907
|
let insertAt = 0;
|
|
811
908
|
for (const entry of without) {
|
|
812
909
|
if (layerRankOf(entry) < rank) insertAt += 1;
|
|
813
910
|
else break;
|
|
814
911
|
}
|
|
815
|
-
const next = [...without.slice(0, insertAt),
|
|
912
|
+
const next = [...without.slice(0, insertAt), ...block, ...without.slice(insertAt)];
|
|
816
913
|
if (next.every((entry, i) => entry === order[i])) return false;
|
|
817
914
|
order = next;
|
|
818
915
|
queueEvent(() => emitter.emit("order", { order }));
|
|
@@ -836,6 +933,7 @@ function createWindowManager(options = {}) {
|
|
|
836
933
|
return Object.values(windows).filter((win) => win.stage === "minimized" && onActiveWorkspace(win) && isVisibleTab(win)).sort((a, b) => a.openedSeq - b.openedSeq);
|
|
837
934
|
}
|
|
838
935
|
function captureEntry() {
|
|
936
|
+
windowsShared = true;
|
|
839
937
|
return { windows, order, focusedId, workspace, activeTabs };
|
|
840
938
|
}
|
|
841
939
|
function recordHistory() {
|
|
@@ -876,19 +974,23 @@ function createWindowManager(options = {}) {
|
|
|
876
974
|
function reflowViewport() {
|
|
877
975
|
for (const id of order) {
|
|
878
976
|
const win = windows[id];
|
|
977
|
+
if (!isVisibleTab(win)) continue;
|
|
879
978
|
if (win.stage === "maximized") {
|
|
880
979
|
const updated = { ...win, bounds: fullBounds() };
|
|
881
980
|
setWindow(updated);
|
|
882
|
-
|
|
981
|
+
const synced = syncGroup(updated);
|
|
982
|
+
queueEvent(() => emitter.emit("resize", { window: synced }));
|
|
883
983
|
} else if (win.stage === "snapped" && win.snapZone) {
|
|
884
984
|
const updated = { ...win, bounds: snapBounds(win, win.snapZone) };
|
|
885
985
|
setWindow(updated);
|
|
886
|
-
|
|
986
|
+
const synced = syncGroup(updated);
|
|
987
|
+
queueEvent(() => emitter.emit("resize", { window: synced }));
|
|
887
988
|
} else if (win.stage === "normal" && keepInViewport) {
|
|
888
989
|
const bounds = clampToViewport(win.bounds, viewport, minVisible);
|
|
889
990
|
if (!boundsEqual(bounds, win.bounds)) {
|
|
890
991
|
const updated = { ...win, bounds };
|
|
891
992
|
setWindow(updated);
|
|
993
|
+
syncGroup(updated);
|
|
892
994
|
queueEvent(() => emitter.emit("move", { window: updated }));
|
|
893
995
|
}
|
|
894
996
|
}
|
|
@@ -897,6 +999,8 @@ function createWindowManager(options = {}) {
|
|
|
897
999
|
function applyEntry(entry) {
|
|
898
1000
|
windows = entry.windows;
|
|
899
1001
|
order = [...entry.order];
|
|
1002
|
+
modalCount = countModals();
|
|
1003
|
+
groupsDirty = true;
|
|
900
1004
|
focusedId = entry.focusedId;
|
|
901
1005
|
activeTabs = entry.activeTabs;
|
|
902
1006
|
const previousWorkspace = workspace;
|
|
@@ -975,7 +1079,7 @@ function createWindowManager(options = {}) {
|
|
|
975
1079
|
function arrange(mode) {
|
|
976
1080
|
const ids = order.filter((id) => {
|
|
977
1081
|
const win = windows[id];
|
|
978
|
-
return win.stage !== "minimized" && onActiveWorkspace(win);
|
|
1082
|
+
return win.stage !== "minimized" && onActiveWorkspace(win) && isVisibleTab(win);
|
|
979
1083
|
});
|
|
980
1084
|
if (ids.length === 0) return;
|
|
981
1085
|
if (mode === "cascade") {
|
|
@@ -1007,7 +1111,8 @@ function createWindowManager(options = {}) {
|
|
|
1007
1111
|
}
|
|
1008
1112
|
function minimizeAll() {
|
|
1009
1113
|
for (const id of [...order]) {
|
|
1010
|
-
|
|
1114
|
+
const win = windows[id];
|
|
1115
|
+
if (onActiveWorkspace(win) && isVisibleTab(win)) minimize(id);
|
|
1011
1116
|
}
|
|
1012
1117
|
}
|
|
1013
1118
|
function restoreAll() {
|
|
@@ -1114,8 +1219,11 @@ function createWindowManager(options = {}) {
|
|
|
1114
1219
|
if (!seen.has(id)) nextOrder.push(id);
|
|
1115
1220
|
}
|
|
1116
1221
|
windows = nextWindows;
|
|
1222
|
+
windowsShared = false;
|
|
1117
1223
|
order = nextOrder;
|
|
1118
1224
|
order = sortByLayer(order);
|
|
1225
|
+
modalCount = countModals();
|
|
1226
|
+
groupsDirty = true;
|
|
1119
1227
|
seq = maxSeq;
|
|
1120
1228
|
const previousWorkspace = workspace;
|
|
1121
1229
|
workspace = normalizeWorkspace(data.workspace, 0);
|
|
@@ -1127,7 +1235,7 @@ function createWindowManager(options = {}) {
|
|
|
1127
1235
|
if (focusedCandidate && (focusedCandidate.stage === "minimized" || !onActiveWorkspace(focusedCandidate))) {
|
|
1128
1236
|
focusedId = null;
|
|
1129
1237
|
}
|
|
1130
|
-
const restoredTabs =
|
|
1238
|
+
const restoredTabs = /* @__PURE__ */ Object.create(null);
|
|
1131
1239
|
const rawTabs = data.activeTabs;
|
|
1132
1240
|
for (const id of order) {
|
|
1133
1241
|
const groupId = windows[id].groupId;
|
|
@@ -1224,6 +1332,7 @@ function createWindowManager(options = {}) {
|
|
|
1224
1332
|
|
|
1225
1333
|
// src/dom/animate.ts
|
|
1226
1334
|
function prefersReducedMotion(win) {
|
|
1335
|
+
if (typeof win.matchMedia !== "function") return false;
|
|
1227
1336
|
return win.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1228
1337
|
}
|
|
1229
1338
|
function flipFromTarget(source, target, options = {}) {
|
|
@@ -1352,14 +1461,6 @@ function createAnnouncer(wm, container, messages = {}) {
|
|
|
1352
1461
|
};
|
|
1353
1462
|
}
|
|
1354
1463
|
|
|
1355
|
-
// src/dom/shared.ts
|
|
1356
|
-
var INTERACTIVE_SELECTOR = "button, input, select, textarea, a[href], [contenteditable], [data-wm-close], [data-wm-minimize], [data-wm-maximize]";
|
|
1357
|
-
function windowOf(element) {
|
|
1358
|
-
const view = element.ownerDocument.defaultView;
|
|
1359
|
-
if (!view) throw new Error("wmkit: desktop element is not attached to a document");
|
|
1360
|
-
return view;
|
|
1361
|
-
}
|
|
1362
|
-
|
|
1363
1464
|
// src/dom/drag.ts
|
|
1364
1465
|
function createDragStarter(ctx) {
|
|
1365
1466
|
const { wm, doc, view } = ctx;
|
|
@@ -1367,7 +1468,7 @@ function createDragStarter(ctx) {
|
|
|
1367
1468
|
const win = wm.get(id);
|
|
1368
1469
|
if (!win?.draggable || event.button !== 0 || ctx.currentDrag()) return;
|
|
1369
1470
|
const target = event.target;
|
|
1370
|
-
if (target?.closest(
|
|
1471
|
+
if (target?.closest(ctx.interactiveSelector)) return;
|
|
1371
1472
|
event.preventDefault();
|
|
1372
1473
|
const releaseRect = ctx.trackRect();
|
|
1373
1474
|
const point = ctx.toLocal(event);
|
|
@@ -1400,6 +1501,8 @@ function createDragStarter(ctx) {
|
|
|
1400
1501
|
const el = ctx.windowElement(id);
|
|
1401
1502
|
function armGroup(target2) {
|
|
1402
1503
|
session.groupTarget = target2;
|
|
1504
|
+
session.zone = null;
|
|
1505
|
+
ctx.hidePreview();
|
|
1403
1506
|
ctx.markGroupTarget(target2);
|
|
1404
1507
|
}
|
|
1405
1508
|
function clearHover() {
|
|
@@ -1444,9 +1547,9 @@ function createDragStarter(ctx) {
|
|
|
1444
1547
|
for (const otherId of state.order) {
|
|
1445
1548
|
if (otherId === id) continue;
|
|
1446
1549
|
const other = state.windows[otherId];
|
|
1447
|
-
if (other
|
|
1448
|
-
|
|
1449
|
-
|
|
1550
|
+
if (!other || other.stage === "minimized" || other.workspace !== state.workspace) continue;
|
|
1551
|
+
if (other.groupId !== null && state.groups[other.groupId]?.activeId !== otherId) continue;
|
|
1552
|
+
targets.push(other.bounds);
|
|
1450
1553
|
}
|
|
1451
1554
|
const magnet = magnetize(
|
|
1452
1555
|
{ x: nextX, y: nextY, width: current.bounds.width, height: current.bounds.height },
|
|
@@ -1720,6 +1823,99 @@ function createResizeHandles(doc, edge, corner) {
|
|
|
1720
1823
|
});
|
|
1721
1824
|
}
|
|
1722
1825
|
|
|
1826
|
+
// src/dom/shared.ts
|
|
1827
|
+
var INTERACTIVE_SELECTOR = "button, input, select, textarea, a[href], [contenteditable], [data-wm-close], [data-wm-minimize], [data-wm-maximize]";
|
|
1828
|
+
function windowOf(element) {
|
|
1829
|
+
const view = element.ownerDocument.defaultView;
|
|
1830
|
+
if (!view) throw new Error("wmkit: desktop element is not attached to a document");
|
|
1831
|
+
return view;
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
// src/dom/stacking.ts
|
|
1835
|
+
var UNASSIGNED = Number.NEGATIVE_INFINITY;
|
|
1836
|
+
var tails = new Int32Array(0);
|
|
1837
|
+
var parents = new Int32Array(0);
|
|
1838
|
+
var kept = new Uint8Array(0);
|
|
1839
|
+
function reserve(length) {
|
|
1840
|
+
if (tails.length >= length) return;
|
|
1841
|
+
const size = Math.max(length, 64);
|
|
1842
|
+
tails = new Int32Array(size);
|
|
1843
|
+
parents = new Int32Array(size);
|
|
1844
|
+
kept = new Uint8Array(size);
|
|
1845
|
+
}
|
|
1846
|
+
function markLongestIncreasing(target) {
|
|
1847
|
+
const length = target.length;
|
|
1848
|
+
reserve(length);
|
|
1849
|
+
kept.fill(0, 0, length);
|
|
1850
|
+
let size = 0;
|
|
1851
|
+
for (let i = 0; i < length; i += 1) {
|
|
1852
|
+
const value = target.zAt(i);
|
|
1853
|
+
parents[i] = -1;
|
|
1854
|
+
if (!Number.isFinite(value)) continue;
|
|
1855
|
+
let low = 0;
|
|
1856
|
+
let high = size;
|
|
1857
|
+
while (low < high) {
|
|
1858
|
+
const mid = low + high >> 1;
|
|
1859
|
+
if (target.zAt(tails[mid]) < value) low = mid + 1;
|
|
1860
|
+
else high = mid;
|
|
1861
|
+
}
|
|
1862
|
+
if (low > 0) parents[i] = tails[low - 1];
|
|
1863
|
+
tails[low] = i;
|
|
1864
|
+
if (low === size) size += 1;
|
|
1865
|
+
}
|
|
1866
|
+
let cursor = size > 0 ? tails[size - 1] : -1;
|
|
1867
|
+
let count = 0;
|
|
1868
|
+
while (cursor !== -1) {
|
|
1869
|
+
kept[cursor] = 1;
|
|
1870
|
+
count += 1;
|
|
1871
|
+
cursor = parents[cursor];
|
|
1872
|
+
}
|
|
1873
|
+
return count;
|
|
1874
|
+
}
|
|
1875
|
+
function between(low, high, base, gap) {
|
|
1876
|
+
if (!Number.isFinite(high)) return Number.isFinite(low) ? low + gap : base + gap;
|
|
1877
|
+
if (!Number.isFinite(low)) {
|
|
1878
|
+
const candidate2 = high - gap > base ? high - gap : Math.floor((base + high) / 2);
|
|
1879
|
+
return candidate2 > base && candidate2 < high ? candidate2 : null;
|
|
1880
|
+
}
|
|
1881
|
+
const candidate = Math.floor((low + high) / 2);
|
|
1882
|
+
return candidate > low && candidate < high ? candidate : null;
|
|
1883
|
+
}
|
|
1884
|
+
function renormalize(target, base, gap) {
|
|
1885
|
+
let writes = 0;
|
|
1886
|
+
for (let i = 0; i < target.length; i += 1) {
|
|
1887
|
+
const z = base + (i + 1) * gap;
|
|
1888
|
+
if (target.zAt(i) === z) continue;
|
|
1889
|
+
target.assign(i, z);
|
|
1890
|
+
writes += 1;
|
|
1891
|
+
}
|
|
1892
|
+
return writes;
|
|
1893
|
+
}
|
|
1894
|
+
function restack(target, options = {}) {
|
|
1895
|
+
const base = options.base ?? 0;
|
|
1896
|
+
const gap = options.gap ?? 32;
|
|
1897
|
+
const length = target.length;
|
|
1898
|
+
if (length === 0) return 0;
|
|
1899
|
+
const keepCount = markLongestIncreasing(target);
|
|
1900
|
+
if (length - keepCount > length / 3) return renormalize(target, base, gap);
|
|
1901
|
+
let writes = 0;
|
|
1902
|
+
for (let i = 0; i < length; i += 1) {
|
|
1903
|
+
if (kept[i] === 1) continue;
|
|
1904
|
+
const low = i > 0 ? target.zAt(i - 1) : UNASSIGNED;
|
|
1905
|
+
let high = Number.POSITIVE_INFINITY;
|
|
1906
|
+
for (let j = i + 1; j < length; j += 1) {
|
|
1907
|
+
if (kept[j] !== 1) continue;
|
|
1908
|
+
high = target.zAt(j);
|
|
1909
|
+
break;
|
|
1910
|
+
}
|
|
1911
|
+
const z = between(low, high, base, gap);
|
|
1912
|
+
if (z === null) return renormalize(target, base, gap);
|
|
1913
|
+
target.assign(i, z);
|
|
1914
|
+
writes += 1;
|
|
1915
|
+
}
|
|
1916
|
+
return writes;
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1723
1919
|
// src/dom/controller.ts
|
|
1724
1920
|
var SNAP_SHORTCUTS = {
|
|
1725
1921
|
ArrowLeft: "left",
|
|
@@ -1746,17 +1942,24 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1746
1942
|
const hitEdge = options.hitAreas?.edge ?? (coarsePointer ? 16 : 8);
|
|
1747
1943
|
const hitCorner = options.hitAreas?.corner ?? (coarsePointer ? 24 : 12);
|
|
1748
1944
|
const magnetThreshold = options.magnetism === false ? 0 : (typeof options.magnetism === "object" ? options.magnetism.threshold : void 0) ?? (coarsePointer ? 12 : 8);
|
|
1945
|
+
const zIndexBase = options.stacking?.base ?? 0;
|
|
1946
|
+
const zIndexGap = options.stacking?.gap ?? 32;
|
|
1947
|
+
const interactiveSelector = options.interactiveSelector ?? INTERACTIVE_SELECTOR;
|
|
1948
|
+
const animationEnabled = options.animation !== false;
|
|
1949
|
+
const animationOptions = typeof options.animation === "object" ? options.animation : {};
|
|
1749
1950
|
element.dataset.wmDesktop = "";
|
|
1750
1951
|
element.tabIndex = -1;
|
|
1751
1952
|
if (view.getComputedStyle(element).position === "static") {
|
|
1752
1953
|
element.style.position = "relative";
|
|
1753
1954
|
}
|
|
1955
|
+
if (options.stacking?.isolate !== false) element.style.isolation = "isolate";
|
|
1754
1956
|
const registry = /* @__PURE__ */ new Map();
|
|
1755
1957
|
const cleanup = [];
|
|
1756
1958
|
let lastOrder = null;
|
|
1757
1959
|
let lastFocused = null;
|
|
1758
1960
|
let drag = null;
|
|
1759
1961
|
let groupTargetId = null;
|
|
1962
|
+
let groupTargetEl = null;
|
|
1760
1963
|
let cachedRect = null;
|
|
1761
1964
|
let rectUsers = 0;
|
|
1762
1965
|
let announcer = null;
|
|
@@ -1827,6 +2030,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1827
2030
|
topEdge,
|
|
1828
2031
|
hitEdge,
|
|
1829
2032
|
hitCorner,
|
|
2033
|
+
interactiveSelector,
|
|
1830
2034
|
magnetThreshold,
|
|
1831
2035
|
groupDwell,
|
|
1832
2036
|
groupTarget(clientX, clientY, selfId) {
|
|
@@ -1835,21 +2039,16 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1835
2039
|
const handle = node.closest?.("[data-wm-drag]");
|
|
1836
2040
|
const host = handle?.closest("[data-wm-window]");
|
|
1837
2041
|
const id = host?.dataset.wmWindow;
|
|
1838
|
-
if (id && id !== selfId && registry.
|
|
2042
|
+
if (id && id !== selfId && registry.get(id)?.element === host) return id;
|
|
1839
2043
|
}
|
|
1840
2044
|
return null;
|
|
1841
2045
|
},
|
|
1842
2046
|
markGroupTarget(id) {
|
|
1843
2047
|
if (groupTargetId === id) return;
|
|
1844
|
-
if (
|
|
1845
|
-
const previous = registry.get(groupTargetId);
|
|
1846
|
-
if (previous) delete previous.element.dataset.wmTabTarget;
|
|
1847
|
-
}
|
|
2048
|
+
if (groupTargetEl) delete groupTargetEl.dataset.wmTabTarget;
|
|
1848
2049
|
groupTargetId = id;
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
if (next) next.element.dataset.wmTabTarget = "";
|
|
1852
|
-
}
|
|
2050
|
+
groupTargetEl = id ? registry.get(id)?.element ?? null : null;
|
|
2051
|
+
if (groupTargetEl) groupTargetEl.dataset.wmTabTarget = "";
|
|
1853
2052
|
},
|
|
1854
2053
|
currentDrag: () => drag,
|
|
1855
2054
|
claimDrag(session) {
|
|
@@ -1868,7 +2067,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1868
2067
|
observer.observe(element);
|
|
1869
2068
|
cleanup.push(() => observer.disconnect());
|
|
1870
2069
|
}
|
|
1871
|
-
function syncWindow(attached, win,
|
|
2070
|
+
function syncWindow(attached, win, activeWorkspace, activeTab) {
|
|
1872
2071
|
const el = attached.element;
|
|
1873
2072
|
const firstSync = attached.lastState === null;
|
|
1874
2073
|
if (firstSync) el.style.transition = "none";
|
|
@@ -1906,27 +2105,44 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1906
2105
|
attached.lastWorkspace = activeWorkspace;
|
|
1907
2106
|
attached.lastTab = activeTab;
|
|
1908
2107
|
}
|
|
1909
|
-
if (attached.lastZ !== zIndex) {
|
|
1910
|
-
el.style.zIndex = String(zIndex + 1);
|
|
1911
|
-
attached.lastZ = zIndex;
|
|
1912
|
-
}
|
|
1913
2108
|
if (firstSync) {
|
|
1914
2109
|
void el.offsetWidth;
|
|
1915
2110
|
el.style.transition = "";
|
|
1916
2111
|
}
|
|
1917
2112
|
}
|
|
2113
|
+
const stackRows = [];
|
|
2114
|
+
const stackTarget = {
|
|
2115
|
+
length: 0,
|
|
2116
|
+
zAt: (index) => stackRows[index].lastZ,
|
|
2117
|
+
assign(index, z) {
|
|
2118
|
+
const attached = stackRows[index];
|
|
2119
|
+
attached.lastZ = z;
|
|
2120
|
+
attached.element.style.zIndex = String(z);
|
|
2121
|
+
}
|
|
2122
|
+
};
|
|
2123
|
+
function applyStacking(order) {
|
|
2124
|
+
let length = 0;
|
|
2125
|
+
for (const id of order) {
|
|
2126
|
+
const attached = registry.get(id);
|
|
2127
|
+
if (attached) stackRows[length++] = attached;
|
|
2128
|
+
}
|
|
2129
|
+
stackTarget.length = length;
|
|
2130
|
+
restack(stackTarget, { base: zIndexBase, gap: zIndexGap });
|
|
2131
|
+
stackRows.length = length;
|
|
2132
|
+
}
|
|
1918
2133
|
function syncAll() {
|
|
1919
2134
|
const state = wm.getState();
|
|
1920
2135
|
const orderChanged = state.order !== lastOrder;
|
|
1921
|
-
state.order
|
|
2136
|
+
for (const id of state.order) {
|
|
1922
2137
|
const attached = registry.get(id);
|
|
1923
2138
|
const win = state.windows[id];
|
|
1924
|
-
if (!attached || !win)
|
|
2139
|
+
if (!attached || !win) continue;
|
|
1925
2140
|
const activeTab = win.groupId === null || state.groups[win.groupId]?.activeId === win.id;
|
|
1926
|
-
if (
|
|
1927
|
-
syncWindow(attached, win,
|
|
2141
|
+
if (attached.lastState !== win || attached.lastWorkspace !== state.workspace || attached.lastTab !== activeTab) {
|
|
2142
|
+
syncWindow(attached, win, state.workspace, activeTab);
|
|
1928
2143
|
}
|
|
1929
|
-
}
|
|
2144
|
+
}
|
|
2145
|
+
if (orderChanged) applyStacking(state.order);
|
|
1930
2146
|
if (state.focusedId !== lastFocused) {
|
|
1931
2147
|
if (lastFocused) {
|
|
1932
2148
|
const prev = registry.get(lastFocused);
|
|
@@ -1964,12 +2180,17 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1964
2180
|
wm.on("stage", ({ window: win, previous }) => {
|
|
1965
2181
|
const attached = registry.get(win.id);
|
|
1966
2182
|
if (!attached) return;
|
|
2183
|
+
if (!animationEnabled) return;
|
|
1967
2184
|
if (win.stage === "minimized" && previous !== "minimized") {
|
|
1968
2185
|
const target = options.minimizeTarget?.(win);
|
|
1969
|
-
if (target) flipToTarget(attached.element, target);
|
|
2186
|
+
if (target) flipToTarget(attached.element, target, animationOptions);
|
|
1970
2187
|
} else if (previous === "minimized" && win.stage !== "minimized") {
|
|
1971
2188
|
const target = options.minimizeTarget?.(win);
|
|
1972
|
-
if (target)
|
|
2189
|
+
if (target) {
|
|
2190
|
+
view.requestAnimationFrame(
|
|
2191
|
+
() => flipFromTarget(attached.element, target, animationOptions)
|
|
2192
|
+
);
|
|
2193
|
+
}
|
|
1973
2194
|
}
|
|
1974
2195
|
})
|
|
1975
2196
|
);
|
|
@@ -1983,7 +2204,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
1983
2204
|
if (!event.ctrlKey && !event.metaKey) return;
|
|
1984
2205
|
if (drag) return;
|
|
1985
2206
|
const target = event.target;
|
|
1986
|
-
if (target?.closest(
|
|
2207
|
+
if (target?.closest(interactiveSelector)) return;
|
|
1987
2208
|
if (historyShortcuts && (event.key === "z" || event.key === "Z")) {
|
|
1988
2209
|
event.preventDefault();
|
|
1989
2210
|
if (event.shiftKey) wm.redo();
|
|
@@ -2025,7 +2246,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
2025
2246
|
handle: null,
|
|
2026
2247
|
handles: [],
|
|
2027
2248
|
lastState: null,
|
|
2028
|
-
lastZ:
|
|
2249
|
+
lastZ: UNASSIGNED,
|
|
2029
2250
|
lastWorkspace: -1,
|
|
2030
2251
|
lastTab: true,
|
|
2031
2252
|
cleanup: []
|
|
@@ -2059,7 +2280,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
2059
2280
|
const current = wm.get(id);
|
|
2060
2281
|
if (!current) return;
|
|
2061
2282
|
if (target.closest("[data-wm-close]")) {
|
|
2062
|
-
if (current.closable) wm.close(id);
|
|
2283
|
+
if (current.closable && options.beforeClose?.(current) !== false) wm.close(id);
|
|
2063
2284
|
} else if (target.closest("[data-wm-minimize]")) {
|
|
2064
2285
|
if (current.minimizable) wm.minimize(id);
|
|
2065
2286
|
} else if (target.closest("[data-wm-maximize]")) {
|
|
@@ -2075,7 +2296,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
2075
2296
|
attached.cleanup.push(() => handle.removeEventListener("pointerdown", onHandleDown));
|
|
2076
2297
|
const onDoubleClick = (event) => {
|
|
2077
2298
|
const target = event.target;
|
|
2078
|
-
if (target?.closest(
|
|
2299
|
+
if (target?.closest(interactiveSelector)) return;
|
|
2079
2300
|
const current = wm.get(id);
|
|
2080
2301
|
if (current?.maximizable) wm.toggleMaximize(id);
|
|
2081
2302
|
};
|
|
@@ -2107,7 +2328,7 @@ function attachDesktop(wm, element, options = {}) {
|
|
|
2107
2328
|
}
|
|
2108
2329
|
const onWindowKeydown = (event) => {
|
|
2109
2330
|
const target = event.target;
|
|
2110
|
-
if (target?.closest(
|
|
2331
|
+
if (target?.closest(interactiveSelector)) return;
|
|
2111
2332
|
const current = wm.get(id);
|
|
2112
2333
|
if (!current) return;
|
|
2113
2334
|
const arrows = {
|
|
@@ -2267,5 +2488,5 @@ exports.flipToTarget = flipToTarget;
|
|
|
2267
2488
|
exports.magnetize = magnetize;
|
|
2268
2489
|
exports.prefersReducedMotion = prefersReducedMotion;
|
|
2269
2490
|
exports.zoneBounds = zoneBounds;
|
|
2270
|
-
//# sourceMappingURL=chunk-
|
|
2271
|
-
//# sourceMappingURL=chunk-
|
|
2491
|
+
//# sourceMappingURL=chunk-DYZQY3BE.cjs.map
|
|
2492
|
+
//# sourceMappingURL=chunk-DYZQY3BE.cjs.map
|