From 82d3afb85161e0746c2136251eced5d7046225ca Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 19 Jul 2016 23:31:07 -0400 Subject: [PATCH] Gtkmm2ext::Pane: attempt to track child lifetime, since Gtkmm 2.4 doesn't do this correctly --- libs/gtkmm2ext/gtkmm2ext/pane.h | 6 +++++- libs/gtkmm2ext/pane.cc | 28 +++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/libs/gtkmm2ext/gtkmm2ext/pane.h b/libs/gtkmm2ext/gtkmm2ext/pane.h index dfe2ef7ffe..9612da08d2 100644 --- a/libs/gtkmm2ext/gtkmm2ext/pane.h +++ b/libs/gtkmm2ext/gtkmm2ext/pane.h @@ -46,10 +46,11 @@ class LIBGTKMM2EXT_API Pane : public Gtk::Container public: struct Child { + Pane* pane; Gtk::Widget* w; int32_t minsize; - Child (Gtk::Widget* widget, uint32_t ms) : w (widget), minsize (ms) {} + Child (Pane* p, Gtk::Widget* widget, uint32_t ms) : pane (p), w (widget), minsize (ms) {} }; typedef std::list Children; @@ -108,6 +109,9 @@ class LIBGTKMM2EXT_API Pane : public Gtk::Container void add_divider (); void handle_child_visibility (); bool fract_is_ok (Dividers::size_type, float fract); + + static void* notify_child_destroyed (void*); + void* child_destroyed (Gtk::Widget*); }; class LIBGTKMM2EXT_API HPane : public Pane diff --git a/libs/gtkmm2ext/pane.cc b/libs/gtkmm2ext/pane.cc index 867912d540..3eda140c57 100644 --- a/libs/gtkmm2ext/pane.cc +++ b/libs/gtkmm2ext/pane.cc @@ -48,6 +48,7 @@ Pane::Pane (bool h) Pane::~Pane () { for (Children::iterator c = children.begin(); c != children.end(); ++c) { + c->w->remove_destroy_notify_callback (&(*c)); c->w->unparent (); } } @@ -140,9 +141,14 @@ Pane::handle_child_visibility () void Pane::on_add (Widget* w) { - children.push_back (Child (w, 0)); + children.push_back (Child (this, w, 0)); w->set_parent (*this); + /* Gtkmm 2.4 does not correctly arrange for ::on_remove() to be called + for custom containers that derive from Gtk::Container. So ... we need + to ensure that we hear about child destruction ourselves. + */ + w->add_destroy_notify_callback (&children.back(), &Pane::notify_child_destroyed); w->signal_show().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility)); w->signal_hide().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility)); @@ -152,11 +158,31 @@ Pane::on_add (Widget* w) } } +void* +Pane::notify_child_destroyed (void* data) +{ + Child* child = reinterpret_cast (data); + return child->pane->child_destroyed (child->w); +} + +void* +Pane::child_destroyed (Gtk::Widget* w) +{ + for (Children::iterator c = children.begin(); c != children.end(); ++c) { + if (c->w == w) { + children.erase (c); + break; + } + } + return 0; +} + void Pane::on_remove (Widget* w) { for (Children::iterator c = children.begin(); c != children.end(); ++c) { if (c->w == w) { + w->remove_destroy_notify_callback (&(*c)); w->unparent (); children.erase (c); break; -- 2.30.2