diff options
| author | Marvin W <git@larma.de> | 2026-04-07 21:51:52 +0200 |
|---|---|---|
| committer | Marvin W <git@larma.de> | 2026-04-08 16:59:43 +0200 |
| commit | 55fe8df4842d683b3f7b446e1dbd091bd7a85a4d (patch) | |
| tree | e24fe3254d761f2cc02760b8d73e52f93941acb9 /main/src/ui/util/leak.vala | |
| parent | aeb8032753dd004db68a0ee144d4f51b4fe3aa0a (diff) | |
Add widget leak detection
Diffstat (limited to 'main/src/ui/util/leak.vala')
| -rw-r--r-- | main/src/ui/util/leak.vala | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/main/src/ui/util/leak.vala b/main/src/ui/util/leak.vala new file mode 100644 index 00000000..07eb1e46 --- /dev/null +++ b/main/src/ui/util/leak.vala @@ -0,0 +1,48 @@ +namespace Dino { + private const string CHECK_WIDGET_LEAK_ID = "dino_check_widget_leak_id"; + private const string CHECK_WIDGET_LEAK_NAME = "dino_check_widget_leak_name"; + private const string CHECK_WIDGET_LEAK_ACTIVE = "dino_check_widget_leak_active"; + private static void check_widget_leak_timeout_reached(Gtk.Widget widget) { + string name = widget.get_data(CHECK_WIDGET_LEAK_NAME) ?? widget.get_type().name(); + warning("%s likely leaked", name); + widget.set_data(CHECK_WIDGET_LEAK_ID, 0); + } + private static void check_widget_leak_disposed(Object widget) { + uint timeout_id = widget.get_data(CHECK_WIDGET_LEAK_ID); + if (timeout_id != 0) Source.remove(timeout_id); + widget.set_data(CHECK_WIDGET_LEAK_ID, 0); + } + private static void check_widget_leak_unrealized(Gtk.Widget widget) { + widget.set_data(CHECK_WIDGET_LEAK_ID, WeakTimeout.add_seconds_once(1, widget, check_widget_leak_timeout_reached)); + widget.weak_ref(check_widget_leak_disposed); + } + private static void check_widget_leak_realized(Gtk.Widget widget) { + uint timeout_id = widget.get_data(CHECK_WIDGET_LEAK_ID); + if (timeout_id != 0) Source.remove(timeout_id); + widget.set_data(CHECK_WIDGET_LEAK_ID, 0); + string name = widget.get_type().name(); + Gtk.Widget parent = widget.parent; + while (parent != null) { + name = parent.get_type().name() + " > " + name; + if (name.has_prefix("Dino")) break; + parent = parent.parent; + } + widget.set_data(CHECK_WIDGET_LEAK_NAME, name); + } + public static Gtk.Widget check_widget_leak(Gtk.Widget widget) { + if (is_leak_check_enabled() && !widget.get_data<bool>(CHECK_WIDGET_LEAK_ACTIVE)) { + widget.set_data(CHECK_WIDGET_LEAK_ACTIVE, true); + widget.set_data(CHECK_WIDGET_LEAK_ID, 0); + widget.realize.connect(check_widget_leak_realized); + widget.unrealize.connect(check_widget_leak_unrealized); + if (widget.get_realized()) { + check_widget_leak_realized(widget); + } + } + return widget; + } + + public static bool is_leak_check_enabled() { + return Environment.get_variable("DINO_CHECK_LEAK") == "1"; + } +}
\ No newline at end of file |
