aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui/util/leak.vala
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/ui/util/leak.vala')
-rw-r--r--main/src/ui/util/leak.vala48
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