diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs index 66f6aeb757..c5e3622404 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs @@ -87,6 +87,8 @@ namespace Avalonia.Android.Platform.SkiaPlatform public Action ScalingChanged { get; set; } + public Action PositionChanged { get; set; } + public View View => this; Action ITopLevelImpl.Activated { get; set; } diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj index d6e5926727..40ff32cccc 100644 --- a/src/Avalonia.Controls/Avalonia.Controls.csproj +++ b/src/Avalonia.Controls/Avalonia.Controls.csproj @@ -56,6 +56,7 @@ + diff --git a/src/Avalonia.Controls/Platform/ITopLevelImpl.cs b/src/Avalonia.Controls/Platform/ITopLevelImpl.cs index f5d8344bda..281851a512 100644 --- a/src/Avalonia.Controls/Platform/ITopLevelImpl.cs +++ b/src/Avalonia.Controls/Platform/ITopLevelImpl.cs @@ -67,6 +67,11 @@ namespace Avalonia.Platform /// Action ScalingChanged { get; set; } + /// + /// Gets or sets a method called when the window's position changes. + /// + Action PositionChanged { get; set; } + /// /// Activates the window. /// diff --git a/src/Avalonia.Controls/PositionChangedEventArgs.cs b/src/Avalonia.Controls/PositionChangedEventArgs.cs new file mode 100644 index 0000000000..74c6e9ede1 --- /dev/null +++ b/src/Avalonia.Controls/PositionChangedEventArgs.cs @@ -0,0 +1,27 @@ +// 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; + +namespace Avalonia.Controls +{ + /// + /// Provides data for the event. + /// + public class PositionChangedEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// The new window position. + public PositionChangedEventArgs(Point newPos) + { + NewPosition = newPos; + } + + /// + /// Gets the new window position. + /// + public Point NewPosition { get; } + } +} \ No newline at end of file diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index 59a3072c23..2ba359ce47 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/src/Avalonia.Controls/TopLevel.cs @@ -105,6 +105,7 @@ namespace Avalonia.Controls PlatformImpl.Input = HandleInput; PlatformImpl.Resized = HandleResized; PlatformImpl.ScalingChanged = HandleScalingChanged; + PlatformImpl.PositionChanged = HandlePositionChanged; _keyboardNavigationHandler?.SetOwner(this); _accessKeyHandler?.SetOwner(this); @@ -138,6 +139,11 @@ namespace Avalonia.Controls /// public event EventHandler Deactivated; + /// + /// Fired when the window position is changed. + /// + public event EventHandler PositionChanged; + /// /// Gets or sets the client size of the window. /// @@ -395,6 +401,16 @@ namespace Avalonia.Controls _inputManager.ProcessInput(e); } + /// + /// Handles a window position change notification from + /// . + /// + /// The window position. + private void HandlePositionChanged(Point pos) + { + PositionChanged?.Invoke(this, new PositionChangedEventArgs(pos)); + } + /// /// Starts moving a window with left button being held. Should be called from left mouse button press event handler /// diff --git a/src/Gtk/Avalonia.Gtk/WindowImpl.cs b/src/Gtk/Avalonia.Gtk/WindowImpl.cs index 26ad52135d..87f733b370 100644 --- a/src/Gtk/Avalonia.Gtk/WindowImpl.cs +++ b/src/Gtk/Avalonia.Gtk/WindowImpl.cs @@ -23,6 +23,8 @@ namespace Avalonia.Gtk private Size _lastClientSize; + private Point _lastPosition; + private Gtk.IMContext _imContext; private uint _lastKeyEventTimestamp; @@ -52,6 +54,7 @@ namespace Avalonia.Gtk DoubleBuffered = false; Realize(); _lastClientSize = ClientSize; + _lastPosition = Position; } protected override void OnRealized () @@ -175,6 +178,8 @@ namespace Avalonia.Gtk public Action ScalingChanged { get; set; } + public Action PositionChanged { get; set; } + public IPopupImpl CreatePopup() { return new PopupImpl(); @@ -338,6 +343,14 @@ namespace Avalonia.Gtk _lastClientSize = newSize; } + var newPosition = new Point(evnt.X, evnt.Y); + + if (newPosition != _lastPosition) + { + PositionChanged(newPosition); + _lastPosition = newPosition; + } + return true; } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 0b09d9ec91..721c834f14 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -55,6 +55,8 @@ namespace Avalonia.Win32 public Action ScalingChanged { get; set; } + public Action PositionChanged { get; set; } + public Thickness BorderThickness { get @@ -561,6 +563,10 @@ namespace Avalonia.Win32 } return IntPtr.Zero; + + case UnmanagedMethods.WindowsMessage.WM_MOVE: + PositionChanged?.Invoke(new Point(ToInt32(lParam) & 0xffff, ToInt32(lParam) >> 16)); + return IntPtr.Zero; } if (e != null && Input != null) diff --git a/src/iOS/Avalonia.iOS/AvaloniaView.cs b/src/iOS/Avalonia.iOS/AvaloniaView.cs index 505a88ecd5..8b14d09573 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaView.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaView.cs @@ -27,6 +27,7 @@ namespace Avalonia.iOS private readonly UIViewController _controller; private IInputRoot _inputRoot; private readonly KeyboardEventsHelper _keyboardHelper; + private Point _position; public AvaloniaView(UIWindow window, UIViewController controller) : base(onFrame => PlatformThreadingInterface.Instance.Render = onFrame) { @@ -72,6 +73,7 @@ namespace Avalonia.iOS public Action Paint { get; set; } public Action Resized { get; set; } public Action ScalingChanged { get; set; } + public Action PositionChanged { get; set; } public IPlatformHandle Handle => AvaloniaPlatformHandle; @@ -136,7 +138,15 @@ namespace Avalonia.iOS //Not supported } - public Point Position { get; set; } + public Point Position + { + get { return _position; } + set + { + _position = value; + PositionChanged?.Invoke(_position); + } + } public Size MaxClientSize => Bounds.Size.ToAvalonia(); public void SetTitle(string title)