Browse Source

Update WindowImpl.AppWndProc.cs (#21337)

Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
pull/21371/head
Symbai 5 months ago
committed by GitHub
parent
commit
f47606ae9d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 24
      src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

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

@ -1363,14 +1363,34 @@ namespace Avalonia.Win32
Imm32InputMethod.Current.SetLanguageAndWindow(this, Hwnd, 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> /// <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> /// </summary>
/// <param name="info">The pointer info.</param> /// <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) 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); GetPointerDeviceRects(info.sourceDevice, out var pointerDeviceRect, out var displayRect);
var himetricLocation = new Point( var himetricLocation = new Point(
info.ptHimetricLocationRawX * displayRect.Width / (double)pointerDeviceRect.Width + displayRect.left, info.ptHimetricLocationRawX * displayRect.Width / (double)pointerDeviceRect.Width + displayRect.left,

Loading…
Cancel
Save