diff --git a/src/Avalonia.Input/MouseDevice.cs b/src/Avalonia.Input/MouseDevice.cs
index 4c4d679087..ee7d0c9501 100644
--- a/src/Avalonia.Input/MouseDevice.cs
+++ b/src/Avalonia.Input/MouseDevice.cs
@@ -20,8 +20,13 @@ namespace Avalonia.Input
private Rect _lastClickRect;
private ulong _lastClickTime;
- private readonly Pointer _pointer = new Pointer(Pointer.GetNextFreeId(), PointerType.Mouse, true);
+ private readonly Pointer _pointer;
+ public MouseDevice(Pointer pointer = null)
+ {
+ _pointer = pointer ?? new Pointer(Pointer.GetNextFreeId(), PointerType.Mouse, true);
+ }
+
///
/// Gets the control that is currently capturing by the mouse, if any.
///
@@ -51,7 +56,7 @@ namespace Avalonia.Input
/// within the control's bounds or not. The current mouse capture control is exposed
/// by the property.
///
- public virtual void Capture(IInputElement control)
+ public void Capture(IInputElement control)
{
_pointer.Capture(control);
}
diff --git a/src/Avalonia.Input/Pointer.cs b/src/Avalonia.Input/Pointer.cs
index 890ad57024..80d803abb1 100644
--- a/src/Avalonia.Input/Pointer.cs
+++ b/src/Avalonia.Input/Pointer.cs
@@ -27,6 +27,11 @@ namespace Avalonia.Input
var seen = new HashSet(control1.GetSelfAndVisualAncestors().OfType());
return control2.GetSelfAndVisualAncestors().OfType().FirstOrDefault(seen.Contains);
}
+
+ protected virtual void PlatformCapture(IInputElement element)
+ {
+
+ }
public void Capture(IInputElement control)
{
@@ -34,6 +39,7 @@ namespace Avalonia.Input
Captured.DetachedFromVisualTree -= OnCaptureDetached;
var oldCapture = control;
Captured = control;
+ PlatformCapture(control);
if (oldCapture != null)
{
var commonParent = FindCommonParent(control, oldCapture);
diff --git a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfMouseDevice.cs b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfMouseDevice.cs
index 0d93115714..ebfe8cde47 100644
--- a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfMouseDevice.cs
+++ b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfMouseDevice.cs
@@ -9,22 +9,32 @@ namespace Avalonia.Win32.Interop.Wpf
{
private readonly WpfTopLevelImpl _impl;
- public WpfMouseDevice(WpfTopLevelImpl impl)
+ public WpfMouseDevice(WpfTopLevelImpl impl) : base(new WpfMousePointer(impl))
{
_impl = impl;
}
- public override void Capture(IInputElement control)
+ class WpfMousePointer : Pointer
{
- if (control == null)
+ private readonly WpfTopLevelImpl _impl;
+
+ public WpfMousePointer(WpfTopLevelImpl impl) : base(Pointer.GetNextFreeId(), PointerType.Mouse, true)
+ {
+ _impl = impl;
+ }
+
+ protected override void PlatformCapture(IInputElement control)
{
- System.Windows.Input.Mouse.Capture(null);
+ if (control == null)
+ {
+ System.Windows.Input.Mouse.Capture(null);
+ }
+ else if ((control.GetVisualRoot() as EmbeddableControlRoot)?.PlatformImpl != _impl)
+ throw new ArgumentException("Visual belongs to unknown toplevel");
+ else
+ System.Windows.Input.Mouse.Capture(_impl);
}
- else if ((control.GetVisualRoot() as EmbeddableControlRoot)?.PlatformImpl != _impl)
- throw new ArgumentException("Visual belongs to unknown toplevel");
- else
- System.Windows.Input.Mouse.Capture(_impl);
- base.Capture(control);
}
+
}
}
diff --git a/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs b/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs
index 2b4105efee..e7c379ad89 100644
--- a/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs
+++ b/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs
@@ -1,7 +1,10 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
+using System;
+using Avalonia.Controls;
using Avalonia.Input;
+using Avalonia.VisualTree;
using Avalonia.Win32.Interop;
namespace Avalonia.Win32.Input
@@ -10,23 +13,32 @@ namespace Avalonia.Win32.Input
{
public static WindowsMouseDevice Instance { get; } = new WindowsMouseDevice();
+ public WindowsMouseDevice() : base(new WindowsMousePointer())
+ {
+
+ }
+
public WindowImpl CurrentWindow
{
get;
set;
}
- public override void Capture(IInputElement control)
+ class WindowsMousePointer : Pointer
{
- base.Capture(control);
-
- if (control != null)
+ public WindowsMousePointer() : base(Pointer.GetNextFreeId(),PointerType.Mouse, true)
{
- UnmanagedMethods.SetCapture(CurrentWindow.Handle.Handle);
}
- else
+
+ protected override void PlatformCapture(IInputElement element)
{
- UnmanagedMethods.ReleaseCapture();
+ var hwnd = ((element?.GetVisualRoot() as TopLevel)?.PlatformImpl as WindowImpl)
+ ?.Handle.Handle;
+
+ if (hwnd.HasValue && hwnd != IntPtr.Zero)
+ UnmanagedMethods.SetCapture(hwnd.Value);
+ else
+ UnmanagedMethods.ReleaseCapture();
}
}
}
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs
index 9e8b2d58a6..5cc148fa0d 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.cs
@@ -336,6 +336,7 @@ namespace Avalonia.Win32
public void BeginMoveDrag()
{
+ WindowsMouseDevice.Instance.Capture(null);
UnmanagedMethods.DefWindowProc(_hwnd, (int)UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN,
new IntPtr((int)UnmanagedMethods.HitTestValues.HTCAPTION), IntPtr.Zero);
}
@@ -357,6 +358,7 @@ namespace Avalonia.Win32
#if USE_MANAGED_DRAG
_managedDrag.BeginResizeDrag(edge, ScreenToClient(MouseDevice.Position));
#else
+ WindowsMouseDevice.Instance.Capture(null);
UnmanagedMethods.DefWindowProc(_hwnd, (int)UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN,
new IntPtr((int)EdgeDic[edge]), IntPtr.Zero);
#endif