Currently if destroy() is called while a subsurface is mapped a dangling
commit listener is left behind. This is obivously a problem, so check if
the subsurface is mapped in destroy() and remove the listener if needed.
When an xdg toplevel, layer surface, etc is destroyed, it is not
guaranteed that all the children in the surface tree have already been
destroyed. If there are still children around, destroying the root of
the tree would leave dangling pointers.
To fix this, destroy all children when destroying any node in the tree.