dockview-core 4.6.0 → 4.7.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.
Files changed (42) hide show
  1. package/dist/cjs/constants.d.ts +1 -0
  2. package/dist/cjs/constants.js +2 -1
  3. package/dist/cjs/dnd/droptarget.js +46 -17
  4. package/dist/cjs/dockview/dockviewComponent.d.ts +6 -0
  5. package/dist/cjs/dockview/dockviewComponent.js +112 -85
  6. package/dist/cjs/gridview/gridview.d.ts +1 -0
  7. package/dist/cjs/gridview/gridview.js +37 -0
  8. package/dist/cjs/overlay/overlayRenderContainer.d.ts +3 -0
  9. package/dist/cjs/overlay/overlayRenderContainer.js +82 -8
  10. package/dist/dockview-core.amd.js +215 -55
  11. package/dist/dockview-core.amd.js.map +1 -1
  12. package/dist/dockview-core.amd.min.js +2 -2
  13. package/dist/dockview-core.amd.min.js.map +1 -1
  14. package/dist/dockview-core.amd.min.noStyle.js +2 -2
  15. package/dist/dockview-core.amd.min.noStyle.js.map +1 -1
  16. package/dist/dockview-core.amd.noStyle.js +214 -54
  17. package/dist/dockview-core.amd.noStyle.js.map +1 -1
  18. package/dist/dockview-core.cjs.js +215 -55
  19. package/dist/dockview-core.cjs.js.map +1 -1
  20. package/dist/dockview-core.esm.js +215 -55
  21. package/dist/dockview-core.esm.js.map +1 -1
  22. package/dist/dockview-core.esm.min.js +2 -2
  23. package/dist/dockview-core.esm.min.js.map +1 -1
  24. package/dist/dockview-core.js +215 -55
  25. package/dist/dockview-core.js.map +1 -1
  26. package/dist/dockview-core.min.js +2 -2
  27. package/dist/dockview-core.min.js.map +1 -1
  28. package/dist/dockview-core.min.noStyle.js +2 -2
  29. package/dist/dockview-core.min.noStyle.js.map +1 -1
  30. package/dist/dockview-core.noStyle.js +214 -54
  31. package/dist/dockview-core.noStyle.js.map +1 -1
  32. package/dist/esm/constants.d.ts +1 -0
  33. package/dist/esm/constants.js +1 -0
  34. package/dist/esm/dnd/droptarget.js +46 -17
  35. package/dist/esm/dockview/dockviewComponent.d.ts +6 -0
  36. package/dist/esm/dockview/dockviewComponent.js +62 -29
  37. package/dist/esm/gridview/gridview.d.ts +1 -0
  38. package/dist/esm/gridview/gridview.js +36 -0
  39. package/dist/esm/overlay/overlayRenderContainer.d.ts +3 -0
  40. package/dist/esm/overlay/overlayRenderContainer.js +69 -8
  41. package/dist/styles/dockview.css +37 -5
  42. package/package.json +1 -1
@@ -5,3 +5,4 @@ export declare const DEFAULT_FLOATING_GROUP_POSITION: {
5
5
  width: number;
6
6
  height: number;
7
7
  };
8
+ export declare const DESERIALIZATION_POPOUT_DELAY_MS = 100;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_FLOATING_GROUP_POSITION = exports.DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = void 0;
3
+ exports.DESERIALIZATION_POPOUT_DELAY_MS = exports.DEFAULT_FLOATING_GROUP_POSITION = exports.DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = void 0;
4
4
  exports.DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
5
5
  exports.DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100, width: 300, height: 300 };
6
+ exports.DESERIALIZATION_POPOUT_DELAY_MS = 100;
@@ -21,6 +21,48 @@ var events_1 = require("../events");
21
21
  var lifecycle_1 = require("../lifecycle");
22
22
  var dnd_1 = require("./dnd");
23
23
  var math_1 = require("../math");
