Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion src/Dock.Avalonia/Controls/DelayedUniformTabPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ protected override Size MeasureOverride(Size availableSize)
? tabWidth
: (IsFinite(targetTabWidth) ? targetTabWidth : tabWidth);
var desiredWidth = (extentTabWidth * visibleCount) + (spacing * Math.Max(0, visibleCount - 1));
desiredWidth = RoundToDevicePixels(desiredWidth);
return new Size(desiredWidth, maxHeight);
}

Expand All @@ -205,7 +206,11 @@ protected override Size ArrangeOverride(Size finalSize)
: ResolveTabWidth(visibleCount, finalSize);
_resolvedInMeasurePass = false;
var spacing = Math.Max(0d, ItemSpacing);
var arrangedExtentWidth = Math.Min(
finalSize.Width,
RoundToDevicePixels((tabWidth * visibleCount) + (spacing * Math.Max(0, visibleCount - 1))));
var x = 0d;
var arrangedIndex = 0;

foreach (var child in Children)
{
Expand All @@ -215,8 +220,15 @@ protected override Size ArrangeOverride(Size finalSize)
continue;
}

child.Arrange(new Rect(x, 0d, tabWidth, finalSize.Height));
var startX = RoundToDevicePixels(x);
var endX = arrangedIndex == visibleCount - 1
? arrangedExtentWidth
: RoundToDevicePixels(x + tabWidth);
Comment on lines +224 to +226
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid stretching the last tab to panel width

When tabWidth is capped (for example, wide viewport with a few tabs), this branch makes the final visible tab end at finalSize.Width, so it absorbs all trailing space instead of keeping the uniform width computed by ResolveTabWidth. In a 1000px layout with 3 tabs and MaxTabWidth=220, the last tab becomes ~552px wide while earlier tabs stay 220px, which breaks the panel’s uniform-tab contract and contradicts the existing headless expectation that all tabs remain equal width (tests/Dock.Avalonia.HeadlessTests/DelayedUniformTabPanelTests.cs, UsesUniformMaxWidthWhenSpaceIsAvailable).

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 6666527

var arrangedWidth = Math.Max(0d, endX - startX);

child.Arrange(new Rect(startX, 0d, arrangedWidth, finalSize.Height));
x += tabWidth + spacing;
arrangedIndex++;
}

return finalSize;
Expand Down Expand Up @@ -273,6 +285,19 @@ private static bool NearlyEqual(double left, double right)
return Math.Abs(left - right) <= WidthEpsilon;
}

private double RoundToDevicePixels(double value)
{
if (!IsFinite(value))
{
return value;
}

var scaling = (this.GetVisualRoot() as TopLevel)?.RenderScaling ?? 1d;
return scaling <= 0d
? value
: Math.Round(value * scaling) / scaling;
}

private double ResolveTabWidth(int visibleCount, Size referenceSize)
{
var targetWidth = ComputeTargetTabWidth(visibleCount, referenceSize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ private static void AssertTabWidth(DelayedUniformTabPanel panel, double expected
{
foreach (var child in panel.Children)
{
Assert.InRange(child.Bounds.Width, expectedWidth - 0.1, expectedWidth + 0.1);
Assert.InRange(child.Bounds.Width, expectedWidth - 0.1, expectedWidth + 1.1);
}
}
}
Loading