The p.inner_mut().delete_child_by_id(id) will be removing the entry from the parent’s sub_windows: Vec<WindowRef> field, which will cause the same kind of drop code to be executed another time (while the outer drop call is still holding onto the borrow_mut of the parent.
It seems generally questionable to implicitly “delete” the window’s entry with its parent any time any WindowRef gets dropped, I mean, dropping a Window would cause the window’s parent, and thus also its grandparents and siblings, and so on… to be “deleted”. Well… it might make sense actually, in case you ensure that only a single WindowRef (perhaps with a better type name) gets handed out to user code… in any case, using this same drop==delete-the-target kind of WindowRef type internally in the Window structure, too, is probably a mistake. If your goal here is to be able to - recursively - drop an entire window tree despite of the reference cycles, a different approach might be better… e.g. you could use some explicit loop or recursive function; or you could use Weak references for the back-pointer to the parent (which might, depending on the use-case, even allow to skip the Option and use the Weak pointers own Option-like properties).