summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-07-19 23:31:07 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2016-07-20 10:48:07 -0400
commit82d3afb85161e0746c2136251eced5d7046225ca (patch)
treec16fd2d3bfc24c8d4a06bb82ab6206a215a1c09b
parent541e6aaeb1a4f743ab43c7afdc99e1ebbd899ec5 (diff)
Gtkmm2ext::Pane: attempt to track child lifetime, since Gtkmm 2.4 doesn't do this correctly
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/pane.h6
-rw-r--r--libs/gtkmm2ext/pane.cc28
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<Child> 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<Child*> (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;