From 4fdc81d9490078a10741cd45d5b3b9b4fd8eaa29 Mon Sep 17 00:00:00 2001 From: scorpion-26 Date: Fri, 15 Mar 2024 19:33:19 +0100 Subject: [PATCH] Destroy timeouts on Widget deletion. Timeouts would tick, even after the parent Widget is long gone causing use-after-free bugs. --- src/Widget.cpp | 10 ++++++++-- src/Widget.h | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Widget.cpp b/src/Widget.cpp index c1c7a10..e9fb7bb 100644 --- a/src/Widget.cpp +++ b/src/Widget.cpp @@ -49,7 +49,12 @@ Widget::~Widget() { if (m_Widget) { - LOG("Destroy widget and its children"); + // LOG("Destroy widget and its children"); + for (guint timeout : m_Timeouts) + { + g_source_remove(timeout); + } + m_Timeouts.clear(); m_Childs.clear(); gtk_widget_destroy(m_Widget); } @@ -178,7 +183,8 @@ void Widget::ApplyPropertiesToWidget() // Apply style auto style = gtk_widget_get_style_context(m_Widget); gtk_style_context_add_class(style, m_CssClass.c_str()); - for (auto& cssClass : m_AdditionalClasses) { + for (auto& cssClass : m_AdditionalClasses) + { gtk_style_context_add_class(style, cssClass.c_str()); } diff --git a/src/Widget.h b/src/Widget.h index e58c232..a3ee2af 100644 --- a/src/Widget.h +++ b/src/Widget.h @@ -135,6 +135,7 @@ public: { TimerCallback timeoutFn; Widget* thisWidget; + guint id; }; TimerPayload* payload = new TimerPayload(); payload->thisWidget = this; @@ -145,6 +146,7 @@ public: TimerResult result = payload->timeoutFn(*(TWidget*)payload->thisWidget); if (result == TimerResult::Delete) { + payload->thisWidget->m_Timeouts.erase(payload->id); delete payload; return false; } @@ -157,7 +159,8 @@ public: return; } } - g_timeout_add(timeoutMS, +fn, payload); + payload->id = g_timeout_add(timeoutMS, +fn, payload); + m_Timeouts.insert(payload->id); } GtkWidget* Get() { return m_Widget; }; @@ -182,6 +185,8 @@ protected: Transform m_VerticalTransform; // Y Callback m_OnCreate; + + std::unordered_set m_Timeouts; }; class Box : public Widget