fix: constraints persistence and precedence issues

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 <noreply@anthropic.com>
This commit is contained in:
mathuo 2025-07-18 22:16:11 +01:00
parent 23a5d84020
commit eec2ae04f3
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
3 changed files with 61 additions and 13 deletions

View File

@ -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',

View File

@ -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

View File

@ -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<Contraints> = {};
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;
}
})
);
}