diff --git a/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs b/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs index 10ff735476..aadbe16d1d 100644 --- a/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs @@ -75,7 +75,7 @@ namespace Avalonia.Gtk3 private bool OnDestroy(IntPtr gtkwidget, IntPtr userdata) { - Closed?.Invoke(); + Dispose(); return false; } @@ -210,7 +210,9 @@ namespace Avalonia.Gtk3 public void Dispose() { - Closed?.Invoke(); + //We are calling it here, since signal handler will be detached + if (!GtkWidget.IsClosed) + Closed?.Invoke(); foreach(var d in Disposables.AsEnumerable().Reverse()) d.Dispose(); Disposables.Clear(); diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 5f59413ba2..d9b200169f 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -182,9 +182,18 @@ namespace Avalonia.Win32 public void Dispose() { - s_instances.Remove(this); - _framebuffer.Dispose(); - UnmanagedMethods.DestroyWindow(_hwnd); + _framebuffer?.Dispose(); + _framebuffer = null; + if (_hwnd != IntPtr.Zero) + { + UnmanagedMethods.DestroyWindow(_hwnd); + _hwnd = IntPtr.Zero; + } + if (_className != null) + { + UnmanagedMethods.UnregisterClass(_className, UnmanagedMethods.GetModuleHandle(null)); + _className = null; + } } public void Hide() @@ -418,12 +427,13 @@ namespace Avalonia.Win32 return IntPtr.Zero; case UnmanagedMethods.WindowsMessage.WM_DESTROY: - if (Closed != null) - { - UnmanagedMethods.UnregisterClass(_className, UnmanagedMethods.GetModuleHandle(null)); - Closed(); - } - + //Window doesn't exist anymore + _hwnd = IntPtr.Zero; + //Remove root reference to this class, so unmanaged delegate can be collected + s_instances.Remove(this); + Closed?.Invoke(); + //Free other resources + Dispose(); return IntPtr.Zero; case UnmanagedMethods.WindowsMessage.WM_DPICHANGED: