{"action":"created","issue":{"url":"https://api.github.com/repos/gtkd-developers/GtkD/issues/165","repository_url":"https://api.github.com/repos/gtkd-developers/GtkD","labels_url":"https://api.github.com/repos/gtkd-developers/GtkD/issues/165/labels{/name}","comments_url":"https://api.github.com/repos/gtkd-developers/GtkD/issues/165/comments","events_url":"https://api.github.com/repos/gtkd-developers/GtkD/issues/165/events","html_url":"https://github.com/gtkd-developers/GtkD/issues/165","id":192314592,"number":165,"title":"Memory leak when using events from subclass","user":{"login":"gnunn1","id":9358238,"avatar_url":"https://avatars.githubusercontent.com/u/9358238?v=3","gravatar_id":"","url":"https://api.github.com/users/gnunn1","html_url":"https://github.com/gnunn1","followers_url":"https://api.github.com/users/gnunn1/followers","following_url":"https://api.github.com/users/gnunn1/following{/other_user}","gists_url":"https://api.github.com/users/gnunn1/gists{/gist_id}","starred_url":"https://api.github.com/users/gnunn1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gnunn1/subscriptions","organizations_url":"https://api.github.com/users/gnunn1/orgs","repos_url":"https://api.github.com/users/gnunn1/repos","events_url":"https://api.github.com/users/gnunn1/events{/privacy}","received_events_url":"https://api.github.com/users/gnunn1/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":12,"created_at":"2016-11-29T15:35:33Z","updated_at":"2016-12-04T21:34:18Z","closed_at":null,"body":"Below is a simple reproducer for a problem I'm having in Terminix (https://github.com/gnunn1/terminix/issues/589) where objects don't seem to be released properly when using eventHandlers. I'm not sure if this is a GtkD problem, an issue with D's GC not handling chained dependencies or a coding practice I shouldn't be doing.\r\n\r\nWhen you run the reproducer, it has an Add and Delete button. Clicking the Add Button creates a new Box with an Entry, clicking the Delete button removes and calls the D GC to collect (just to force things for testing purposes). The CustomVox and CustomEntry which are created have destructors that simply write a line out to stdout.\r\n\r\nIf you run the code and press Add then Delete and repeat several times you will see that the destructors for CustomBox and CustomEntry are not being executed. However, if you comment out the line:\r\n\r\n```\r\nentry.addOnChanged(&onChanged);\r\n```\r\n\r\nand repeat the test you will see that the destructors are being called properly.\r\n\r\nMy expectation is that because the CustomBox is not being referenced in D anywhere that it should be GC'ed, however something with the event handler between the CustomBox and CustomEvent is stopping it from working. Is this incrementing the reference count and preventing the GC from removing the struct from root maybe? \r\n\r\n```\r\nimport std.stdio;\r\n\r\nimport gio.Application : GioApplication = Application;\r\nimport gtk.Application;\r\nimport gtk.ApplicationWindow;\r\nimport gtk.Box;\r\nimport gtk.Button;\r\nimport gtk.EditableIF;\r\nimport gtk.Entry;\r\nimport gtk.Label;\r\n\r\nclass HelloWorld : ApplicationWindow\r\n{\r\n\r\n\tBox bContent;\r\n\tCustomBox bEntry;\r\n\r\n\tthis(Application application)import std.stdio;\r\n\r\nimport gio.Application : GioApplication = Application;\r\nimport gtk.Application;\r\nimport gtk.ApplicationWindow;\r\nimport gtk.Box;\r\nimport gtk.Button;\r\nimport gtk.EditableIF;\r\nimport gtk.Entry;\r\nimport gtk.Label;\r\n\r\nclass HelloWorld : ApplicationWindow\r\n{\r\n\r\n\tBox bContent;\r\n\tCustomBox bEntry;\r\n\r\n\tthis(Application application)\r\n\t{\r\n\t\tsuper(application);\r\n\t\tsetTitle(\"GtkD\");\r\n\t\tsetBorderWidth(10);\r\n\r\n\t\tBox bButtons = new Box(Orientation.HORIZONTAL,6);\r\n\t\tButton btnAdd = new Button(\"Add\");\r\n\t\tbtnAdd.addOnClicked(delegate(Button b) {\r\n\t\t\tif (bEntry is null) {\r\n\t\t\t\tbEntry = new CustomBox();\r\n\t\t\t\tbEntry.showAll();\r\n\t\t\t\tbContent.add(bEntry);\r\n\t\t\t}\r\n\t\t});\r\n\t\tbButtons.add(btnAdd);\r\n\t\t\r\n\t\tButton btnDelete = new Button(\"Delete\");\r\n\t\tbtnDelete.addOnClicked(delegate(Button b) {\r\n\t\t\tif (bEntry !is null) {\r\n\t\t\t\tbContent.remove(bEntry);\r\n\t\t\t\tbEntry = null;\r\n\r\n\t\t\t\timport core.memory;\r\n\t\t\t\tGC.collect();\r\n\t\t\t}\r\n\t\t});\r\n\t\tbButtons.add(btnDelete);\r\n\r\n\t\tbContent = new Box(Orientation.VERTICAL, 6);\r\n\t\tbContent.add(bButtons);\r\n\r\n\t\tadd(bContent);\r\n\r\n\t\tshowAll();\r\n\t}\r\n}\r\n\r\nclass CustomBox: Box {\r\nprivate:\r\n\tCustomEntry entry;\r\n\r\n\tvoid onChanged(EditableIF editable) {\r\n\t\twriteln(\"Entry changed\");\r\n\t}\r\n\r\npublic:\r\n\tthis() {\r\n\t\tsuper(Orientation.HORIZONTAL,0);\r\n\t\tentry = new CustomEntry();\r\n\t\t// Comment out the addOnChanged and destructors start triggering properly\r\n\t\tentry.addOnChanged(&onChanged);\r\n\t\tadd(entry);\r\n\t}\r\n\r\n\t~this() {\r\n\t\twriteln(\"Box destructor destroyed\");\r\n\t}\r\n}\r\n\r\nclass CustomEntry: Entry {\r\n\r\n\t~this() {\r\n\t\twriteln(\"Entry destructor called\");\r\n\t}\r\n}\r\n\r\nint main(string[] args)\r\n{\r\n    auto application = new Application(\"org.gtkd.demo.helloworld\", GApplicationFlags.FLAGS_NONE);\r\n    application.addOnActivate(delegate void(GioApplication app) { new HelloWorld(application); });\r\n    return application.run(args);\r\n}\r\n```\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/gtkd-developers/GtkD/issues/comments/264733207","html_url":"https://github.com/gtkd-developers/GtkD/issues/165#issuecomment-264733207","issue_url":"https://api.github.com/repos/gtkd-developers/GtkD/issues/165","id":264733207,"user":{"login":"csoriano89","id":1755514,"avatar_url":"https://avatars.githubusercontent.com/u/1755514?v=3","gravatar_id":"","url":"https://api.github.com/users/csoriano89","html_url":"https://github.com/csoriano89","followers_url":"https://api.github.com/users/csoriano89/followers","following_url":"https://api.github.com/users/csoriano89/following{/other_user}","gists_url":"https://api.github.com/users/csoriano89/gists{/gist_id}","starred_url":"https://api.github.com/users/csoriano89/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/csoriano89/subscriptions","organizations_url":"https://api.github.com/users/csoriano89/orgs","repos_url":"https://api.github.com/users/csoriano89/repos","events_url":"https://api.github.com/users/csoriano89/events{/privacy}","received_events_url":"https://api.github.com/users/csoriano89/received_events","type":"User","site_admin":false},"created_at":"2016-12-04T21:34:18Z","updated_at":"2016-12-04T21:34:18Z","body":"Hey Gerald, if I understood correctly your question... gtk finalization is \"mandatory\", as any other GObject, so every gtk widget must free its resources in there."}}
{"actor":{"display_login":"csoriano89"}}