dockview-core 4.6.2 → 4.7.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.
Files changed (58) hide show
  1. package/dist/cjs/constants.d.ts +1 -0
  2. package/dist/cjs/constants.js +2 -1
  3. package/dist/cjs/dnd/abstractDragHandler.d.ts +3 -1
  4. package/dist/cjs/dnd/abstractDragHandler.js +6 -2
  5. package/dist/cjs/dnd/droptarget.js +46 -17
  6. package/dist/cjs/dnd/groupDragHandler.d.ts +1 -1
  7. package/dist/cjs/dnd/groupDragHandler.js +2 -2
  8. package/dist/cjs/dockview/components/tab/tab.d.ts +1 -0
  9. package/dist/cjs/dockview/components/tab/tab.js +6 -5
  10. package/dist/cjs/dockview/components/titlebar/voidContainer.d.ts +1 -0
  11. package/dist/cjs/dockview/components/titlebar/voidContainer.js +3 -2
  12. package/dist/cjs/dockview/dockviewComponent.d.ts +6 -0
  13. package/dist/cjs/dockview/dockviewComponent.js +115 -86
  14. package/dist/cjs/gridview/gridview.d.ts +1 -0
  15. package/dist/cjs/gridview/gridview.js +37 -0
  16. package/dist/cjs/overlay/overlayRenderContainer.d.ts +3 -0
  17. package/dist/cjs/overlay/overlayRenderContainer.js +82 -8
  18. package/dist/dockview-core.amd.js +235 -67
  19. package/dist/dockview-core.amd.js.map +1 -1
  20. package/dist/dockview-core.amd.min.js +2 -2
  21. package/dist/dockview-core.amd.min.js.map +1 -1
  22. package/dist/dockview-core.amd.min.noStyle.js +2 -2
  23. package/dist/dockview-core.amd.min.noStyle.js.map +1 -1
  24. package/dist/dockview-core.amd.noStyle.js +234 -66
  25. package/dist/dockview-core.amd.noStyle.js.map +1 -1
  26. package/dist/dockview-core.cjs.js +235 -67
  27. package/dist/dockview-core.cjs.js.map +1 -1
  28. package/dist/dockview-core.esm.js +235 -67
  29. package/dist/dockview-core.esm.js.map +1 -1
  30. package/dist/dockview-core.esm.min.js +2 -2
  31. package/dist/dockview-core.esm.min.js.map +1 -1
  32. package/dist/dockview-core.js +235 -67
  33. package/dist/dockview-core.js.map +1 -1
  34. package/dist/dockview-core.min.js +2 -2
  35. package/dist/dockview-core.min.js.map +1 -1
  36. package/dist/dockview-core.min.noStyle.js +2 -2
  37. package/dist/dockview-core.min.noStyle.js.map +1 -1
  38. package/dist/dockview-core.noStyle.js +234 -66
  39. package/dist/dockview-core.noStyle.js.map +1 -1
  40. package/dist/esm/constants.d.ts +1 -0
  41. package/dist/esm/constants.js +1 -0
  42. package/dist/esm/dnd/abstractDragHandler.d.ts +3 -1
  43. package/dist/esm/dnd/abstractDragHandler.js +6 -2
  44. package/dist/esm/dnd/droptarget.js +46 -17
  45. package/dist/esm/dnd/groupDragHandler.d.ts +1 -1
  46. package/dist/esm/dnd/groupDragHandler.js +2 -2
  47. package/dist/esm/dockview/components/tab/tab.d.ts +1 -0
  48. package/dist/esm/dockview/components/tab/tab.js +6 -5
  49. package/dist/esm/dockview/components/titlebar/voidContainer.d.ts +1 -0
  50. package/dist/esm/dockview/components/titlebar/voidContainer.js +3 -2
  51. package/dist/esm/dockview/dockviewComponent.d.ts +6 -0
  52. package/dist/esm/dockview/dockviewComponent.js +65 -30
  53. package/dist/esm/gridview/gridview.d.ts +1 -0
  54. package/dist/esm/gridview/gridview.js +36 -0
  55. package/dist/esm/overlay/overlayRenderContainer.d.ts +3 -0
  56. package/dist/esm/overlay/overlayRenderContainer.js +69 -8
  57. package/dist/styles/dockview.css +37 -5
  58. package/package.json +1 -1
