From 78257bb174a22a0f5eb838869d14f5276fa22bab Mon Sep 17 00:00:00 2001 From: Dan Walmsley <4672627+danwalmsley@users.noreply.github.com> Date: Tue, 10 Mar 2026 07:43:04 +0000 Subject: [PATCH 1/5] fix browser tab seperator rendering. --- .../Styles/BrowserTabTheme.axaml | 8 ++++---- .../Controls/DocumentTabStripItem.axaml | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Dock.Avalonia.Themes.Browser/Styles/BrowserTabTheme.axaml b/src/Dock.Avalonia.Themes.Browser/Styles/BrowserTabTheme.axaml index 44d6d9369..98f1a7709 100644 --- a/src/Dock.Avalonia.Themes.Browser/Styles/BrowserTabTheme.axaml +++ b/src/Dock.Avalonia.Themes.Browser/Styles/BrowserTabTheme.axaml @@ -18,9 +18,9 @@ - @@ -60,11 +60,11 @@ - - diff --git a/src/Dock.Avalonia.Themes.Fluent/Controls/DocumentTabStripItem.axaml b/src/Dock.Avalonia.Themes.Fluent/Controls/DocumentTabStripItem.axaml index a3106b93d..b49546a06 100644 --- a/src/Dock.Avalonia.Themes.Fluent/Controls/DocumentTabStripItem.axaml +++ b/src/Dock.Avalonia.Themes.Fluent/Controls/DocumentTabStripItem.axaml @@ -387,13 +387,13 @@ - + @@ -432,8 +432,8 @@ - From 6e5486265fe3770b2792151846b6540615c850d2 Mon Sep 17 00:00:00 2001 From: Dan Walmsley <4672627+danwalmsley@users.noreply.github.com> Date: Tue, 10 Mar 2026 07:59:02 +0000 Subject: [PATCH 2/5] delayeduniformtabpanel pixel rounding. --- .../Controls/DelayedUniformTabPanel.cs | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Dock.Avalonia/Controls/DelayedUniformTabPanel.cs b/src/Dock.Avalonia/Controls/DelayedUniformTabPanel.cs index fa463002a..78737fbed 100644 --- a/src/Dock.Avalonia/Controls/DelayedUniformTabPanel.cs +++ b/src/Dock.Avalonia/Controls/DelayedUniformTabPanel.cs @@ -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); } @@ -206,6 +207,7 @@ protected override Size ArrangeOverride(Size finalSize) _resolvedInMeasurePass = false; var spacing = Math.Max(0d, ItemSpacing); var x = 0d; + var arrangedIndex = 0; foreach (var child in Children) { @@ -215,8 +217,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 + ? finalSize.Width + : RoundToDevicePixels(x + tabWidth); + var arrangedWidth = Math.Max(0d, endX - startX); + + child.Arrange(new Rect(startX, 0d, arrangedWidth, finalSize.Height)); x += tabWidth + spacing; + arrangedIndex++; } return finalSize; @@ -273,6 +282,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); From c9ad9a0db475ab8302e7cfe7759bc5cc61d207aa Mon Sep 17 00:00:00 2001 From: Dan Walmsley <4672627+danwalmsley@users.noreply.github.com> Date: Tue, 10 Mar 2026 08:01:18 +0000 Subject: [PATCH 3/5] Revert "fix browser tab seperator rendering." This reverts commit 78257bb174a22a0f5eb838869d14f5276fa22bab. --- .../Styles/BrowserTabTheme.axaml | 8 ++++---- .../Controls/DocumentTabStripItem.axaml | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Dock.Avalonia.Themes.Browser/Styles/BrowserTabTheme.axaml b/src/Dock.Avalonia.Themes.Browser/Styles/BrowserTabTheme.axaml index 98f1a7709..44d6d9369 100644 --- a/src/Dock.Avalonia.Themes.Browser/Styles/BrowserTabTheme.axaml +++ b/src/Dock.Avalonia.Themes.Browser/Styles/BrowserTabTheme.axaml @@ -18,9 +18,9 @@ - @@ -60,11 +60,11 @@ - - diff --git a/src/Dock.Avalonia.Themes.Fluent/Controls/DocumentTabStripItem.axaml b/src/Dock.Avalonia.Themes.Fluent/Controls/DocumentTabStripItem.axaml index b49546a06..a3106b93d 100644 --- a/src/Dock.Avalonia.Themes.Fluent/Controls/DocumentTabStripItem.axaml +++ b/src/Dock.Avalonia.Themes.Fluent/Controls/DocumentTabStripItem.axaml @@ -387,13 +387,13 @@ - + @@ -432,8 +432,8 @@ - From feceb8a03d77986170a1c889d4c4689120ed325d Mon Sep 17 00:00:00 2001 From: Dan Walmsley <4672627+danwalmsley@users.noreply.github.com> Date: Tue, 10 Mar 2026 09:02:57 +0000 Subject: [PATCH 4/5] fix tests --- .../DelayedUniformTabPanelTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Dock.Avalonia.HeadlessTests/DelayedUniformTabPanelTests.cs b/tests/Dock.Avalonia.HeadlessTests/DelayedUniformTabPanelTests.cs index 7790ba894..19e1f783d 100644 --- a/tests/Dock.Avalonia.HeadlessTests/DelayedUniformTabPanelTests.cs +++ b/tests/Dock.Avalonia.HeadlessTests/DelayedUniformTabPanelTests.cs @@ -185,14 +185,14 @@ private static DelayedUniformTabPanel CreatePanel(int count = 3) private static void Layout(DelayedUniformTabPanel panel, double width, double height) { panel.Measure(new Size(width, height)); - panel.Arrange(new Rect(0, 0, width, height)); + panel.Arrange(new Rect(0, 0, panel.DesiredSize.Width, height)); } private static void AssertTabWidth(DelayedUniformTabPanel panel, double expectedWidth) { 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); } } } From 666652709ff3fd4df1b9e4b15440d55561eb09fe Mon Sep 17 00:00:00 2001 From: Dan Walmsley <4672627+danwalmsley@users.noreply.github.com> Date: Tue, 10 Mar 2026 09:08:58 +0000 Subject: [PATCH 5/5] Fix tab panel pixel snapping --- src/Dock.Avalonia/Controls/DelayedUniformTabPanel.cs | 5 ++++- .../DelayedUniformTabPanelTests.cs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Dock.Avalonia/Controls/DelayedUniformTabPanel.cs b/src/Dock.Avalonia/Controls/DelayedUniformTabPanel.cs index 78737fbed..ad5c08719 100644 --- a/src/Dock.Avalonia/Controls/DelayedUniformTabPanel.cs +++ b/src/Dock.Avalonia/Controls/DelayedUniformTabPanel.cs @@ -206,6 +206,9 @@ 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; @@ -219,7 +222,7 @@ protected override Size ArrangeOverride(Size finalSize) var startX = RoundToDevicePixels(x); var endX = arrangedIndex == visibleCount - 1 - ? finalSize.Width + ? arrangedExtentWidth : RoundToDevicePixels(x + tabWidth); var arrangedWidth = Math.Max(0d, endX - startX); diff --git a/tests/Dock.Avalonia.HeadlessTests/DelayedUniformTabPanelTests.cs b/tests/Dock.Avalonia.HeadlessTests/DelayedUniformTabPanelTests.cs index 19e1f783d..9e9955d90 100644 --- a/tests/Dock.Avalonia.HeadlessTests/DelayedUniformTabPanelTests.cs +++ b/tests/Dock.Avalonia.HeadlessTests/DelayedUniformTabPanelTests.cs @@ -185,7 +185,7 @@ private static DelayedUniformTabPanel CreatePanel(int count = 3) private static void Layout(DelayedUniformTabPanel panel, double width, double height) { panel.Measure(new Size(width, height)); - panel.Arrange(new Rect(0, 0, panel.DesiredSize.Width, height)); + panel.Arrange(new Rect(0, 0, width, height)); } private static void AssertTabWidth(DelayedUniformTabPanel panel, double expectedWidth)