using XFESystem.Core; using XFESystem.Desktop; using Xunit; namespace XFESystem.Desktop.Tests; public sealed class PointerReleaseTests { [Theory] [InlineData(false)] [InlineData(true)] public void TitleDragAppliesTheReleasePositionAndThenRetiresCapture(bool intermediateMotion) { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace(seed: false)); var window = desktop.Open(DesktopApplication.Files); var original = window.Bounds; int x = original.X + 110, y = original.Y + 16; desktop.Pointer(x, y, true, timestampMs: 1000); if (intermediateMotion) desktop.Pointer(x + 17, y + 9, true, timestampMs: 1020); // A device can report the final motion and button break in one packet. desktop.Pointer(x + 40, y + 30, false, timestampMs: 1040); var expected = original with { X = original.X + 40, Y = original.Y + 30 }; Assert.Equal(expected, window.Bounds); Assert.Equal(expected, window.RestoreBounds); Assert.True(desktop.NeedsRender); desktop.Pointer(x + 90, y + 80, false, timestampMs: 1060); Assert.Equal(expected, window.Bounds); } [Theory] [InlineData(false)] [InlineData(true)] public void CornerResizeAppliesTheReleasePositionAndThenRetiresCapture(bool intermediateMotion) { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace(seed: false)); var window = desktop.Open(DesktopApplication.Files); var original = window.Bounds; int x = original.X + original.Width - 5, y = original.Y + original.Height - 5; desktop.Pointer(x, y, true, timestampMs: 1000); if (intermediateMotion) desktop.Pointer(x + 17, y + 9, true, timestampMs: 1020); desktop.Pointer(x + 48, y + 25, false, timestampMs: 1040); var expected = original with { Width = original.Width + 48, Height = original.Height + 25 }; Assert.Equal(expected, window.Bounds); Assert.Equal(expected, window.RestoreBounds); Assert.True(desktop.NeedsRender); desktop.Pointer(x + 90, y + 80, false, timestampMs: 1060); Assert.Equal(expected, window.Bounds); } [Theory] [InlineData(false)] [InlineData(true)] public void LostReportsCancelCaptureBeforeAReleaseWithDifferentCoordinates(bool resize) { var desktop = new DesktopSession(new Canvas(), new MemoryWorkspace(seed: false)); var window = desktop.Open(DesktopApplication.Files); var original = window.Bounds; int x = resize ? original.X + original.Width - 5 : original.X + 110; int y = resize ? original.Y + original.Height - 5 : original.Y + 16; desktop.Pointer(x, y, true, timestampMs: 1000); // Report loss has no reliable displacement; it must cancel the old grab. desktop.PointerReportsLost(x + 30, y + 20, true, timestampMs: 1020); desktop.Pointer(x + 40, y + 30, false, timestampMs: 1040); Assert.Equal(original, window.Bounds); Assert.Equal(original, window.RestoreBounds); } private sealed class Canvas : IDesktopCanvas { public int Width => 1920; public int Height => 1080; public void Fill(uint rgb, int x, int y, int width, int height) { } public void Line(uint rgb, int x1, int y1, int x2, int y2) { } public void Text(string text, uint rgb, int x, int y) { } public void Present() { } } }