@@ -159,6 +159,7 @@ var DockviewComponent = /** @class */ (function (_super) {
159
159
  _this.onDidMaximizedGroupChange = _this._onDidMaximizedGroupChange.event;
160
160
  _this._floatingGroups = [];
161
161
  _this._popoutGroups = [];
162
+ _this._popoutRestorationPromise = Promise.resolve();
162
163
  _this._onDidRemoveGroup = new events_1.Emitter();
163
164
  _this.onDidRemoveGroup = _this._onDidRemoveGroup.event;
164
165
  _this._onDidAddGroup = new events_1.Emitter();
@@ -380,6 +381,17 @@ var DockviewComponent = /** @class */ (function (_super) {
380
381
  enumerable: false,
381
382
  configurable: true
382
383
  });
384
+ Object.defineProperty(DockviewComponent.prototype, "popoutRestorationPromise", {
385
+ /**
386
+ * Promise that resolves when all popout groups from the last fromJSON call are restored.
387
+ * Useful for tests that need to wait for delayed popout creation.
388
+ */
389
+ get: function () {
390
+ return this._popoutRestorationPromise;
391
+ },
392
+ enumerable: false,
393
+ configurable: true
394
+ });
383
395
  DockviewComponent.prototype.setVisible = function (panel, visible) {
384
396
  switch (panel.api.location.type) {
385
397
  case 'grid':
@@ -807,6 +819,7 @@ var DockviewComponent = /** @class */ (function (_super) {
807
819
  this.updateWatermark();
808
820
  };
809
821
  DockviewComponent.prototype.orthogonalize = function (position, options) {
822
+ this.gridview.normalize();
810
823
  switch (position) {
811
824
  case 'top':
812
825
  case 'bottom':
@@ -1018,9 +1031,9 @@ var DockviewComponent = /** @class */ (function (_super) {
1018
1031
  return result;
1019
1032
  };
1020
1033
  DockviewComponent.prototype.fromJSON = function (data) {
1021
- var e_6, _a, e_7, _b, e_8, _c, e_9, _d, e_10, _e, e_11, _f, e_12, _g;
1034
+ var e_6, _a, e_7, _b, e_8, _c, e_9, _d, e_10, _e, e_11, _f;
1022
1035
  var _this = this;
1023
- var _h, _j;
1036
+ var _g, _h;
1024
1037
  this.clear();
1025
1038
  if (typeof data !== 'object' || data === null) {
1026
1039
  throw new Error('serialized layout must be a non-null object');
@@ -1034,7 +1047,7 @@ var DockviewComponent = /** @class */ (function (_super) {
1034
1047
  var width = this.width;
1035
1048
  var height = this.height;
1036
1049
  var createGroupFromSerializedState_1 = function (data) {
1037
- var e_13, _a;
1050
+ var e_12, _a;
1038
1051
  var id = data.id, locked = data.locked, hideHeader = data.hideHeader, views = data.views, activeView = data.activeView;
1039
1052
  if (typeof id !== 'string') {
1040
1053
  throw new Error('group id must be of type string');
@@ -1058,12 +1071,12 @@ var DockviewComponent = /** @class */ (function (_super) {
1058
1071
  createdPanels.push(panel);
1059
1072
  }
1060
1073
  }
1061
- catch (e_13_1) { e_13 = { error: e_13_1 }; }
1074
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
1062
1075
  finally {
1063
1076
  try {
1064
1077
  if (views_1_1 && !views_1_1.done && (_a = views_1.return)) _a.call(views_1);
1065
1078
  }
1066
- finally { if (e_13) throw e_13.error; }
1079
+ finally { if (e_12) throw e_12.error; }
1067
1080
  }
1068
1081
  for (var i = 0; i < views.length; i++) {
1069
1082
  var panel = createdPanels[i];
@@ -1087,7 +1100,7 @@ var DockviewComponent = /** @class */ (function (_super) {
1087
1100
  },
1088
1101
  });
1089
1102
  this.layout(width, height, true);
1090
- var serializedFloatingGroups = (_h = data.floatingGroups) !== null && _h !== void 0 ? _h : [];
1103
+ var serializedFloatingGroups = (_g = data.floatingGroups) !== null && _g !== void 0 ? _g : [];
1091
1104
  try {
1092
1105
  for (var serializedFloatingGroups_1 = __values(serializedFloatingGroups), serializedFloatingGroups_1_1 = serializedFloatingGroups_1.next(); !serializedFloatingGroups_1_1.done; serializedFloatingGroups_1_1 = serializedFloatingGroups_1.next()) {
1093
1106
  var serializedFloatingGroup = serializedFloatingGroups_1_1.value;
@@ -1109,42 +1122,44 @@ var DockviewComponent = /** @class */ (function (_super) {
1109
1122
  }
1110
1123
  finally { if (e_6) throw e_6.error; }
1111
1124
  }
1112
- var serializedPopoutGroups = (_j = data.popoutGroups) !== null && _j !== void 0 ? _j : [];
1125
+ var serializedPopoutGroups = (_h = data.popoutGroups) !== null && _h !== void 0 ? _h : [];
1126
+ // Create a promise that resolves when all popout groups are created
1127
+ var popoutPromises_1 = [];
1128
+ // Queue popup group creation with delays to avoid browser blocking
1129
+ serializedPopoutGroups.forEach(function (serializedPopoutGroup, index) {
1130
+ var data = serializedPopoutGroup.data, position = serializedPopoutGroup.position, gridReferenceGroup = serializedPopoutGroup.gridReferenceGroup, url = serializedPopoutGroup.url;
1131
+ var group = createGroupFromSerializedState_1(data);
1132
+ // Add a small delay for each popup after the first to avoid browser popup blocking
1133
+ var popoutPromise = new Promise(function (resolve) {
1134
+ setTimeout(function () {
1135
+ _this.addPopoutGroup(group, {
1136
+ position: position !== null && position !== void 0 ? position : undefined,
1137
+ overridePopoutGroup: gridReferenceGroup ? group : undefined,
1138
+ referenceGroup: gridReferenceGroup
1139
+ ? _this.getPanel(gridReferenceGroup)
1140
+ : undefined,
1141
+ popoutUrl: url,
1142
+ });
1143
+ resolve();
1144
+ }, index * constants_1.DESERIALIZATION_POPOUT_DELAY_MS); // 100ms delay between each popup
1145
+ });
1146
+ popoutPromises_1.push(popoutPromise);
1147
+ });
1148
+ // Store the promise for tests to wait on
1149
+ this._popoutRestorationPromise = Promise.all(popoutPromises_1).then(function () { return void 0; });
1113
1150
  try {
1114
- for (var serializedPopoutGroups_1 = __values(serializedPopoutGroups), serializedPopoutGroups_1_1 = serializedPopoutGroups_1.next(); !serializedPopoutGroups_1_1.done; serializedPopoutGroups_1_1 = serializedPopoutGroups_1.next()) {
1115
- var serializedPopoutGroup = serializedPopoutGroups_1_1.value;
1116
- var data_2 = serializedPopoutGroup.data, position = serializedPopoutGroup.position, gridReferenceGroup = serializedPopoutGroup.gridReferenceGroup, url = serializedPopoutGroup.url;
1117
- var group = createGroupFromSerializedState_1(data_2);
1118
- this.addPopoutGroup(group, {
1119
- position: position !== null && position !== void 0 ? position : undefined,
1120
- overridePopoutGroup: gridReferenceGroup ? group : undefined,
1121
- referenceGroup: gridReferenceGroup
1122
- ? this.getPanel(gridReferenceGroup)
1123
- : undefined,
1124
- popoutUrl: url,
1125
- });
1151
+ for (var _j = __values(this._floatingGroups), _k = _j.next(); !_k.done; _k = _j.next()) {
1152
+ var floatingGroup = _k.value;
1153
+ floatingGroup.overlay.setBounds();
1126
1154
  }
1127
1155
  }
1128
1156
  catch (e_7_1) { e_7 = { error: e_7_1 }; }
1129
1157
  finally {
1130
1158
  try {
1131
- if (serializedPopoutGroups_1_1 && !serializedPopoutGroups_1_1.done && (_b = serializedPopoutGroups_1.return)) _b.call(serializedPopoutGroups_1);
1159
+ if (_k && !_k.done && (_b = _j.return)) _b.call(_j);
1132
1160
  }
1133
1161
  finally { if (e_7) throw e_7.error; }
1134
1162
  }
1135
- try {
1136
- for (var _k = __values(this._floatingGroups), _l = _k.next(); !_l.done; _l = _k.next()) {
1137
- var floatingGroup = _l.value;
1138
- floatingGroup.overlay.setBounds();
1139
- }
1140
- }
1141
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
1142
- finally {
1143
- try {
1144
- if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
1145
- }
1146
- finally { if (e_8) throw e_8.error; }
1147
- }
1148
1163
  if (typeof activeGroup === 'string') {
1149
1164
  var panel = this.getPanel(activeGroup);
1150
1165
  if (panel) {
@@ -1158,65 +1173,65 @@ var DockviewComponent = /** @class */ (function (_super) {
1158
1173
  /**
1159
1174
  * Takes all the successfully created groups and remove all of their panels.
1160
1175
  */
1161
- for (var _m = __values(this.groups), _o = _m.next(); !_o.done; _o = _m.next()) {
1162
- var group = _o.value;
1176
+ for (var _l = __values(this.groups), _m = _l.next(); !_m.done; _m = _l.next()) {
1177
+ var group = _m.value;
1163
1178
  try {
1164
- for (var _p = (e_10 = void 0, __values(group.panels)), _q = _p.next(); !_q.done; _q = _p.next()) {
1165
- var panel = _q.value;
1179
+ for (var _o = (e_9 = void 0, __values(group.panels)), _p = _o.next(); !_p.done; _p = _o.next()) {
1180
+ var panel = _p.value;
1166
1181
  this.removePanel(panel, {
1167
1182
  removeEmptyGroup: false,
1168
1183
  skipDispose: false,
1169
1184
  });
1170
1185
  }
1171
1186
  }
1172
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
1187
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
1173
1188
  finally {
1174
1189
  try {
1175
- if (_q && !_q.done && (_e = _p.return)) _e.call(_p);
1190
+ if (_p && !_p.done && (_d = _o.return)) _d.call(_o);
1176
1191
  }
1177
- finally { if (e_10) throw e_10.error; }
1192
+ finally { if (e_9) throw e_9.error; }
1178
1193
  }
1179
1194
  }
1180
1195
  }
1181
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
1196
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
1182
1197
  finally {
1183
1198
  try {
1184
- if (_o && !_o.done && (_d = _m.return)) _d.call(_m);
1199
+ if (_m && !_m.done && (_c = _l.return)) _c.call(_l);
1185
1200
  }
1186
- finally { if (e_9) throw e_9.error; }
1201
+ finally { if (e_8) throw e_8.error; }
1187
1202
  }
1188
1203
  try {
1189
1204
  /**
1190
1205
  * To remove a group we cannot call this.removeGroup(...) since this makes assumptions about
1191
1206
  * the underlying HTMLElement existing in the Gridview.
1192
1207
  */
1193
- for (var _r = __values(this.groups), _s = _r.next(); !_s.done; _s = _r.next()) {
1194
- var group = _s.value;
1208
+ for (var _q = __values(this.groups), _r = _q.next(); !_r.done; _r = _q.next()) {
1209
+ var group = _r.value;
1195
1210
  group.dispose();
1196
1211
  this._groups.delete(group.id);
1197
1212
  this._onDidRemoveGroup.fire(group);
1198
1213
  }
1199
1214
  }
1200
- catch (e_11_1) { e_11 = { error: e_11_1 }; }
1215
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
1201
1216
  finally {
1202
1217
  try {
1203
- if (_s && !_s.done && (_f = _r.return)) _f.call(_r);
1218
+ if (_r && !_r.done && (_e = _q.return)) _e.call(_q);
1204
1219
  }
1205
- finally { if (e_11) throw e_11.error; }
1220
+ finally { if (e_10) throw e_10.error; }
1206
1221
  }
1207
1222
  try {
1208
1223
  // iterate over a reassigned array since original array will be modified
1209
- for (var _t = __values(__spreadArray([], __read(this._floatingGroups), false)), _u = _t.next(); !_u.done; _u = _t.next()) {
1210
- var floatingGroup = _u.value;
1224
+ for (var _s = __values(__spreadArray([], __read(this._floatingGroups), false)), _t = _s.next(); !_t.done; _t = _s.next()) {
1225
+ var floatingGroup = _t.value;
1211
1226
  floatingGroup.dispose();
1212
1227
  }
1213
1228
  }
1214
- catch (e_12_1) { e_12 = { error: e_12_1 }; }
1229
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
1215
1230
  finally {
1216
1231
  try {
1217
- if (_u && !_u.done && (_g = _t.return)) _g.call(_t);
1232
+ if (_t && !_t.done && (_f = _s.return)) _f.call(_s);
1218
1233
  }
1219
- finally { if (e_12) throw e_12.error; }
1234
+ finally { if (e_11) throw e_11.error; }
1220
1235
  }
1221
1236
  // fires clean-up events and clears the underlying HTML gridview.
1222
1237
  this.clear();
@@ -1228,10 +1243,14 @@ var DockviewComponent = /** @class */ (function (_super) {
1228
1243
  throw err;
1229
1244
  }
1230
1245
  this.updateWatermark();
1246
+ // Force position updates for always visible panels after DOM layout is complete
1247
+ requestAnimationFrame(function () {
1248
+ _this.overlayRenderContainer.updateAllPositions();
1249
+ });
1231
1250
  this._onDidLayoutFromJSON.fire();
1232
1251
  };
1233
1252
  DockviewComponent.prototype.clear = function () {
1234
- var e_14, _a;
1253
+ var e_13, _a;
1235
1254
  var groups = Array.from(this._groups.values()).map(function (_) { return _.value; });
1236
1255
  var hasActiveGroup = !!this.activeGroup;
1237
1256
  try {
@@ -1241,12 +1260,12 @@ var DockviewComponent = /** @class */ (function (_super) {
1241
1260
  this.removeGroup(group, { skipActive: true });
1242
1261
  }
1243
1262
  }
1244
- catch (e_14_1) { e_14 = { error: e_14_1 }; }
1263
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
1245
1264
  finally {
1246
1265
  try {
1247
1266
  if (groups_1_1 && !groups_1_1.done && (_a = groups_1.return)) _a.call(groups_1);
1248
1267
  }
1249
- finally { if (e_14) throw e_14.error; }
1268
+ finally { if (e_13) throw e_13.error; }
1250
1269
  }
1251
1270
  if (hasActiveGroup) {
1252
1271
  this.doSetGroupAndPanelActive(undefined);
@@ -1254,7 +1273,7 @@ var DockviewComponent = /** @class */ (function (_super) {
1254
1273
  this.gridview.clear();
1255
1274
  };
1256
1275
  DockviewComponent.prototype.closeAllGroups = function () {
1257
- var e_15, _a;
1276
+ var e_14, _a;
1258
1277
  try {
1259
1278
  for (var _b = __values(this._groups.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
1260
1279
  var entry = _c.value;
@@ -1262,12 +1281,12 @@ var DockviewComponent = /** @class */ (function (_super) {
1262
1281
  group.value.model.closeAllPanels();
1263
1282
  }
1264
1283
  }
1265
- catch (e_15_1) { e_15 = { error: e_15_1 }; }
1284
+ catch (e_14_1) { e_14 = { error: e_14_1 }; }
1266
1285
  finally {
1267
1286
  try {
1268
1287
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1269
1288
  }
1270
- finally { if (e_15) throw e_15.error; }
1289
+ finally { if (e_14) throw e_14.error; }
1271
1290
  }
1272
1291
  };
1273
1292
  DockviewComponent.prototype.addPanel = function (options) {
@@ -1518,7 +1537,7 @@ var DockviewComponent = /** @class */ (function (_super) {
1518
1537
  this.doRemoveGroup(group, options);
1519
1538
  };
1520
1539
  DockviewComponent.prototype.doRemoveGroup = function (group, options) {
1521
- var e_16, _a;
1540
+ var e_15, _a;
1522
1541
  var _b;
1523
1542
  var panels = __spreadArray([], __read(group.panels), false); // reassign since group panels will mutate
1524
1543
  if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
@@ -1531,12 +1550,12 @@ var DockviewComponent = /** @class */ (function (_super) {
1531
1550
  });
1532
1551
  }
1533
1552
  }
1534
- catch (e_16_1) { e_16 = { error: e_16_1 }; }
1553
+ catch (e_15_1) { e_15 = { error: e_15_1 }; }
1535
1554
  finally {
1536
1555
  try {
1537
1556
  if (panels_1_1 && !panels_1_1.done && (_a = panels_1.return)) _a.call(panels_1);
1538
1557
  }
1539
- finally { if (e_16) throw e_16.error; }
1558
+ finally { if (e_15) throw e_15.error; }
1540
1559
  }
1541
1560
  }
1542
1561
  var activePanel = this.activePanel;
@@ -1652,11 +1671,13 @@ var DockviewComponent = /** @class */ (function (_super) {
1652
1671
  // remove the group and do not set a new group as active
1653
1672
  this.doRemoveGroup(sourceGroup, { skipActive: true });
1654
1673
  }
1674
+ // Check if destination group is empty - if so, force render the component
1675
+ var isDestinationGroupEmpty_1 = destinationGroup.model.size === 0;
1655
1676
  this.movingLock(function () {
1656
1677
  var _a;
1657
1678
  return destinationGroup.model.openPanel(removedPanel_1, {
1658
1679
  index: destinationIndex,
1659
- skipSetActive: (_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false,
1680
+ skipSetActive: ((_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false) && !isDestinationGroupEmpty_1,
1660
1681
  skipSetGroupActive: true,
1661
1682
  });
1662
1683
  });
@@ -1775,8 +1796,7 @@ var DockviewComponent = /** @class */ (function (_super) {
1775
1796
  var to = options.to.group;
1776
1797
  var target = options.to.position;
1777
1798
  if (target === 'center') {
1778
- var activePanel = from.activePanel;
1779
- var targetActivePanel = to.activePanel;
1799
+ var activePanel_1 = from.activePanel;
1780
1800
  var panels_2 = this.movingLock(function () {
1781
1801
  return __spreadArray([], __read(from.panels), false).map(function (p) {
1782
1802
  return from.model.removePanel(p.id, {
@@ -1788,35 +1808,34 @@ var DockviewComponent = /** @class */ (function (_super) {
1788
1808
  this.doRemoveGroup(from, { skipActive: true });
1789
1809
  }
1790
1810
  this.movingLock(function () {
1791
- var e_17, _a;
1811
+ var e_16, _a;
1792
1812
  try {
1793
1813
  for (var panels_3 = __values(panels_2), panels_3_1 = panels_3.next(); !panels_3_1.done; panels_3_1 = panels_3.next()) {
1794
1814
  var panel = panels_3_1.value;
1795
1815
  to.model.openPanel(panel, {
1796
- skipSetActive: true, // Always skip setting panels active during move
1816
+ skipSetActive: panel !== activePanel_1,
1797
1817
  skipSetGroupActive: true,
1798
1818
  });
1799
1819
  }
1800
1820
  }
1801
- catch (e_17_1) { e_17 = { error: e_17_1 }; }
1821
+ catch (e_16_1) { e_16 = { error: e_16_1 }; }
1802
1822
  finally {
1803
1823
  try {
1804
1824
  if (panels_3_1 && !panels_3_1.done && (_a = panels_3.return)) _a.call(panels_3);
1805
1825
  }
1806
- finally { if (e_17) throw e_17.error; }
1826
+ finally { if (e_16) throw e_16.error; }
1807
1827
  }
1808
1828
  });
1809
- if (!options.skipSetActive) {
1810
- // Make the moved panel (from the source group) active
1811
- if (activePanel) {
1812
- this.doSetGroupAndPanelActive(to);
1813
- }
1829
+ // Ensure group becomes active after move
1830
+ if (options.skipSetActive !== true) {
1831
+ // For center moves (merges), we need to ensure the target group is active
1832
+ // unless explicitly told not to (skipSetActive: true)
1833
+ this.doSetGroupAndPanelActive(to);
1814
1834
  }
1815
- else if (targetActivePanel) {
1816
- // Ensure the target group's original active panel remains active
1817
- to.model.openPanel(targetActivePanel, {
1818
- skipSetGroupActive: true
1819
- });
1835
+ else if (!this.activePanel) {
1836
+ // Even with skipSetActive: true, ensure there's an active panel if none exists
1837
+ // This maintains basic functionality while respecting skipSetActive
1838
+ this.doSetGroupAndPanelActive(to);
1820
1839
  }
1821
1840
  }
1822
1841
  else {
@@ -1846,20 +1865,26 @@ var DockviewComponent = /** @class */ (function (_super) {
1846
1865
  if (selectedPopoutGroup.referenceGroup) {
1847
1866
  var referenceGroup = this.getPanel(selectedPopoutGroup.referenceGroup);
1848
1867
  if (referenceGroup && !referenceGroup.api.isVisible) {
1849
- this.doRemoveGroup(referenceGroup, { skipActive: true });
1868
+ this.doRemoveGroup(referenceGroup, {
1869
+ skipActive: true,
1870
+ });
1850
1871
  }
1851
1872
  }
1852
1873
  // Manually dispose the window without triggering restoration
1853
1874
  selectedPopoutGroup.window.dispose();
1854
1875
  // Update group's location and containers for target
1855
1876
  if (to.api.location.type === 'grid') {
1856
- from.model.renderContainer = this.overlayRenderContainer;
1857
- from.model.dropTargetContainer = this.rootDropTargetContainer;
1877
+ from.model.renderContainer =
1878
+ this.overlayRenderContainer;
1879
+ from.model.dropTargetContainer =
1880
+ this.rootDropTargetContainer;
1858
1881
  from.model.location = { type: 'grid' };
1859
1882
  }
1860
1883
  else if (to.api.location.type === 'floating') {
1861
- from.model.renderContainer = this.overlayRenderContainer;
1862
- from.model.dropTargetContainer = this.rootDropTargetContainer;
1884
+ from.model.renderContainer =
1885
+ this.overlayRenderContainer;
1886
+ from.model.dropTargetContainer =
1887
+ this.rootDropTargetContainer;
1863
1888
  from.model.location = { type: 'floating' };
1864
1889
  }
1865
1890
  break;
@@ -1927,8 +1952,12 @@ var DockviewComponent = /** @class */ (function (_super) {
1927
1952
  from.panels.forEach(function (panel) {
1928
1953
  _this._onDidMovePanel.fire({ panel: panel, from: from });
1929
1954
  });
1930
- if (!options.skipSetActive) {
1931
- this.doSetGroupAndPanelActive(from);
1955
+ // Ensure group becomes active after move
1956
+ if (options.skipSetActive === false) {
1957
+ // Only activate when explicitly requested (skipSetActive: false)
1958
+ // Use 'to' group for non-center moves since 'from' may have been destroyed
1959
+ var targetGroup = to !== null && to !== void 0 ? to : from;
1960
+ this.doSetGroupAndPanelActive(targetGroup);
1932
1961
  }
1933
1962
  };
1934
1963
  DockviewComponent.prototype.doSetGroupActive = function (group) {
@@ -134,6 +134,7 @@ export declare class Gridview implements IDisposable {
134
134
  private _deserializeNode;
135
135
  private get root();
136
136
  private set root(value);
137
+ normalize(): void;
137
138
  /**
138
139
  * If the root is orientated as a VERTICAL node then nest the existing root within a new HORIZIONTAL root node
139
140
  * If the root is orientated as a HORIZONTAL node then nest the existing root within a new VERITCAL root node
@@ -45,6 +45,19 @@ function findLeaf(candiateNode, last) {
45
45
  }
46
46
  throw new Error('invalid node');
47
47
  }
48
+ function cloneNode(node, size, orthogonalSize) {
49
+ if (node instanceof branchNode_1.BranchNode) {
50
+ var result = new branchNode_1.BranchNode(node.orientation, node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled, node.margin);
51
+ for (var i = node.children.length - 1; i >= 0; i--) {
52
+ var child = node.children[i];
53
+ result.addChild(cloneNode(child, child.size, child.orthogonalSize), child.size, 0, true);
54
+ }
55
+ return result;
56
+ }
57
+ else {
58
+ return new leafNode_1.LeafNode(node.view, node.orientation, orthogonalSize);
59
+ }
60
+ }
48
61
  function flipNode(node, size, orthogonalSize) {
49
62
  if (node instanceof branchNode_1.BranchNode) {
50
63
  var result = new branchNode_1.BranchNode((0, exports.orthogonal)(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled, node.margin);
@@ -471,6 +484,30 @@ var Gridview = /** @class */ (function () {
471
484
  enumerable: false,
472
485
  configurable: true
473
486
  });
487
+ Gridview.prototype.normalize = function () {
488
+ var _this = this;
489
+ if (!this._root) {
490
+ return;
491
+ }
492
+ if (this._root.children.length !== 1) {
493
+ return;
494
+ }
495
+ var oldRoot = this.root;
496
+ // can remove one level of redundant branching if there is only a single child
497
+ var childReference = oldRoot.children[0];
498
+ if (childReference instanceof leafNode_1.LeafNode) {
499
+ return;
500
+ }
501
+ oldRoot.element.remove();
502
+ var child = oldRoot.removeChild(0); // Remove child to prevent double disposal
503
+ oldRoot.dispose(); // Dispose old root (won't dispose removed child)
504
+ child.dispose(); // Dispose the removed child
505
+ this._root = cloneNode(childReference, childReference.size, childReference.orthogonalSize);
506
+ this.element.appendChild(this._root.element);
507
+ this.disposable.value = this._root.onDidChange(function (e) {
508
+ _this._onDidChange.fire(e);
509
+ });
510
+ };
474
511
  /**
475
512
  * If the root is orientated as a VERTICAL node then nest the existing root within a new HORIZIONTAL root node
476
513
  * If the root is orientated as a HORIZONTAL node then nest the existing root within a new VERITCAL root node
@@ -12,7 +12,10 @@ export declare class OverlayRenderContainer extends CompositeDisposable {
12
12
  readonly accessor: DockviewComponent;
13
13
  private readonly map;
14
14
  private _disposed;
15
+ private readonly positionCache;
16
+ private readonly pendingUpdates;
15
17
  constructor(element: HTMLElement, accessor: DockviewComponent);
18
+ updateAllPositions(): void;
16
19
  detatch(panel: IDockviewPanel): boolean;
17
20
  attach(options: {
18
21
  panel: IDockviewPanel;
@@ -30,6 +30,36 @@ exports.OverlayRenderContainer = void 0;
30
30
  var dnd_1 = require("../dnd/dnd");
31
31
  var dom_1 = require("../dom");
32
32
  var lifecycle_1 = require("../lifecycle");
33
+ var PositionCache = /** @class */ (function () {
34
+ function PositionCache() {
35
+ this.cache = new Map();
36
+ this.currentFrameId = 0;
37
+ this.rafId = null;
38
+ }
39
+ PositionCache.prototype.getPosition = function (element) {
40
+ var cached = this.cache.get(element);
41
+ if (cached && cached.frameId === this.currentFrameId) {
42
+ return cached.rect;
43
+ }
44
+ this.scheduleFrameUpdate();
45
+ var rect = (0, dom_1.getDomNodePagePosition)(element);
46
+ this.cache.set(element, { rect: rect, frameId: this.currentFrameId });
47
+ return rect;
48
+ };
49
+ PositionCache.prototype.invalidate = function () {
50
+ this.currentFrameId++;
51
+ };
52
+ PositionCache.prototype.scheduleFrameUpdate = function () {
53
+ var _this = this;
54
+ if (this.rafId)
55
+ return;
56
+ this.rafId = requestAnimationFrame(function () {
57
+ _this.currentFrameId++;
58
+ _this.rafId = null;
59
+ });
60
+ };
61
+ return PositionCache;
62
+ }());
33
63
  function createFocusableElement() {
34
64
  var element = document.createElement('div');
35
65
  element.tabIndex = -1;
@@ -43,6 +73,8 @@ var OverlayRenderContainer = /** @class */ (function (_super) {
43
73
  _this.accessor = accessor;
44
74
  _this.map = {};
45
75
  _this._disposed = false;
76
+ _this.positionCache = new PositionCache();
77
+ _this.pendingUpdates = new Set();
46
78
  _this.addDisposables(lifecycle_1.Disposable.from(function () {
47
79
  var e_1, _a;
48
80
  try {
@@ -63,6 +95,30 @@ var OverlayRenderContainer = /** @class */ (function (_super) {
63
95
  }));
64
96
  return _this;
65
97
  }
98
+ OverlayRenderContainer.prototype.updateAllPositions = function () {
99
+ var e_2, _a;
100
+ if (this._disposed) {
101
+ return;
102
+ }
103
+ // Invalidate position cache to force recalculation
104
+ this.positionCache.invalidate();
105
+ try {
106
+ // Call resize function directly for all visible panels
107
+ for (var _b = __values(Object.values(this.map)), _c = _b.next(); !_c.done; _c = _b.next()) {
108
+ var entry = _c.value;
109
+ if (entry.panel.api.isVisible && entry.resize) {
110
+ entry.resize();
111
+ }
112
+ }
113
+ }
114
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
115
+ finally {
116
+ try {
117
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
118
+ }
119
+ finally { if (e_2) throw e_2.error; }
120
+ }
121
+ };
66
122
  OverlayRenderContainer.prototype.detatch = function (panel) {
67
123
  if (this.map[panel.api.id]) {
68
124
  var _a = this.map[panel.api.id], disposable = _a.disposable, destroy = _a.destroy;
@@ -94,17 +150,33 @@ var OverlayRenderContainer = /** @class */ (function (_super) {
94
150
  this.element.appendChild(focusContainer);
95
151
  }
96
152
  var resize = function () {
97
- // TODO propagate position to avoid getDomNodePagePosition calls, possible performance bottleneck?
98
- var box = (0, dom_1.getDomNodePagePosition)(referenceContainer.element);
99
- var box2 = (0, dom_1.getDomNodePagePosition)(_this.element);
100
- focusContainer.style.left = "".concat(box.left - box2.left, "px");
101
- focusContainer.style.top = "".concat(box.top - box2.top, "px");
102
- focusContainer.style.width = "".concat(box.width, "px");
103
- focusContainer.style.height = "".concat(box.height, "px");
104
- (0, dom_1.toggleClass)(focusContainer, 'dv-render-overlay-float', panel.group.api.location.type === 'floating');
153
+ var panelId = panel.api.id;
154
+ if (_this.pendingUpdates.has(panelId)) {
155
+ return; // Update already scheduled
156
+ }
157
+ _this.pendingUpdates.add(panelId);
158
+ requestAnimationFrame(function () {
159
+ _this.pendingUpdates.delete(panelId);
160
+ if (_this.isDisposed || !_this.map[panelId]) {
161
+ return;
162
+ }
163
+ var box = _this.positionCache.getPosition(referenceContainer.element);
164
+ var box2 = _this.positionCache.getPosition(_this.element);
165
+ // Use traditional positioning for overlay containers
166
+ var left = box.left - box2.left;
167
+ var top = box.top - box2.top;
168
+ var width = box.width;
169
+ var height = box.height;
170
+ focusContainer.style.left = "".concat(left, "px");
171
+ focusContainer.style.top = "".concat(top, "px");
172
+ focusContainer.style.width = "".concat(width, "px");
173
+ focusContainer.style.height = "".concat(height, "px");
174
+ (0, dom_1.toggleClass)(focusContainer, 'dv-render-overlay-float', panel.group.api.location.type === 'floating');
175
+ });
105
176
  };
106
177
  var visibilityChanged = function () {
107
178
  if (panel.api.isVisible) {
179
+ _this.positionCache.invalidate();
108
180
  resize();
109
181
  }
110
182
  focusContainer.style.display = panel.api.isVisible ? '' : 'none';
@@ -201,6 +273,8 @@ var OverlayRenderContainer = /** @class */ (function (_super) {
201
273
  this.map[panel.api.id].disposable.dispose();
202
274
  // and reset the disposable to the active reference-container
203
275
  this.map[panel.api.id].disposable = disposable;
276
+ // store the resize function for direct access
277
+ this.map[panel.api.id].resize = resize;
204
278
  return focusContainer;
205
279
  };
206
280
  return OverlayRenderContainer;