Skip to content
Merged
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
24 changes: 22 additions & 2 deletions src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1363,14 +1363,34 @@ private void UpdateInputMethod(IntPtr hkl)

Imm32InputMethod.Current.SetLanguageAndWindow(this, Hwnd, hkl);
}

// GetPointerDeviceRects is part of the WM_POINTER API (Windows 8+) but is not implemented
// by Wine/Proton. Probe once and fall back to the integer pixel location when missing,
// otherwise the P/Invoke throws EntryPointNotFoundException for every pointer message.
// See https://github.com/AvaloniaUI/Avalonia/issues/21081.
private static readonly bool s_isGetPointerDeviceRectsAvailable = ProbeGetPointerDeviceRects();

private static bool ProbeGetPointerDeviceRects()
{
var user32 = LoadLibrary("user32.dll");
return user32 != IntPtr.Zero
&& GetProcAddress(user32, nameof(GetPointerDeviceRects)) != IntPtr.Zero;
}

/// <summary>
/// Get the location of the pointer in himetric units.
/// Get the location of the pointer in screen coordinates with HIMETRIC sub-pixel precision
/// when supported, falling back to the integer pixel location on platforms that do not
/// implement <c>GetPointerDeviceRects</c> (e.g. Wine/Proton).
/// </summary>
/// <param name="info">The pointer info.</param>
/// <returns>The location of the pointer in himetric units.</returns>
/// <returns>The pointer location in screen pixels.</returns>
private Point GetHimetricLocation(POINTER_INFO info)
{
if (!s_isGetPointerDeviceRectsAvailable)
{
return new Point(info.ptPixelLocationX, info.ptPixelLocationY);
}

GetPointerDeviceRects(info.sourceDevice, out var pointerDeviceRect, out var displayRect);
var himetricLocation = new Point(
info.ptHimetricLocationRawX * displayRect.Width / (double)pointerDeviceRect.Width + displayRect.left,
Expand Down