Browse Source

[GTK3] Unregister tick callback and properly close the window. Fixes #1424

pull/1426/head
Nikita Tsukanov 9 years ago
parent
commit
82acff0d57
  1. 10
      src/Gtk/Avalonia.Gtk3/Interop/Native.cs
  2. 22
      src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

10
src/Gtk/Avalonia.Gtk3/Interop/Native.cs

@ -219,7 +219,10 @@ namespace Avalonia.Gtk3.Interop
public delegate void gtk_widget_queue_draw_area(GtkWidget widget, int x, int y, int width, int height);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_widget_add_tick_callback(GtkWidget widget, TickCallback callback, IntPtr userData, IntPtr destroy);
public delegate uint gtk_widget_add_tick_callback(GtkWidget widget, TickCallback callback, IntPtr userData, IntPtr destroy);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate uint gtk_widget_remove_tick_callback(GtkWidget widget, uint id);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate GtkImContext gtk_im_multicontext_new();
@ -256,6 +259,9 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_unmaximize(GtkWindow window);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_close(GtkWindow window);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate void gtk_window_set_geometry_hints(GtkWindow window, IntPtr geometry_widget, ref GdkGeometry geometry, GdkWindowHints geom_mask);
@ -434,6 +440,7 @@ namespace Avalonia.Gtk3.Interop
public static D.gdk_window_invalidate_rect GdkWindowInvalidateRect;
public static D.gtk_widget_queue_draw_area GtkWidgetQueueDrawArea;
public static D.gtk_widget_add_tick_callback GtkWidgetAddTickCallback;
public static D.gtk_widget_remove_tick_callback GtkWidgetRemoveTickCallback;
public static D.gtk_widget_activate GtkWidgetActivate;
public static D.gtk_clipboard_get_for_display GtkClipboardGetForDisplay;
public static D.gtk_clipboard_request_text GtkClipboardRequestText;
@ -456,6 +463,7 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_window_deiconify GtkWindowDeiconify;
public static D.gtk_window_maximize GtkWindowMaximize;
public static D.gtk_window_unmaximize GtkWindowUnmaximize;
public static D.gtk_window_close GtkWindowClose;
public static D.gdk_window_begin_move_drag GdkWindowBeginMoveDrag;
public static D.gdk_window_begin_resize_drag GdkWindowBeginResizeDrag;
public static D.gdk_event_request_motions GdkEventRequestMotions;

22
src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

@ -33,11 +33,11 @@ namespace Avalonia.Gtk3
private readonly AutoResetEvent _canSetNextOperation = new AutoResetEvent(true);
internal IntPtr? GdkWindowHandle;
private bool _overrideRedirect;
private uint? _tickCallback;
public WindowBaseImpl(GtkWindow gtkWidget)
{
GtkWidget = gtkWidget;
Disposables.Add(gtkWidget);
_framebuffer = new FramebufferManager(this);
_imContext = Native.GtkImMulticontextNew();
Disposables.Add(_imContext);
@ -62,7 +62,7 @@ namespace Avalonia.Gtk3
{
Native.GtkWidgetSetDoubleBuffered(gtkWidget, false);
_gcHandle = GCHandle.Alloc(this);
Native.GtkWidgetAddTickCallback(GtkWidget, PinnedStaticCallback, GCHandle.ToIntPtr(_gcHandle), IntPtr.Zero);
_tickCallback = Native.GtkWidgetAddTickCallback(GtkWidget, PinnedStaticCallback, GCHandle.ToIntPtr(_gcHandle), IntPtr.Zero);
}
}
@ -103,7 +103,7 @@ namespace Avalonia.Gtk3
private bool OnDestroy(IntPtr gtkwidget, IntPtr userdata)
{
Dispose();
DoDispose(true);
return false;
}
@ -297,14 +297,28 @@ namespace Avalonia.Gtk3
}
public void Dispose()
public void Dispose() => DoDispose(false);
void DoDispose(bool fromDestroy)
{
if (_tickCallback.HasValue)
{
if (!GtkWidget.IsClosed)
Native.GtkWidgetRemoveTickCallback(GtkWidget, _tickCallback.Value);
_tickCallback = null;
}
//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();
if (!fromDestroy && !GtkWidget.IsClosed)
Native.GtkWindowClose(GtkWidget);
GtkWidget.Dispose();
if (_gcHandle.IsAllocated)
{
_gcHandle.Free();

Loading…
Cancel
Save