From eec2ae04f391543eb4d0a4a41019a5a203396c14 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Fri, 18 Jul 2025 22:16:11 +0100 Subject: [PATCH] fix: constraints persistence and precedence issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves issue #869 where setConstraints calls would not persist after refresh and could not override addPanel constraints. Changes: - Fix critical bug in DockviewGroupPanel constructor (minimumWidth was using maximumHeight) - Restore setConstraints method to DockviewPanelApi by removing from Omit list - Implement explicit constraint tracking to allow group constraints to override panel constraints - Add constraint change listener to track when setConstraints is called explicitly - Update constraint getter precedence: explicit setConstraints > panel constraints > defaults - Update tests to reflect new behavior where group constraints can override panel constraints The new constraint hierarchy ensures that: 1. Explicit setConstraints calls take highest priority 2. Panel constraints from addPanel are used when no explicit group constraints exist 3. Group defaults are used as fallback 4. Constraints persist properly after page refresh 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../dockview/dockviewGroupPanel.spec.ts | 20 +++---- .../dockview-core/src/api/dockviewPanelApi.ts | 2 +- .../src/dockview/dockviewGroupPanel.ts | 52 ++++++++++++++++++- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanel.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanel.spec.ts index 1a01b1d30..be5dfa665 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanel.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanel.spec.ts @@ -132,12 +132,12 @@ describe('dockviewGroupPanel', () => { cut.model.openPanel(panel); - // active panel constraints + // explicit group constraints now override panel constraints - expect(cut.minimumWidth).toBe(21); - expect(cut.minimumHeight).toBe(11); - expect(cut.maximumHeight).toBe(101); - expect(cut.maximumWidth).toBe(201); + expect(cut.minimumWidth).toBe(20); // group constraint overrides panel constraint + expect(cut.minimumHeight).toBe(10); // group constraint overrides panel constraint + expect(cut.maximumHeight).toBe(100); // group constraint overrides panel constraint + expect(cut.maximumWidth).toBe(200); // group constraint overrides panel constraint const panel2 = new DockviewPanel( 'panel_id', @@ -158,12 +158,12 @@ describe('dockviewGroupPanel', () => { cut.model.openPanel(panel2); - // active panel constraints + // explicit group constraints still override panel constraints - expect(cut.minimumWidth).toBe(22); - expect(cut.minimumHeight).toBe(12); - expect(cut.maximumHeight).toBe(102); - expect(cut.maximumWidth).toBe(202); + expect(cut.minimumWidth).toBe(20); // group constraint overrides panel constraint + expect(cut.minimumHeight).toBe(10); // group constraint overrides panel constraint + expect(cut.maximumHeight).toBe(100); // group constraint overrides panel constraint + expect(cut.maximumWidth).toBe(200); // group constraint overrides panel constraint const panel3 = new DockviewPanel( 'panel_id', diff --git a/packages/dockview-core/src/api/dockviewPanelApi.ts b/packages/dockview-core/src/api/dockviewPanelApi.ts index 4b33f5eae..876351a1a 100644 --- a/packages/dockview-core/src/api/dockviewPanelApi.ts +++ b/packages/dockview-core/src/api/dockviewPanelApi.ts @@ -33,7 +33,7 @@ export interface DockviewPanelApi extends Omit< GridviewPanelApi, // omit properties that do not make sense here - 'setVisible' | 'onDidConstraintsChange' | 'setConstraints' + 'setVisible' | 'onDidConstraintsChange' > { /** * The id of the tab component renderer diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanel.ts index fd5e70fe3..4909914a0 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanel.ts @@ -7,12 +7,13 @@ import { IHeader, DockviewGroupPanelLocked, } from './dockviewGroupPanelModel'; -import { GridviewPanel, IGridviewPanel } from '../gridview/gridviewPanel'; +import { GridviewPanel, IGridviewPanel, Contraints } from '../gridview/gridviewPanel'; import { IDockviewPanel } from '../dockview/dockviewPanel'; import { DockviewGroupPanelApi, DockviewGroupPanelApiImpl, } from '../api/dockviewGroupPanelApi'; +// GridConstraintChangeEvent2 is not exported, so we'll type it manually const MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH = 100; const MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT = 100; @@ -33,8 +34,16 @@ export class DockviewGroupPanel implements IDockviewGroupPanel { private readonly _model: DockviewGroupPanelModel; + + // Track explicitly set constraints to override panel constraints + private _explicitConstraints: Partial = {}; override get minimumWidth(): number { + // Check for explicitly set group constraint first + if (typeof this._explicitConstraints.minimumWidth === 'number') { + return this._explicitConstraints.minimumWidth; + } + const activePanelMinimumWidth = this.activePanel?.minimumWidth; if (typeof activePanelMinimumWidth === 'number') { return activePanelMinimumWidth; @@ -43,6 +52,11 @@ export class DockviewGroupPanel } override get minimumHeight(): number { + // Check for explicitly set group constraint first + if (typeof this._explicitConstraints.minimumHeight === 'number') { + return this._explicitConstraints.minimumHeight; + } + const activePanelMinimumHeight = this.activePanel?.minimumHeight; if (typeof activePanelMinimumHeight === 'number') { return activePanelMinimumHeight; @@ -51,6 +65,11 @@ export class DockviewGroupPanel } override get maximumWidth(): number { + // Check for explicitly set group constraint first + if (typeof this._explicitConstraints.maximumWidth === 'number') { + return this._explicitConstraints.maximumWidth; + } + const activePanelMaximumWidth = this.activePanel?.maximumWidth; if (typeof activePanelMaximumWidth === 'number') { return activePanelMaximumWidth; @@ -59,6 +78,11 @@ export class DockviewGroupPanel } override get maximumHeight(): number { + // Check for explicitly set group constraint first + if (typeof this._explicitConstraints.maximumHeight === 'number') { + return this._explicitConstraints.maximumHeight; + } + const activePanelMaximumHeight = this.activePanel?.maximumHeight; if (typeof activePanelMaximumHeight === 'number') { return activePanelMaximumHeight; @@ -107,7 +131,7 @@ export class DockviewGroupPanel options.constraints?.minimumHeight ?? MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT, minimumWidth: - options.constraints?.maximumHeight ?? + options.constraints?.minimumWidth ?? MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH, maximumHeight: options.constraints?.maximumHeight, maximumWidth: options.constraints?.maximumWidth, @@ -128,6 +152,30 @@ export class DockviewGroupPanel this.addDisposables( this.model.onDidActivePanelChange((event) => { this.api._onDidActivePanelChange.fire(event); + }), + this.api.onDidConstraintsChangeInternal((event: any) => { + // Track explicitly set constraints to override panel constraints + // Extract numeric values from functions or values + if (event.minimumWidth !== undefined) { + this._explicitConstraints.minimumWidth = typeof event.minimumWidth === 'function' + ? event.minimumWidth() + : event.minimumWidth; + } + if (event.minimumHeight !== undefined) { + this._explicitConstraints.minimumHeight = typeof event.minimumHeight === 'function' + ? event.minimumHeight() + : event.minimumHeight; + } + if (event.maximumWidth !== undefined) { + this._explicitConstraints.maximumWidth = typeof event.maximumWidth === 'function' + ? event.maximumWidth() + : event.maximumWidth; + } + if (event.maximumHeight !== undefined) { + this._explicitConstraints.maximumHeight = typeof event.maximumHeight === 'function' + ? event.maximumHeight() + : event.maximumHeight; + } }) ); }