Skip to content

Commit 6668f68

Browse files
authored
[Backport to release/11.0-preview2]: Updating build agent image to use VS2026 (#14312)
Backport from #14299 * Updating build agent image to use VS2026 VS2022 images have been deprecated this week and we need to move to VS2026. This change will need to be backported to servicing branches also. * Using scout images * The Form_SnapsRightAsync(Maximized) test failed because the Win+Z snap layout panel interaction was broken. The test used Win+Z to open the snap layout panel, then navigated with arrow keys to select the right-half snap position. However, each SendAsync(Form, params object[]) call invoked SetForegroundWindow on the form, which dismissed the snap layout panel before the arrow keys could navigate it. For maximized windows, the window remained maximized and the snap never occurred. Root Cause 1. SetForegroundWindow in SendAsync(Form, params object[]) dismissed the Win+Z snap layout panel before arrow keys could navigate it. 2. Win+Z snap panel keyboard navigation is fragile and varies across Windows versions, making it unreliable for automated testing. Fix: Replaced Win+Z + keyboard navigation with Win+Left/Win+Right shortcuts in both Form_SnapsLeftAsync(FormWindowState) and Form_SnapsRightAsync(FormWindowState). These shortcuts directly snap windows without requiring interaction with the snap layout panel, making the tests more reliable across Windows versions. * Test fix: Layout display names may include OS-specific suffixes e.g. "French" became "French (Legacy, AZERTY)" in Windows 11.0. Due to this reason we are using StartsWith instead of equality check for layout name. * Test fix for GraphicsPath_AddRoundedRectangle_Integer and GraphicsPath_AddRoundedRectangle_Float failure on x86. Issue: Old and new GDI+ are producing different number of points: 19 and 25 respectively for rounded rectangles' arcs. Fix Updated both tests to validate shape correctness rather than exact point sequences: 1. Point count: Assert that the count is one of the two valid values (19 or 25) 2. Bounding box: Verify the path bounds match the expected (10, 10, 20, 20) rectangle 3. Key coordinates: Verify the first point (top-right corner start at ~27.5, 10) and last point (top-left corner end at ~12.5, 10) are correct This makes the tests robust across different GDI+ implementations while still validating that AddRoundedRectangle(Rectangle, Size) produces a geometrically correct rounded rectangle. * Test issue: The VisibleClipBound(), VisibleClipBound_BigClip(), and Rotate() tests were failing on x86 Windows due to floating-point precision differences after RotateTransform(90). There are tiny epsilon differences (e.g., 1.9E-06 instead of exactly 0). The tests used exact Assert.Equal(0, rotclip.X) for values computed through rotation matrix transforms, which broke on x86. The same issue already existed on ARM (covered by IsArmOrArm64Process skip guards). Fix For all three tests: 1. Replaced exact equality (Assert.Equal(0, value)) with tolerance-based equality (Assert.Equal(0.0, value, 4)) for values computed after RotateTransform() — specifically the .X properties that should be 0 but may have tiny epsilon drift. Note that similar change was already done for verifying other points/lengths. 2. Removed the ARM skip guards (IsArmOrArm64Process + Skip(uint)) since the tolerance-based assertions now handle precision differences on all architectures (ARM, x86, x64). * Due to GDI+ changes in Windows 11 on x86, floating point overflow causes the value to change to Infinity instead of float.MaxValue. * Trigger PR update * Fix for remaining matrix tests which are also failing on x86 due to similar issue as Translation Matrix test.
2 parents 6ac21ae + 3a79fd9 commit 6668f68

6 files changed

Lines changed: 86 additions & 109 deletions

File tree

eng/pipelines/build-PR.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ jobs:
1717
pool:
1818
${{ if eq(variables['System.TeamProject'], 'public') }}:
1919
name: $(DncEngPublicBuildPool)
20-
demands: ImageOverride -equals windows.vs2022preview.amd64.open
20+
demands: ImageOverride -equals windows.vs2026preview.scout.amd64.open
2121
${{ if ne(variables['System.TeamProject'], 'public') }}:
2222
name: $(DncEngInternalBuildPool)
23-
demands: ImageOverride -equals windows.vs2022preview.amd64
23+
demands: ImageOverride -equals windows.vs2026preview.scout.amd64
2424
strategy:
2525
matrix:
2626
Debug:

src/System.Drawing.Common/tests/System/Drawing/Drawing2D/GraphicsPathTests.cs

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,61 +2348,45 @@ public void GraphicsPath_AddRoundedRectangle_Integer()
23482348
{
23492349
using GraphicsPath path = new();
23502350
path.AddRoundedRectangle(new Rectangle(10, 10, 20, 20), new(5, 5));
2351-
path.PathPoints.Should().BeApproximatelyEquivalentTo(
2352-
new PointF[]
2353-
{
2354-
new(27.499994f, 10),
2355-
new(28.880707f, 9.999997f),
2356-
new(29.999996f, 11.119284f),
2357-
new(29.999998f, 12.499999f),
2358-
new(29.999998f, 12.499999f),
2359-
new(29.999998f, 12.5f),
2360-
new(29.999998f, 12.5f),
2361-
new(29.999998f, 27.499998f),
2362-
new(29.999998f, 28.88071f),
2363-
new(28.88071f, 29.999998f),
2364-
new(27.5f, 29.999998f),
2365-
new(12.500001f, 29.999998f),
2366-
new(11.119289f, 30),
2367-
new(10.000001f, 28.880713f),
2368-
new(10f, 27.5f),
2369-
new(9.999999f, 12.500001f),
2370-
new(9.999998f, 11.119289f),
2371-
new(11.119286f, 10.000001f),
2372-
new(12.499997f, 9.999999f),
2373-
},
2374-
0.000001f);
2351+
2352+
// The number of points (19 or 25) can vary by GDI+ implementation.
2353+
path.PointCount.Should().BeOneOf(19, 25);
2354+
path.GetBounds().Should().BeApproximately(new RectangleF(10f, 10f, 20f, 20f), 0.01f);
2355+
2356+
PointF[] points = path.PathPoints;
2357+
PointF first = points[0];
2358+
PointF last = points[^1];
2359+
2360+
// First point should be on the top edge near top-right corner.
2361+
first.X.Should().BeApproximately(27.5f, 0.001f);
2362+
first.Y.Should().BeApproximately(10f, 0.001f);
2363+
2364+
// Last point should be on the top edge near top-left corner.
2365+
last.X.Should().BeApproximately(12.5f, 0.001f);
2366+
last.Y.Should().BeApproximately(10f, 0.001f);
23752367
}
23762368

23772369
[Fact]
23782370
public void GraphicsPath_AddRoundedRectangle_Float()
23792371
{
23802372
using GraphicsPath path = new();
23812373
path.AddRoundedRectangle(new RectangleF(10, 10, 20, 20), new(5, 5));
2382-
path.PathPoints.Should().BeApproximatelyEquivalentTo(
2383-
new PointF[]
2384-
{
2385-
new(27.499994f, 10),
2386-
new(28.880707f, 9.999997f),
2387-
new(29.999996f, 11.119284f),
2388-
new(29.999998f, 12.499999f),
2389-
new(29.999998f, 12.499999f),
2390-
new(29.999998f, 12.5f),
2391-
new(29.999998f, 12.5f),
2392-
new(29.999998f, 27.499998f),
2393-
new(29.999998f, 28.88071f),
2394-
new(28.88071f, 29.999998f),
2395-
new(27.5f, 29.999998f),
2396-
new(12.500001f, 29.999998f),
2397-
new(11.119289f, 30),
2398-
new(10.000001f, 28.880713f),
2399-
new(10f, 27.5f),
2400-
new(9.999999f, 12.500001f),
2401-
new(9.999998f, 11.119289f),
2402-
new(11.119286f, 10.000001f),
2403-
new(12.499997f, 9.999999f),
2404-
},
2405-
0.000001f);
2374+
2375+
// The number of points can vary by GDI+ implementation (19 or 25).
2376+
path.PointCount.Should().BeOneOf(19, 25);
2377+
path.GetBounds().Should().BeApproximately(new RectangleF(10f, 10f, 20f, 20f), 0.01f);
2378+
2379+
PointF[] points = path.PathPoints;
2380+
PointF first = points[0];
2381+
PointF last = points[^1];
2382+
2383+
// First point should be on the top edge near top-right corner.
2384+
first.X.Should().BeApproximately(27.5f, 0.001f);
2385+
first.Y.Should().BeApproximately(10f, 0.001f);
2386+
2387+
// Last point should be on the top edge near top-left corner.
2388+
last.X.Should().BeApproximately(12.5f, 0.001f);
2389+
last.Y.Should().BeApproximately(10f, 0.001f);
24062390
}
24072391

24082392
#endif

src/System.Drawing.Common/tests/System/Drawing/Drawing2D/MatrixTests.cs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,14 @@ public static IEnumerable<object[]> Multiply_TestData()
308308
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity), MatrixOrder.Prepend, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity } };
309309
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity), MatrixOrder.Append, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity } };
310310

