@surdeddd/wmkit 0.5.0 → 0.5.1

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.
@@ -254,16 +254,22 @@ function createWindowManager(options = {}) {
254
254
  function sortByLayer(ids) {
255
255
  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
256
  }
257
+ function blockOf(id) {
258
+ const win = windows[id];
259
+ if (win.groupId === null) return [id];
260
+ return [...membersOf(win.groupId).filter((entry) => entry !== id), id];
261
+ }
257
262
  function raise(id) {
258
263
  const win = windows[id];
259
- const without = order.filter((entry) => entry !== id);
264
+ const block = blockOf(id);
265
+ const without = order.filter((entry) => !block.includes(entry));
260
266
  const rank = LAYER_RANK[win.layer];
261
267
  let insertAt = without.length;
262
268
  for (let i = without.length - 1; i >= 0; i -= 1) {
263
269
  if (layerRankOf(without[i]) > rank) insertAt = i;
264
270
  else break;
265
271
  }
266
- const next = [...without.slice(0, insertAt), id, ...without.slice(insertAt)];
272
+ const next = [...without.slice(0, insertAt), ...block, ...without.slice(insertAt)];
267
273
  const changed = next.length !== order.length || next.some((entry, i) => entry !== order[i]);
268
274
  order = next;
269
275
  return changed;
@@ -278,7 +284,7 @@ function createWindowManager(options = {}) {
278
284
  return win.groupId === null || activeTabs[win.groupId] === win.id;
279
285
  }
280
286
  function buildGroups() {
281
- const result = {};
287
+ const result = /* @__PURE__ */ Object.create(null);
282
288
  for (const [groupId, activeId] of Object.entries(activeTabs)) {
283
289
  result[groupId] = { id: groupId, activeId, members: membersOf(groupId) };
284
290
  }
@@ -335,6 +341,14 @@ function createWindowManager(options = {}) {
335
341
  const targets = focusTargets();
336
342
  focusedId = targets.length > 0 ? targets[targets.length - 1] : null;
337
343
  }
344
+ function reconcileFocus() {
345
+ if (focusedId === null) return;
346
+ const win = windows[focusedId];
347
+ if (win && win.stage !== "minimized" && onActiveWorkspace(win) && isVisibleTab(win)) return;
348
+ const previous = focusedId;
349
+ focusTop();
350
+ if (focusedId) emitFocus(windows[focusedId], previous);
351
+ }
338
352
  function emitFocus(win, previous) {
339
353
  queueEvent(() => emitter.emit("focus", { window: win, previous }));
340
354
  }
@@ -456,7 +470,6 @@ function createWindowManager(options = {}) {
456
470
  const win = windows[id];
457
471
  if (!win) return false;
458
472
  if (!onActiveWorkspace(win)) setWorkspace(win.workspace);
459
- if (!isVisibleTab(win)) activateTab(id);
460
473
  const modal = topModalId();
461
474
  if (modal && modal !== id && win.layer !== "modal") {
462
475
  const modalWin = windows[modal];
@@ -464,6 +477,7 @@ function createWindowManager(options = {}) {
464
477
  commitQuiet();
465
478
  return false;
466
479
  }
480
+ if (!isVisibleTab(win)) activateTab(id);
467
481
  if (win.stage === "minimized") {
468
482
  restore(id);
469
483
  return focusedId === id;
@@ -518,6 +532,7 @@ function createWindowManager(options = {}) {
518
532
  setWindow(next);
519
533
  syncGroup(next);
520
534
  queueEvent(() => emitter.emit("stage", { window: next, previous: win.stage }));
535
+ if (next.groupId !== null) reconcileFocus();
521
536
  commit();
522
537
  return true;
523
538
  }
@@ -722,6 +737,8 @@ function createWindowManager(options = {}) {
722
737
  if (!onActiveWorkspace(updated) && focusedId === id) {
723
738
  focusTop();
724
739
  if (focusedId) emitFocus(windows[focusedId], id);
740
+ } else if (updated.groupId !== null && !onActiveWorkspace(updated)) {
741
+ reconcileFocus();
725
742
  } else if (onActiveWorkspace(updated) && topModalId() === id && focusedId !== id) {
726
743
  const previous = focusedId;
727
744
  focusedId = id;
@@ -747,7 +764,16 @@ function createWindowManager(options = {}) {
747
764
  for (const entry of siblings) if (!expanded.includes(entry)) expanded.push(entry);
748
765
  }
749
766
  if (expanded.length < 2) return null;
750
- const groupId = `${idPrefix}-group-${++groupCounter}`;
767
+ let groupId = `${idPrefix}-group-${++groupCounter}`;
768
+ while (activeTabs[groupId]) groupId = `${idPrefix}-group-${++groupCounter}`;
769
+ const shared = expanded.reduce(
770
+ (size, id) => {
771
+ const fit = normalizeSize(size, windows[id]);
772
+ return { width: Math.max(size.width, fit.width), height: Math.max(size.height, fit.height) };
773
+ },
774
+ { width: host.bounds.width, height: host.bounds.height }
775
+ );
776
+ const bounds = { x: host.bounds.x, y: host.bounds.y, ...shared };
751
777
  const retired = /* @__PURE__ */ new Set();
752
778
  for (const id of expanded) {
753
779
  const win = windows[id];
@@ -755,7 +781,7 @@ function createWindowManager(options = {}) {
755
781
  setWindow({
756
782
  ...win,
757
783
  groupId,
758
- bounds: host.bounds,
784
+ bounds,
759
785
  stage: host.stage,
760
786
  snapZone: host.snapZone,
761
787
  restoreBounds: host.restoreBounds,
@@ -770,8 +796,10 @@ function createWindowManager(options = {}) {
770
796
  raise(host.id);
771
797
  emitGroup(groupId, null);
772
798
  queueEvent(() => emitter.emit("order", { order }));
799
+ const hostVisible = onActiveWorkspace(host) && host.stage !== "minimized";
800
+ if (!hostVisible) reconcileFocus();
773
801
  commit();
774
- if (onActiveWorkspace(host) && host.stage !== "minimized") focus(host.id);
802
+ if (hostVisible) focus(host.id);
775
803
  return groupId;
776
804
  }
777
805
  function ungroup(id) {
@@ -785,7 +813,7 @@ function createWindowManager(options = {}) {
785
813
  dissolveIfOrphaned(groupId);
786
814
  if (membersOf(groupId).length >= 2) emitGroup(groupId, wasActive ? id : null);
787
815
  commit();
788
- focus(id);
816
+ if (onActiveWorkspace(win) && win.stage !== "minimized") focus(id);
789
817
  return true;
790
818
  }
791
819
  function activateTab(id) {
@@ -795,6 +823,10 @@ function createWindowManager(options = {}) {
795
823
  const previous = activeTabs[groupId];
796
824
  if (previous === id) return false;
797
825
  activeTabs = { ...activeTabs, [groupId]: id };
826
+ if (focusedId === previous) {
827
+ focusedId = id;
828
+ emitFocus(win, previous);
829
+ }
798
830
  emitGroup(groupId, previous);
799
831
  commit();
800
832
  return true;
@@ -805,14 +837,15 @@ function createWindowManager(options = {}) {
805
837
  function sendToBack(id) {
806
838
  const win = windows[id];
807
839
  if (!win) return false;
808
- const without = order.filter((entry) => entry !== id);
840
+ const block = blockOf(id);
841
+ const without = order.filter((entry) => !block.includes(entry));
809
842
  const rank = LAYER_RANK[win.layer];
810
843
  let insertAt = 0;
811
844
  for (const entry of without) {
812
845
  if (layerRankOf(entry) < rank) insertAt += 1;
813
846
  else break;
814
847
  }
815
- const next = [...without.slice(0, insertAt), id, ...without.slice(insertAt)];
848
+ const next = [...without.slice(0, insertAt), ...block, ...without.slice(insertAt)];
816
849
  if (next.every((entry, i) => entry === order[i])) return false;
817
850
  order = next;
818
851
  queueEvent(() => emitter.emit("order", { order }));
@@ -876,19 +909,23 @@ function createWindowManager(options = {}) {
876
909
  function reflowViewport() {
877
910
  for (const id of order) {
878
911
  const win = windows[id];
912
+ if (!isVisibleTab(win)) continue;
879
913
  if (win.stage === "maximized") {
880
914
  const updated = { ...win, bounds: fullBounds() };
881
915
  setWindow(updated);
916
+ syncGroup(updated);
882
917
  queueEvent(() => emitter.emit("resize", { window: updated }));
883
918
  } else if (win.stage === "snapped" && win.snapZone) {
884
919
  const updated = { ...win, bounds: snapBounds(win, win.snapZone) };
885
920
  setWindow(updated);
921
+ syncGroup(updated);
886
922
  queueEvent(() => emitter.emit("resize", { window: updated }));
887
923
  } else if (win.stage === "normal" && keepInViewport) {
888
924
  const bounds = clampToViewport(win.bounds, viewport, minVisible);
889
925
  if (!boundsEqual(bounds, win.bounds)) {
890
926
  const updated = { ...win, bounds };
891
927
  setWindow(updated);
928
+ syncGroup(updated);
892
929
  queueEvent(() => emitter.emit("move", { window: updated }));
893
930
  }
894
931
  }
@@ -975,7 +1012,7 @@ function createWindowManager(options = {}) {
975
1012
  function arrange(mode) {
976
1013
  const ids = order.filter((id) => {
977
1014
  const win = windows[id];
978
- return win.stage !== "minimized" && onActiveWorkspace(win);
1015
+ return win.stage !== "minimized" && onActiveWorkspace(win) && isVisibleTab(win);
979
1016
  });
980
1017
  if (ids.length === 0) return;
981
1018
  if (mode === "cascade") {
@@ -1007,7 +1044,8 @@ function createWindowManager(options = {}) {
1007
1044
  }
1008
1045
  function minimizeAll() {
1009
1046
  for (const id of [...order]) {
1010
- if (onActiveWorkspace(windows[id])) minimize(id);
1047
+ const win = windows[id];
1048
+ if (onActiveWorkspace(win) && isVisibleTab(win)) minimize(id);
1011
1049
  }
1012
1050
  }
1013
1051
  function restoreAll() {
@@ -1127,7 +1165,7 @@ function createWindowManager(options = {}) {
1127
1165
  if (focusedCandidate && (focusedCandidate.stage === "minimized" || !onActiveWorkspace(focusedCandidate))) {
1128
1166
  focusedId = null;
1129
1167
  }
1130
- const restoredTabs = {};
1168
+ const restoredTabs = /* @__PURE__ */ Object.create(null);
1131
1169
  const rawTabs = data.activeTabs;
1132
1170
  for (const id of order) {
1133
1171
  const groupId = windows[id].groupId;
@@ -1400,6 +1438,8 @@ function createDragStarter(ctx) {
1400
1438
  const el = ctx.windowElement(id);
1401
1439
  function armGroup(target2) {
1402
1440
  session.groupTarget = target2;
1441
+ session.zone = null;
1442
+ ctx.hidePreview();
1403
1443
  ctx.markGroupTarget(target2);
1404
1444
  }
1405
1445
  function clearHover() {
@@ -1444,9 +1484,9 @@ function createDragStarter(ctx) {
1444
1484
  for (const otherId of state.order) {
1445
1485
  if (otherId === id) continue;
1446
1486
  const other = state.windows[otherId];
1447
- if (other && other.stage !== "minimized" && other.workspace === state.workspace) {
1448
- targets.push(other.bounds);
1449
- }
1487
+ if (!other || other.stage === "minimized" || other.workspace !== state.workspace) continue;
1488
+ if (other.groupId !== null && state.groups[other.groupId]?.activeId !== otherId) continue;
1489
+ targets.push(other.bounds);
1450
1490
  }
1451
1491
  const magnet = magnetize(
1452
1492
  { x: nextX, y: nextY, width: current.bounds.width, height: current.bounds.height },
@@ -1757,6 +1797,7 @@ function attachDesktop(wm, element, options = {}) {
1757
1797
  let lastFocused = null;
1758
1798
  let drag = null;
1759
1799
  let groupTargetId = null;
1800
+ let groupTargetEl = null;
1760
1801
  let cachedRect = null;
1761
1802
  let rectUsers = 0;
1762
1803
  let announcer = null;
@@ -1835,21 +1876,16 @@ function attachDesktop(wm, element, options = {}) {
1835
1876
  const handle = node.closest?.("[data-wm-drag]");
1836
1877
  const host = handle?.closest("[data-wm-window]");
1837
1878
  const id = host?.dataset.wmWindow;
1838
- if (id && id !== selfId && registry.has(id)) return id;
1879
+ if (id && id !== selfId && registry.get(id)?.element === host) return id;
1839
1880
  }
1840
1881
  return null;
1841
1882
  },
1842
1883
  markGroupTarget(id) {
1843
1884
  if (groupTargetId === id) return;
1844
- if (groupTargetId) {
1845
- const previous = registry.get(groupTargetId);
1846
- if (previous) delete previous.element.dataset.wmTabTarget;
1847
- }
1885
+ if (groupTargetEl) delete groupTargetEl.dataset.wmTabTarget;
1848
1886
  groupTargetId = id;
1849
- if (id) {
1850
- const next = registry.get(id);
1851
- if (next) next.element.dataset.wmTabTarget = "";
1852
- }
1887
+ groupTargetEl = id ? registry.get(id)?.element ?? null : null;
1888
+ if (groupTargetEl) groupTargetEl.dataset.wmTabTarget = "";
1853
1889
  },
1854
1890
  currentDrag: () => drag,
1855
1891
  claimDrag(session) {
@@ -2267,5 +2303,5 @@ exports.flipToTarget = flipToTarget;
2267
2303
  exports.magnetize = magnetize;
2268
2304
  exports.prefersReducedMotion = prefersReducedMotion;
2269
2305
  exports.zoneBounds = zoneBounds;
2270
- //# sourceMappingURL=chunk-RXAMUBUJ.cjs.map
2271
- //# sourceMappingURL=chunk-RXAMUBUJ.cjs.map
2306
+ //# sourceMappingURL=chunk-C2UHNBSA.cjs.map
2307
+ //# sourceMappingURL=chunk-C2UHNBSA.cjs.map