Move "Feedback" option to control-portocol settings
[ardour.git] / libs / gtkmm2ext / pane.cc
index 5926809a5518b7c7ac699650347c2bb4d7a5ab1e..60a6dc543c195831d6e085831e3d01b51bf8f95f 100644 (file)
@@ -48,6 +48,9 @@ Pane::Pane (bool h)
 Pane::~Pane ()
 {
        for (Children::iterator c = children.begin(); c != children.end(); ++c) {
+               c->show_con.disconnect ();
+               c->hide_con.disconnect ();
+               c->w->remove_destroy_notify_callback (&(*c));
                c->w->unparent ();
        }
 }
@@ -140,23 +143,53 @@ Pane::handle_child_visibility ()
 void
 Pane::on_add (Widget* w)
 {
-       children.push_back (Child (w, 0));
+       children.push_back (Child (this, w, 0));
+       Child& kid = children.back ();
 
        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));
+       kid.show_con = w->signal_show().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility));
+       kid.hide_con = w->signal_hide().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility));
 
        while (dividers.size() < (children.size() - 1)) {
                add_divider ();
        }
 }
 
+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) {
+                       c->show_con.disconnect ();
+                       c->hide_con.disconnect ();
+                       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) {
+                       c->show_con.disconnect ();
+                       c->hide_con.disconnect ();
+                       w->remove_destroy_notify_callback (&(*c));
                        w->unparent ();
                        children.erase (c);
                        break;
@@ -336,7 +369,7 @@ Pane::handle_release_event (GdkEventButton* ev, Divider* d)
 {
        d->dragging = false;
 
-       if (did_move) {
+       if (did_move && !children.empty()) {
                children.front().w->queue_resize ();
                did_move = false;
        }
@@ -357,6 +390,15 @@ Pane::fract_is_ok (Dividers::size_type div, float fract)
                return true;
        }
 
+
+       if (get_allocation().get_width() == 1 && get_allocation().get_height() == 1) {
+               /* space not * allocated - * divider being set from startup code. Let it pass,
+                  since our goal is mostly to catch drags to a position that will interfere with window
+                  resizing.
+               */
+               return true;
+       }
+
        /* On Quartz, if the pane handle (divider) gets to
           be adjacent to the window edge, you can no longer grab it:
           any attempt to do so is interpreted by the Quartz window