Replacing finalizers with destructors for gintro seems to work in principle, at least I got cairo_anim.nim running with a few hacks.
Problem is similar as with finalizers -- for callback vars owned by gtk we do not want a finalizer or destroy call, while for ordinary use we want the call. For finalizers I made the var global to prevent finalizer call. But for destroy global pragma makes no difference. What I have is basically type Context00* = object Context* = object of RootObj impl*: ptr Context00 proc `=destroy`*(s: var Context) = echo "=destroy called" if s.impl != nil: cairo_destroy(s.impl) s.impl = nil proc `=sink`*(s: var Context; x: Context) = echo "=sink called" if s.impl != nil and s.impl != x.impl: cairo_destroy(s.impl) s.impl = nil s.impl = x.impl Run and the macro generated callback proc proc connect_for_signal_cdecl_draw1(self: ptr Widget00; cr: ptr cairo.Context00; data: pointer): gboolean {.cdecl.} = let h: pointer = g_object_get_qdata(self, Quark) var cr1: cairo.Context cr1.impl = cr drawingAreaDrawCb(cast[DrawingArea](h), cr1).ord.gboolean Run (Here drawingAreaDrawCb() is the user provided high level callback proc.) Unfortunately at the end of connect proc =destroy is called for cr1, resulting in freeing cr which is owned by gtk. I tried sink and lent modifier for cr1, but that does not work, at least not in macro. So there remain two solutions: 1: cr1.impl = nil at end of connect proc, so destroy is called but does nothing. 2: Use ContextXX* = object of Context for type of cr1, that prevents call of =destroy currently, but I am not sure if that is guaranteed.