Based on this question, I wrote the following mwe:
import tkinter as tk
class BaseFrame(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.parent = parent
      
        self.bmanage = tk.Button(self, text='undock', command = self.undock)
        self.bforget = tk.Button(self, text='dock', command = self.dock)
        self.bmanage.grid(row=0, column=0, padx=20, pady=20, sticky='nsew')
        self.bforget.grid(row=0, column=1, padx=20, pady=20, sticky='nsew')
        self.dockable_frame = tk.Frame(self, bg="red", height=100)
        self.dockable_frame.grid(row=1, column=0, padx=20, pady=20, columnspan=2, sticky='nsew')
        self.label = tk.Label(self.dockable_frame, text="hi")
        self.label.grid(row=0, column=0, padx=150, pady=20, sticky='nsew')
    def undock(self):
        self.parent.wm_manage(self.dockable_frame)
        self.dockable_frame.configure(bg='blue')
        print(type(self.dockable_frame))
    def dock(self):
        self.parent.wm_forget(self.dockable_frame)
        self.dockable_frame.grid()
if __name__ == "__main__":
    root = tk.Tk()
    base_frame = BaseFrame(root)
    base_frame.grid(row=0, column=0, padx=20, pady=20, sticky='nsew')
    
    root.mainloop() 
By clicking the undock button, the red frame is undocked and by clicking the dock button, the frame is docked again. I have two questions:
- Why is the type of self.dockable_frame a <class 'tkinter.Frame'> and not a TopLevel since the wm manage documentation says: The widget specified will become a stand alone top-level window?
- How can I handle the window close event since self.dockable_frame.protocol("WM_DELETE_WINDOW", insert_function_here) gives an error on my Windows pc?
The error is:
AttributeError: 'Frame' object has no attribute 'protocol'
I understand the error but how to handle the window close event?
 
     
    