|
|
|
@ -1363,14 +1363,34 @@ namespace Avalonia.Win32 |
|
|
|
|
|
|
|
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, |
|
|
|
|