Browse Source

Fixed intermediate points order for windows (#20075)

* Fixed points order for windows

* Added static comparer

* Fixed points order for windows

* Added static comparer

* optimization
pull/20170/head
Krzysztof Krysiński 2 months ago
committed by GitHub
parent
commit
bc407c27b5
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 54
      src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
  2. 7
      src/Windows/Avalonia.Win32/WindowImpl.cs

54
src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices;
using Avalonia.Automation.Peers;
using Avalonia.Controls;
@ -983,7 +984,8 @@ namespace Avalonia.Win32
return null;
}
private unsafe IReadOnlyList<RawPointerPoint> CreateIntermediatePoints(MOUSEMOVEPOINT movePoint, MOUSEMOVEPOINT prevMovePoint)
private unsafe IReadOnlyList<RawPointerPoint> CreateIntermediatePoints(MOUSEMOVEPOINT movePoint,
MOUSEMOVEPOINT prevMovePoint)
{
// To understand some of this code, please check MS docs:
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmousemovepointsex#remarks
@ -994,6 +996,7 @@ namespace Avalonia.Win32
{
var movePointCopy = movePoint;
movePointCopy.time = 0; // empty "time" as otherwise WinAPI will always fail
int pointsCount = GetMouseMovePointsEx(
(uint)(Marshal.SizeOf(movePointCopy)),
&movePointCopy, movePoints, s_mouseHistoryInfos.Length,
@ -1001,47 +1004,46 @@ namespace Avalonia.Win32
// GetMouseMovePointsEx can return -1 if point wasn't found or there is so beeg delay that original points were erased from the buffer.
if (pointsCount <= 1)
{
return Array.Empty<RawPointerPoint>();
}
s_intermediatePointsPooledList.Clear();
s_intermediatePointsPooledList.Capacity = pointsCount;
for (int i = pointsCount - 1; i >= 1; i--)
{
var historyInfo = s_mouseHistoryInfos[i];
// Skip points newer than current point.
if (historyInfo.time > movePoint.time ||
(historyInfo.time == movePoint.time &&
historyInfo.x == movePoint.x &&
historyInfo.y == movePoint.y))
s_sortedPoints.Clear();
s_sortedPoints.Capacity = pointsCount;
for (int i = 0; i < pointsCount; i++)
{
var mp = movePoints[i];
var x = mp.x > 32767 ? mp.x - 65536 : mp.x;
var y = mp.y > 32767 ? mp.y - 65536 : mp.y;
if(mp.time <= prevMovePoint.time || mp.time >= movePoint.time)
continue;
}
// Skip points older from previous WM_MOUSEMOVE point.
if (historyInfo.time < prevMovePoint.time ||
(historyInfo.time == prevMovePoint.time &&
historyInfo.x == prevMovePoint.x &&
historyInfo.y == prevMovePoint.y))
s_sortedPoints.Add(new InternalPoint
{
continue;
Time = mp.time,
Pt = new PixelPoint(x, y)
});
}
// To support multiple screens.
if (historyInfo.x > 32767)
historyInfo.x -= 65536;
// sorting is required to ensure points are in order from oldest to newest
s_sortedPoints.Sort(static (a, b) => a.Time.CompareTo(b.Time));
if (historyInfo.y > 32767)
historyInfo.y -= 65536;
foreach (var p in s_sortedPoints)
{
var client = PointToClient(p.Pt);
var point = PointToClient(new PixelPoint(historyInfo.x, historyInfo.y));
s_intermediatePointsPooledList.Add(new RawPointerPoint
{
Position = point
Position = client
});
}
return s_intermediatePointsPooledList;
}
}
private RawPointerEventArgs CreatePointerArgs(IInputDevice device, ulong timestamp, RawPointerEventType eventType, RawPointerPoint point, RawInputModifiers modifiers, uint rawPointerId)

7
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -111,6 +111,7 @@ namespace Avalonia.Win32
private const int MaxPointerHistorySize = 512;
private static readonly PooledList<RawPointerPoint> s_intermediatePointsPooledList = new();
private static readonly List<InternalPoint> s_sortedPoints = new(64);
private static POINTER_TOUCH_INFO[]? s_historyTouchInfos;
private static POINTER_PEN_INFO[]? s_historyPenInfos;
private static POINTER_INFO[]? s_historyInfos;
@ -1741,5 +1742,11 @@ namespace Avalonia.Win32
public double Scaling => _owner.RenderScaling;
}
private struct InternalPoint
{
public int Time;
public PixelPoint Pt;
}
}
}

Loading…
Cancel
Save