Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -5104,6 +5104,36 @@
}
#endif

[TestMethod]
public async Task When_Selection_Background_Has_No_Gaps_Between_Characters()
{
Comment on lines +5107 to +5109
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The PR description currently includes closes # without an issue number/link. Please update it to use a fully-qualified issue URL (e.g., Closes https://github.com/unoplatform/uno/issues/<id>) or note explicitly that there is no related issue and who approved it, per the repo PR requirements.

Copilot uses AI. Check for mistakes.
using var _ = new TextBoxFeatureConfigDisposable();

// Text with spaces that can produce cluster boundaries at exact
// integer coordinates, which previously caused 1-pixel gaps in
// the selection background due to rounding/antialiasing issues.
var SUT = new TextBox
{
Text = "____",
FontSize = 14,
Comment on lines +5112 to +5118
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The comment above this test says it relies on β€œText with spaces”, but the actual test text is "____" (underscores). Please either update the text to match the intended reproduction case, or adjust the comment to reflect why underscores are the right input for triggering cluster-boundary rounding issues.

Copilot uses AI. Check for mistakes.
Width = 300,
SelectionHighlightColor = new SolidColorBrush(Colors.Red),
};

await UITestHelper.Load(SUT);

SUT.Focus(FocusState.Programmatic);
SUT.SelectAll();
await UITestHelper.WaitForIdle();

var tb = SUT.FindVisualChildByType<TextBlock>();
var screenshot = await UITestHelper.ScreenShot(tb);
for (int i = 0; i < 20; i++)
{
screenshot.GetPixel(i, screenshot.Height / 2).Should().Be(Colors.Red, $"Selection background should have no gaps at x={i}");
Comment on lines +5131 to +5133
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The test compares pixel colors with exact equality (Should().Be(Colors.Red)), which is brittle with antialiasing and subpixel blending at highlight edges. To reduce flakiness, prefer an assertion that allows a small tolerance (or sample pixels away from edges / validate a rectangle region using ImageAssert’s tolerance helpers).

Suggested change
for (int i = 0; i < 20; i++)
{
screenshot.GetPixel(i, screenshot.Height / 2).Should().Be(Colors.Red, $"Selection background should have no gaps at x={i}");
const byte colorTolerance = 8;
for (int i = 0; i < 20; i++)
{
var pixel = screenshot.GetPixel(i, screenshot.Height / 2);
pixel.A.Should().BeInRange((byte)Math.Max(0, Colors.Red.A - colorTolerance), (byte)Math.Min(255, Colors.Red.A + colorTolerance), $"Selection background alpha should have no gaps at x={i}");
pixel.R.Should().BeInRange((byte)Math.Max(0, Colors.Red.R - colorTolerance), (byte)Math.Min(255, Colors.Red.R + colorTolerance), $"Selection background red channel should have no gaps at x={i}");
pixel.G.Should().BeInRange((byte)Math.Max(0, Colors.Red.G - colorTolerance), (byte)Math.Min(255, Colors.Red.G + colorTolerance), $"Selection background green channel should have no gaps at x={i}");
pixel.B.Should().BeInRange((byte)Math.Max(0, Colors.Red.B - colorTolerance), (byte)Math.Min(255, Colors.Red.B + colorTolerance), $"Selection background blue channel should have no gaps at x={i}");

Copilot uses AI. Check for mistakes.
}
}

Check failure on line 5135 in src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_TextBox.skia.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Fix formatting (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0055)

Check failure on line 5135 in src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_TextBox.skia.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Fix formatting (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0055)
Comment on lines +5131 to +5135
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

This assertion checks only the first 20 pixels of the screenshot, so it doesn’t actually validate β€œno gaps between characters” across the whole selected text (a gap could exist later and the test would still pass). It’s also sensitive to template padding/offsets because it assumes the selection background starts at x=0. Consider deriving the expected highlight span from the screenshot (e.g., find the highlight bounds first) and then asserting there are no non-highlight pixels within that span.

Suggested change
for (int i = 0; i < 20; i++)
{
screenshot.GetPixel(i, screenshot.Height / 2).Should().Be(Colors.Red, $"Selection background should have no gaps at x={i}");
}
}
var y = screenshot.Height / 2;
var startX = Enumerable.Range(0, screenshot.Width)
.FirstOrDefault(x => screenshot.GetPixel(x, y) == Colors.Red);
var endX = Enumerable.Range(0, screenshot.Width)
.LastOrDefault(x => screenshot.GetPixel(x, y) == Colors.Red);
(startX <= endX).Should().BeTrue("Selection background should be visible on the sampled scanline.");
for (int x = startX; x <= endX; x++)
{
screenshot.GetPixel(x, y).Should().Be(Colors.Red, $"Selection background should have no gaps between x={startX} and x={endX}; found a gap at x={x}");
}
}

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

Indentation for the closing brace is inconsistent here (spaces instead of the surrounding tabs). Please align it with the file’s existing indentation to avoid noisy diffs and keep formatting consistent.

Suggested change
}
}

Copilot uses AI. Check for mistakes.

[TestMethod]
public async Task When_OuterScrollViewer_BringIntoView_Scrolls_To_Caret()
{
Expand Down
11 changes: 6 additions & 5 deletions src/Uno.UI/UI/Xaml/Documents/UnicodeText.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -888,12 +888,13 @@ public void Draw(in Visual.PaintingSession session,
}
}

// The rounding is to avoid 1-pixel gaps between adjacent clusters that have a background, even with antialiasing.
// Floor every edge and +1 the trailing edges so adjacent background
// rects always overlap by 1 px, preventing antialiased-edge seams.
var backgroundRect = new SKRect(
MathF.Round(unalignedX + alignmentOffset, MidpointRounding.AwayFromZero),
y,
(float)Math.Round(unalignedX + alignmentOffset + cluster.Value.width),
y + line.lineHeight);
MathF.Floor(unalignedX + alignmentOffset),
MathF.Floor(y),
MathF.Floor(unalignedX + alignmentOffset + cluster.Value.width) + 1,
MathF.Floor(y + line.lineHeight) + 1);
highlighter.Value.background?.Paint(session.Canvas, session.Opacity, backgroundRect);

if (_corrections?[wordBoundariesIndex] is { } correction)
Expand Down
Loading