24
+ function setGPUOptimizedBounds(element, bounds) {
25
+ var top = bounds.top, left = bounds.left, width = bounds.width, height = bounds.height;
26
+ var topPx = "".concat(Math.round(top), "px");
27
+ var leftPx = "".concat(Math.round(left), "px");
28
+ var widthPx = "".concat(Math.round(width), "px");
29
+ var heightPx = "".concat(Math.round(height), "px");
30
+ // Use traditional positioning but maintain GPU layer
31
+ element.style.top = topPx;
32
+ element.style.left = leftPx;
33
+ element.style.width = widthPx;
34
+ element.style.height = heightPx;
35
+ element.style.visibility = 'visible';
36
+ // Ensure GPU layer is maintained
37
+ if (!element.style.transform || element.style.transform === '') {
38
+ element.style.transform = 'translate3d(0, 0, 0)';
39
+ }
40
+ }
41
+ function setGPUOptimizedBoundsFromStrings(element, bounds) {
42
+ var top = bounds.top, left = bounds.left, width = bounds.width, height = bounds.height;
43
+ // Use traditional positioning but maintain GPU layer
44
+ element.style.top = top;
45
+ element.style.left = left;
46
+ element.style.width = width;
47
+ element.style.height = height;
48
+ element.style.visibility = 'visible';
49
+ // Ensure GPU layer is maintained
50
+ if (!element.style.transform || element.style.transform === '') {
51
+ element.style.transform = 'translate3d(0, 0, 0)';
52
+ }
53
+ }
54
+ function checkBoundsChanged(element, bounds) {
55
+ var top = bounds.top, left = bounds.left, width = bounds.width, height = bounds.height;
56
+ var topPx = "".concat(Math.round(top), "px");
57
+ var leftPx = "".concat(Math.round(left), "px");
58
+ var widthPx = "".concat(Math.round(width), "px");
59
+ var heightPx = "".concat(Math.round(height), "px");
60
+ // Check if position or size changed (back to traditional method)
61
+ return element.style.top !== topPx ||
62
+ element.style.left !== leftPx ||
63
+ element.style.width !== widthPx ||
64
+ element.style.height !== heightPx;
65
+ }
24
66
  var WillShowOverlayEvent = /** @class */ (function (_super) {
25
67
  __extends(WillShowOverlayEvent, _super);
26
68
  function WillShowOverlayEvent(options) {
@@ -328,21 +370,11 @@ var Droptarget = /** @class */ (function (_super) {
328
370
  box_1.left = rootLeft + width - 4;
329
371
  box_1.width = 4;
330
372
  }
331
- var topPx = "".concat(Math.round(box_1.top), "px");
332
- var leftPx = "".concat(Math.round(box_1.left), "px");
333
- var widthPx = "".concat(Math.round(box_1.width), "px");
334
- var heightPx = "".concat(Math.round(box_1.height), "px");
335
- if (overlay_1.style.top === topPx &&
336
- overlay_1.style.left === leftPx &&
337
- overlay_1.style.width === widthPx &&
338
- overlay_1.style.height === heightPx) {
373
+ // Use GPU-optimized bounds checking and setting
374
+ if (!checkBoundsChanged(overlay_1, box_1)) {
339
375
  return;
340
376
  }
341
- overlay_1.style.top = topPx;
342
- overlay_1.style.left = leftPx;
343
- overlay_1.style.width = widthPx;
344
- overlay_1.style.height = heightPx;
345
- overlay_1.style.visibility = 'visible';
377
+ setGPUOptimizedBounds(overlay_1, box_1);
346
378
  overlay_1.className = "dv-drop-target-anchor".concat(this.options.className ? " ".concat(this.options.className) : '');
347
379
  (0, dom_1.toggleClass)(overlay_1, 'dv-drop-target-left', isLeft);
348
380
  (0, dom_1.toggleClass)(overlay_1, 'dv-drop-target-right', isRight);
@@ -394,10 +426,7 @@ var Droptarget = /** @class */ (function (_super) {
394
426
  box.top = "".concat(100 * (1 - size), "%");
395
427
  box.height = "".concat(100 * size, "%");
396
428
  }
397
- this.overlayElement.style.top = box.top;
398
- this.overlayElement.style.left = box.left;
399
- this.overlayElement.style.width = box.width;
400
- this.overlayElement.style.height = box.height;
429
+ setGPUOptimizedBoundsFromStrings(this.overlayElement, box);
401
430
  (0, dom_1.toggleClass)(this.overlayElement, 'dv-drop-target-small-vertical', isSmallY);
402
431
  (0, dom_1.toggleClass)(this.overlayElement, 'dv-drop-target-small-horizontal', isSmallX);
403
432
  (0, dom_1.toggleClass)(this.overlayElement, 'dv-drop-target-left', isLeft);
@@ -219,6 +219,7 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
219
219
  private readonly _floatingGroups;
220
220
  private readonly _popoutGroups;
221
221
  private readonly _rootDropTarget;
222
+ private _popoutRestorationPromise;
222
223
  private readonly _onDidRemoveGroup;
223
224
  readonly onDidRemoveGroup: Event<DockviewGroupPanel>;
224
225
  protected readonly _onDidAddGroup: Emitter<DockviewGroupPanel>;
@@ -235,6 +236,11 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
235
236
  get renderer(): DockviewPanelRenderer;
236
237
  get api(): DockviewApi;
237
238
  get floatingGroups(): DockviewFloatingGroupPanel[];
239
+ /**
240
+ * Promise that resolves when all popout groups from the last fromJSON call are restored.
241
+ * Useful for tests that need to wait for delayed popout creation.
242
+ */
243
+ get popoutRestorationPromise(): Promise<void>;
238
244
  constructor(container: HTMLElement, options: DockviewComponentOptions);
239
245
  setVisible(panel: DockviewGroupPanel, visible: boolean): void;
240
246
  addPopoutGroup(itemToPopout: DockviewPanel | DockviewGroupPanel, options?: DockviewPopoutGroupOptions): Promise<boolean>;
@@ -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;
@@ -1775,8 +1794,7 @@ var DockviewComponent = /** @class */ (function (_super) {
1775
1794
  var to = options.to.group;
1776
1795
  var target = options.to.position;
1777
1796
  if (target === 'center') {
1778
- var activePanel = from.activePanel;
1779
- var targetActivePanel = to.activePanel;
1797
+ var activePanel_1 = from.activePanel;
1780
1798
  var panels_2 = this.movingLock(function () {
1781
1799
  return __spreadArray([], __read(from.panels), false).map(function (p) {
1782
1800
  return from.model.removePanel(p.id, {
@@ -1788,35 +1806,34 @@ var DockviewComponent = /** @class */ (function (_super) {
1788
1806
  this.doRemoveGroup(from, { skipActive: true });
1789
1807
  }
1790
1808
  this.movingLock(function () {
1791
- var e_17, _a;
1809
+ var e_16, _a;
1792
1810
  try {
1793
1811
  for (var panels_3 = __values(panels_2), panels_3_1 = panels_3.next(); !panels_3_1.done; panels_3_1 = panels_3.next()) {
1794
1812
  var panel = panels_3_1.value;
1795
1813
  to.model.openPanel(panel, {
1796
- skipSetActive: true, // Always skip setting panels active during move
1814
+ skipSetActive: panel !== activePanel_1,
1797
1815
  skipSetGroupActive: true,
1798
1816
  });
1799
1817
  }
1800
1818
  }
1801
- catch (e_17_1) { e_17 = { error: e_17_1 }; }
1819
+ catch (e_16_1) { e_16 = { error: e_16_1 }; }
1802
1820
  finally {
1803
1821
  try {
1804
1822
  if (panels_3_1 && !panels_3_1.done && (_a = panels_3.return)) _a.call(panels_3);
1805
1823
  }
1806
- finally { if (e_17) throw e_17.error; }
1824
+ finally { if (e_16) throw e_16.error; }
1807
1825
  }
1808
1826
  });
1809
- if (!options.skipSetActive) {
1810
- // Make the moved panel (from the source group) active
1811
- if (activePanel) {
1812
- this.doSetGroupAndPanelActive(to);
1813
- }
1827
+ // Ensure group becomes active after move
1828
+ if (options.skipSetActive !== true) {
1829
+ // For center moves (merges), we need to ensure the target group is active
1830
+ // unless explicitly told not to (skipSetActive: true)
1831
+ this.doSetGroupAndPanelActive(to);
1814
1832
  }
1815
- else if (targetActivePanel) {
1816
- // Ensure the target group's original active panel remains active
1817
- to.model.openPanel(targetActivePanel, {
1818
- skipSetGroupActive: true
1819
- });
1833
+ else if (!this.activePanel) {
1834
+ // Even with skipSetActive: true, ensure there's an active panel if none exists
1835
+ // This maintains basic functionality while respecting skipSetActive
1836
+ this.doSetGroupAndPanelActive(to);
1820
1837
  }
1821
1838
  }
1822
1839
  else {
@@ -1846,20 +1863,26 @@ var DockviewComponent = /** @class */ (function (_super) {
1846
1863
  if (selectedPopoutGroup.referenceGroup) {
1847
1864
  var referenceGroup = this.getPanel(selectedPopoutGroup.referenceGroup);
1848
1865
  if (referenceGroup && !referenceGroup.api.isVisible) {
1849
- this.doRemoveGroup(referenceGroup, { skipActive: true });
1866
+ this.doRemoveGroup(referenceGroup, {
1867
+ skipActive: true,
1868
+ });
1850
1869
  }
1851
1870
  }
1852
1871
  // Manually dispose the window without triggering restoration
1853
1872
  selectedPopoutGroup.window.dispose();
1854
1873
  // Update group's location and containers for target
1855
1874
  if (to.api.location.type === 'grid') {
1856
- from.model.renderContainer = this.overlayRenderContainer;
1857
- from.model.dropTargetContainer = this.rootDropTargetContainer;
1875
+ from.model.renderContainer =
1876
+ this.overlayRenderContainer;
1877
+ from.model.dropTargetContainer =
1878
+ this.rootDropTargetContainer;
1858
1879
  from.model.location = { type: 'grid' };
1859
1880
  }
1860
1881
  else if (to.api.location.type === 'floating') {
1861
- from.model.renderContainer = this.overlayRenderContainer;
1862
- from.model.dropTargetContainer = this.rootDropTargetContainer;
1882
+ from.model.renderContainer =
1883
+ this.overlayRenderContainer;
1884
+ from.model.dropTargetContainer =
1885
+ this.rootDropTargetContainer;
1863
1886
  from.model.location = { type: 'floating' };
1864
1887
  }
1865
1888
  break;
@@ -1927,8 +1950,12 @@ var DockviewComponent = /** @class */ (function (_super) {
1927
1950
  from.panels.forEach(function (panel) {
1928
1951
  _this._onDidMovePanel.fire({ panel: panel, from: from });
1929
1952
  });
1930
- if (!options.skipSetActive) {
1931
- this.doSetGroupAndPanelActive(from);
1953
+ // Ensure group becomes active after move
1954
+ if (options.skipSetActive === false) {
1955
+ // Only activate when explicitly requested (skipSetActive: false)
1956
+ // Use 'to' group for non-center moves since 'from' may have been destroyed
1957
+ var targetGroup = to !== null && to !== void 0 ? to : from;
1958
+ this.doSetGroupAndPanelActive(targetGroup);
1932
1959
  }
1933
1960
  };
1934
1961
  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;