aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui/util
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/ui/util')
-rw-r--r--main/src/ui/util/leak.vala48
-rw-r--r--main/src/ui/util/size_request_box.vala5
-rw-r--r--main/src/ui/util/sizing_bin.vala4
3 files changed, 57 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
diff --git a/main/src/ui/util/size_request_box.vala b/main/src/ui/util/size_request_box.vala
index 98f1a20a..f479e14e 100644
--- a/main/src/ui/util/size_request_box.vala
+++ b/main/src/ui/util/size_request_box.vala
@@ -2,6 +2,10 @@ using Gtk;
namespace Dino.Ui {
public class SizeRequestBox : Box {
+ construct {
+ check_widget_leak(this);
+ }
+
public SizeRequestMode size_request_mode { get; set; default = SizeRequestMode.CONSTANT_SIZE; }
public override Gtk.SizeRequestMode get_request_mode() {
@@ -14,6 +18,7 @@ public class SizeRequestBin : Widget {
construct {
this.layout_manager = new BinLayout();
+ check_widget_leak(this);
}
public override void compute_expand_internal(out bool hexpand, out bool vexpand) {
diff --git a/main/src/ui/util/sizing_bin.vala b/main/src/ui/util/sizing_bin.vala
index 7401ddbf..0f5b9035 100644
--- a/main/src/ui/util/sizing_bin.vala
+++ b/main/src/ui/util/sizing_bin.vala
@@ -9,6 +9,10 @@ public class SizingBin : Widget {
public int target_height { get; set; default = -1; }
public int max_height { get; set; default = -1; }
+ construct {
+ check_widget_leak(this);
+ }
+
public override void compute_expand_internal(out bool hexpand, out bool vexpand) {
hexpand = false;
vexpand = false;