311-
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue), MatrixOrder.Prepend, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue } };
312-
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue), MatrixOrder.Append, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue } };
311+
// On x86, multiplying matrix coefficients (10-60) by MaxValue overflows float to infinity
312+
// due to x87 FPU 80-bit intermediate precision behavior.
313+
float expectedMaxMultiply = RuntimeInformation.ProcessArchitecture == Architecture.X86
314+
? float.PositiveInfinity
315+
: float.MaxValue;
316+
317+
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue), MatrixOrder.Prepend, new float[] { expectedMaxMultiply, expectedMaxMultiply, expectedMaxMultiply, expectedMaxMultiply, expectedMaxMultiply, expectedMaxMultiply } };
318+
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), new Matrix(float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue), MatrixOrder.Append, new float[] { expectedMaxMultiply, expectedMaxMultiply, expectedMaxMultiply, expectedMaxMultiply, expectedMaxMultiply, expectedMaxMultiply } };
313319
}
314320

315321
[Theory]
@@ -531,8 +537,14 @@ public static IEnumerable<object[]> Scale_TestData()
531537
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Prepend, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, 50, 60 } };
532538
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Append, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity } };
533539

534-
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Prepend, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, 50, 60 } };
535-
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Append, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue } };
540+
// On x86, scaling matrix coefficients (10-60) by MaxValue overflows float to infinity
541+
// due to x87 FPU 80-bit intermediate precision behavior.
542+
float expectedMaxScale = RuntimeInformation.ProcessArchitecture == Architecture.X86
543+
? float.PositiveInfinity
544+
: float.MaxValue;
545+
546+
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Prepend, new float[] { expectedMaxScale, expectedMaxScale, expectedMaxScale, expectedMaxScale, 50, 60 } };
547+
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Append, new float[] { expectedMaxScale, expectedMaxScale, expectedMaxScale, expectedMaxScale, expectedMaxScale, expectedMaxScale } };
536548
}
537549

