diff --git a/src/Avalonia.Windowing/Bindings/EventNotifier.cs b/src/Avalonia.Windowing/Bindings/EventNotifier.cs index 5f38bfa707..a36beca8c6 100644 --- a/src/Avalonia.Windowing/Bindings/EventNotifier.cs +++ b/src/Avalonia.Windowing/Bindings/EventNotifier.cs @@ -10,6 +10,7 @@ namespace Avalonia.Windowing.Bindings public delegate void CharacterEventCallback(WindowId windowId, CharacterEvent characterEvent); public delegate void AwakenedEventCallback(); public delegate byte ShouldExitEventLoopCallback(WindowId windowId); + public delegate void CloseRequestedCallback(WindowId windowId); [StructLayout(LayoutKind.Sequential)] public struct EventNotifier @@ -20,5 +21,6 @@ namespace Avalonia.Windowing.Bindings public KeyboardEventCallback OnKeyboardEvent; public CharacterEventCallback OnCharacterEvent; public ShouldExitEventLoopCallback OnShouldExitEventLoop; + public CloseRequestedCallback OnCloseRequested; } } diff --git a/src/Avalonia.Windowing/Bindings/EventsLoop.cs b/src/Avalonia.Windowing/Bindings/EventsLoop.cs index b5f128cdf1..dcf1ed00c0 100644 --- a/src/Avalonia.Windowing/Bindings/EventsLoop.cs +++ b/src/Avalonia.Windowing/Bindings/EventsLoop.cs @@ -6,7 +6,10 @@ namespace Avalonia.Windowing.Bindings public class EventsLoop : IDisposable { [DllImport("winit_wrapper")] - private static extern IntPtr winit_events_loop_new(out IntPtr eventsLoopProxyHandle); + private static extern IntPtr winit_events_loop_new(); + + [DllImport("winit_wrapper")] + private static extern IntPtr winit_events_loop_proxy_new(IntPtr eventsLoopHandle); [DllImport("winit_wrapper")] private static extern void winit_events_loop_destroy(IntPtr handle); @@ -19,6 +22,7 @@ namespace Avalonia.Windowing.Bindings ); public IntPtr Handle { get; private set; } + private readonly EventsLoopProxy _eventsLoopProxy; private readonly EventNotifier _notifier; @@ -28,11 +32,12 @@ namespace Avalonia.Windowing.Bindings public event AwakenedEventCallback OnAwakened; public event ResizeEventCallback OnResized; public event ShouldExitEventLoopCallback OnShouldExitEventLoop; + public event CloseRequestedCallback OnCloseRequested; public EventsLoop() { - Handle = winit_events_loop_new(out var elpHandle); - _eventsLoopProxy = new EventsLoopProxy(elpHandle); + Handle = winit_events_loop_new(); + _eventsLoopProxy = new EventsLoopProxy(winit_events_loop_proxy_new(Handle)); _notifier = new EventNotifier() { OnMouseEvent = (windowId, mouseEvent) => OnMouseEvent?.Invoke(windowId, mouseEvent), @@ -40,7 +45,8 @@ namespace Avalonia.Windowing.Bindings OnCharacterEvent = (windowId, characterEvent) => OnCharacterEvent?.Invoke(windowId, characterEvent), OnResized = (windowId, resizeEvent) => OnResized?.Invoke(windowId, resizeEvent), OnAwakened = () => OnAwakened?.Invoke(), - OnShouldExitEventLoop = (windowId) => (byte)OnShouldExitEventLoop?.Invoke(windowId) + OnShouldExitEventLoop = (windowId) => (byte)OnShouldExitEventLoop?.Invoke(windowId), + OnCloseRequested = (windowId) => OnCloseRequested?.Invoke(windowId) }; } diff --git a/src/Avalonia.Windowing/WIndowingPlatform.cs b/src/Avalonia.Windowing/WIndowingPlatform.cs index c5f11c4de9..711c59b0fb 100644 --- a/src/Avalonia.Windowing/WIndowingPlatform.cs +++ b/src/Avalonia.Windowing/WIndowingPlatform.cs @@ -44,14 +44,29 @@ namespace Avalonia.Windowing _eventsLoop.OnAwakened += _eventsLoop_Awakened; _eventsLoop.OnResized += _eventsLoop_Resized; _eventsLoop.OnShouldExitEventLoop += _eventsLoop_OnShouldExitEventLoop; + _eventsLoop.OnCloseRequested += _eventsLoop_OnCloseRequested; + _windows = new Dictionary(); } + void _eventsLoop_OnCloseRequested(WindowId windowId) + { + if (_windows.ContainsKey(windowId)) + { + if (!_windows[windowId].OnCloseRequested()) + { + _windows[windowId].Dispose(); + } + } + } + byte _eventsLoop_OnShouldExitEventLoop(WindowId windowId) { if (_windows.ContainsKey(windowId)) + { + _windows[windowId].OnClosed(); _windows.Remove(windowId); - + } return _windows.Any() ? (byte)0 : (byte)1; } diff --git a/src/Avalonia.Windowing/WindowImpl.cs b/src/Avalonia.Windowing/WindowImpl.cs index d5734b16f6..e0e3173117 100644 --- a/src/Avalonia.Windowing/WindowImpl.cs +++ b/src/Avalonia.Windowing/WindowImpl.cs @@ -319,5 +319,15 @@ namespace Avalonia.Windowing gpuCtx.ResizeContext(ClientSize.Width, ClientSize.Height); } } + + public void OnClosed() + { + Closed?.Invoke(); + } + + public bool OnCloseRequested() + { + return (bool)Closing?.Invoke(); + } } } \ No newline at end of file