538550
[Theory]
@@ -597,8 +609,14 @@ public static IEnumerable<object[]> Shear_TestData()
597609
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Prepend, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, 50, 60 } };
598610
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Append, new float[] { float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity } };
599611

600-
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Prepend, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, 50, 60 } };
601-
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Append, new float[] { float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue, float.MaxValue } };
612+
// On x86, shearing matrix coefficients (10-60) by MaxValue overflows float to infinity
613+
// due to x87 FPU 80-bit intermediate precision behavior.
614+
float expectedMaxShear = RuntimeInformation.ProcessArchitecture == Architecture.X86
615+
? float.PositiveInfinity
616+
: float.MaxValue;
617+
618+
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Prepend, new float[] { expectedMaxShear, expectedMaxShear, expectedMaxShear, expectedMaxShear, 50, 60 } };
619+
yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.MaxValue, float.MaxValue, MatrixOrder.Append, new float[] { expectedMaxShear, expectedMaxShear, expectedMaxShear, expectedMaxShear, expectedMaxShear, expectedMaxShear } };
602620
}
603621

604622
[Theory]
@@ -654,7 +672,12 @@ public static IEnumerable<object[]> Translate_TestData()
654672
yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Prepend, new float[] { 1, 2, 3, 4, float.NegativeInfinity, float.NegativeInfinity } };
655673
yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.NegativeInfinity, float.NegativeInfinity, MatrixOrder.Append, new float[] { 1, 2, 3, 4, float.NegativeInfinity, float.NegativeInfinity } };
656674

657-
yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.MaxValue, float.MaxValue, MatrixOrder.Prepend, new float[] { 1, 2, 3, 4, float.MaxValue, float.MaxValue } };
675+
// On x86, Prepend operation causes float overflow to infinity due to x87 FPU behavior.
676+
float expectedMaxTranslation = RuntimeInformation.ProcessArchitecture == Architecture.X86
677+
? float.PositiveInfinity
678+
: float.MaxValue;
679+
680+
yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.MaxValue, float.MaxValue, MatrixOrder.Prepend, new float[] { 1, 2, 3, 4, expectedMaxTranslation, expectedMaxTranslation } };
658681
yield return new object[] { new Matrix(1, 2, 3, 4, 5, 6), float.MaxValue, float.MaxValue, MatrixOrder.Append, new float[] { 1, 2, 3, 4, float.MaxValue, float.MaxValue } };
659682
}
660683

src/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,12 +2189,6 @@ public void TestReleaseHdcException2()
21892189
[Fact]
21902190
public void VisibleClipBound()
21912191
{
2192-
if (PlatformDetection.IsArmOrArm64Process)
2193-
{
2194-
// [ActiveIssue("https://github.com/dotnet/winforms/issues/8817")]
2195-
Assert.Skip("Precision on float numbers");
2196-
}
2197-
21982192
// see #78958
21992193
using Bitmap bmp = new(100, 100);
22002194
using Graphics g = Graphics.FromImage(bmp);
@@ -2214,7 +2208,7 @@ public void VisibleClipBound()
22142208

22152209
g.RotateTransform(90);
22162210
RectangleF rotclip = g.VisibleClipBounds;
2217-
Assert.Equal(0, rotclip.X);
2211+
Assert.Equal(0.0, rotclip.X, 4);
22182212
Assert.Equal(-32.0, rotclip.Y, 4);
22192213
Assert.Equal(32.0, rotclip.Width, 4);
22202214
Assert.Equal(32.0, rotclip.Height, 4);
@@ -2223,12 +2217,6 @@ public void VisibleClipBound()
22232217
[Fact]
22242218
public void VisibleClipBound_BigClip()
22252219
{
2226-
if (PlatformDetection.IsArmOrArm64Process)
2227-
{
2228-
// ActiveIssue: 35744
2229-
Assert.Skip("Precision on float numbers");
2230-
}
2231-
22322220
using Bitmap bmp = new(100, 100);
22332221
using Graphics g = Graphics.FromImage(bmp);
22342222
RectangleF noclip = g.VisibleClipBounds;
@@ -2253,13 +2241,13 @@ public void VisibleClipBound_BigClip()
22532241

22542242
g.RotateTransform(90);
22552243
RectangleF rotclipbound = g.ClipBounds;
2256-
Assert.Equal(0, rotclipbound.X);
2244+
Assert.Equal(0.0, rotclipbound.X, 4);
22572245
Assert.Equal(-200.0, rotclipbound.Y, 4);
22582246
Assert.Equal(200.0, rotclipbound.Width, 4);
22592247
Assert.Equal(200.0, rotclipbound.Height, 4);
22602248

22612249
RectangleF rotclip = g.VisibleClipBounds;
2262-
Assert.Equal(0, rotclip.X);
2250+
Assert.Equal(0.0, rotclip.X, 4);
22632251
Assert.Equal(-100.0, rotclip.Y, 4);
22642252
Assert.Equal(100.0, rotclip.Width, 4);
22652253
Assert.Equal(100.0, rotclip.Height, 4);
@@ -2268,12 +2256,6 @@ public void VisibleClipBound_BigClip()
22682256
[Fact]
22692257
public void Rotate()
22702258
{
2271-
if (PlatformDetection.IsArmOrArm64Process)
2272-
{
2273-
// ActiveIssue: 35744
2274-
Assert.Skip("Precision on float numbers");
2275-
}
2276-
22772259
using Bitmap bmp = new(100, 50);
22782260
using Graphics g = Graphics.FromImage(bmp);
22792261
RectangleF vcb = g.VisibleClipBounds;
@@ -2284,7 +2266,7 @@ public void Rotate()
22842266

22852267
g.RotateTransform(90);
22862268
RectangleF rvcb = g.VisibleClipBounds;
2287-
Assert.Equal(0, rvcb.X);
2269+
Assert.Equal(0.0, rvcb.X, 4);
22882270
Assert.Equal(-100.0, rvcb.Y, 4);
22892271
Assert.Equal(50.0, rvcb.Width, 4);
22902272
Assert.Equal(100.0, rvcb.Height, 4);

src/test/integration/UIIntegrationTests/FormTests.cs

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,18 @@ await RunEmptyFormTestAsync(async form =>
3535

3636
form.WindowState = windowState;
3737

38+
// Snap left using Win+Left shortcut. This directly snaps the window
39+
// to the left half of the screen without requiring snap layout panel navigation.
3840
await InputSimulator.SendAsync(
3941
form,
40-
inputSimulator => inputSimulator.Keyboard.ModifiedKeyStroke(VIRTUAL_KEY.VK_LWIN, VIRTUAL_KEY.VK_Z));
42+
inputSimulator => inputSimulator.Keyboard
43+
.ModifiedKeyStroke(VIRTUAL_KEY.VK_LWIN, VIRTUAL_KEY.VK_LEFT));
4144

42-
// inputSimulator.Sleep appears wildly inconsistent with snap panel timing. Task.Delay does not
4345
await Task.Delay(SnapLayoutDelayMS);
4446

45-
// Snap left
46-
await InputSimulator.SendAsync(
47-
form,
48-
inputSimulator => inputSimulator.Keyboard.KeyPress(VIRTUAL_KEY.VK_RIGHT)
49-
.KeyPress(VIRTUAL_KEY.VK_RETURN));
50-
51-
await Task.Delay(SnapLayoutDelayMS);
52-
53-
// At this point, Windows displays a panel containing all running applications so the
54-
// user can select one to dock next to our form. It also takes the keyboard focus away.
55-
// If left in this state, subsequently run tests will fail since keyboard focus is not
56-
// given to any newly launched window until this panel is dismissed.
47+
// After snapping left, Windows may display a panel containing all running
48+
// applications so the user can select one to dock next to our form. It also
49+
// takes the keyboard focus away. Dismiss it with Escape.
5750
await InputSimulator.SendAsync(
5851
form,
5952
inputSimulator => inputSimulator.Keyboard.KeyPress(VIRTUAL_KEY.VK_ESCAPE));
@@ -94,26 +87,18 @@ await RunEmptyFormTestAsync(async form =>
9487

9588
form.WindowState = windowState;
9689

90+
// Snap right using Win+Right shortcut. This directly snaps the window
91+
// to the right half of the screen without requiring snap layout panel navigation.
9792
await InputSimulator.SendAsync(
9893
form,
99-
inputSimulator => inputSimulator.Keyboard.ModifiedKeyStroke(VIRTUAL_KEY.VK_LWIN, VIRTUAL_KEY.VK_Z));
100-
101-
// inputSimulator.Sleep appears wildly inconsistent with snap panel timing. Task.Delay does not
102-
await Task.Delay(SnapLayoutDelayMS);
103-
104-
// Snap right
105-
await InputSimulator.SendAsync(
106-
form,
107-
inputSimulator => inputSimulator.Keyboard.KeyPress(VIRTUAL_KEY.VK_RIGHT)
108-
.KeyPress(VIRTUAL_KEY.VK_RIGHT)
109-
.KeyPress(VIRTUAL_KEY.VK_RETURN));
94+
inputSimulator => inputSimulator.Keyboard
95+
.ModifiedKeyStroke(VIRTUAL_KEY.VK_LWIN, VIRTUAL_KEY.VK_RIGHT));
11096

11197
await Task.Delay(SnapLayoutDelayMS);
11298

113-
// At this point, Windows displays a panel containing all running applications so the
114-
// user can select one to dock next to our form. It also takes the keyboard focus away.
115-
// If left in this state, subsequently run tests will fail since keyboard focus is not
116-
// given to any newly launched window until this panel is dismissed.
99+
// After snapping right, Windows may display a panel containing all running
100+
// applications so the user can select one to dock next to our form. It also
101+
// takes the keyboard focus away. Dismiss it with Escape.
117102
await InputSimulator.SendAsync(
118103
form,
119104
inputSimulator => inputSimulator.Keyboard.KeyPress(VIRTUAL_KEY.VK_ESCAPE));

src/test/unit/System.Windows.Forms/System/Windows/Forms/InputLanguageTests.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,10 @@ private static void VerifyInputLanguage(InputLanguage language, string languageT
190190

191191
if (CultureInfo.InstalledUICulture.Name.StartsWith("en-", StringComparison.OrdinalIgnoreCase))
192192
{
193-
language.LayoutName.Should().Be(layoutName);
193+
// Layout display names may include OS-specific suffixes e.g. "French" became
194+
// "French (Legacy, AZERTY)" in Windows 11.0. Due to this reason we are using StartsWith
195+
// instead of equality check for layout name.
196+
language.LayoutName.Should().StartWith(layoutName);
194197
}
195198
else
196199
{

0 commit comments

Comments
 (0)