17db96d56Sopenharmony_cifrom tkinter import Toplevel, TclError
27db96d56Sopenharmony_ciimport sys
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci
57db96d56Sopenharmony_ciclass WindowList:
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci    def __init__(self):
87db96d56Sopenharmony_ci        self.dict = {}
97db96d56Sopenharmony_ci        self.callbacks = []
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci    def add(self, window):
127db96d56Sopenharmony_ci        window.after_idle(self.call_callbacks)
137db96d56Sopenharmony_ci        self.dict[str(window)] = window
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci    def delete(self, window):
167db96d56Sopenharmony_ci        try:
177db96d56Sopenharmony_ci            del self.dict[str(window)]
187db96d56Sopenharmony_ci        except KeyError:
197db96d56Sopenharmony_ci            # Sometimes, destroy() is called twice
207db96d56Sopenharmony_ci            pass
217db96d56Sopenharmony_ci        self.call_callbacks()
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ci    def add_windows_to_menu(self,  menu):
247db96d56Sopenharmony_ci        list = []
257db96d56Sopenharmony_ci        for key in self.dict:
267db96d56Sopenharmony_ci            window = self.dict[key]
277db96d56Sopenharmony_ci            try:
287db96d56Sopenharmony_ci                title = window.get_title()
297db96d56Sopenharmony_ci            except TclError:
307db96d56Sopenharmony_ci                continue
317db96d56Sopenharmony_ci            list.append((title, key, window))
327db96d56Sopenharmony_ci        list.sort()
337db96d56Sopenharmony_ci        for title, key, window in list:
347db96d56Sopenharmony_ci            menu.add_command(label=title, command=window.wakeup)
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci    def register_callback(self, callback):
377db96d56Sopenharmony_ci        self.callbacks.append(callback)
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci    def unregister_callback(self, callback):
407db96d56Sopenharmony_ci        try:
417db96d56Sopenharmony_ci            self.callbacks.remove(callback)
427db96d56Sopenharmony_ci        except ValueError:
437db96d56Sopenharmony_ci            pass
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ci    def call_callbacks(self):
467db96d56Sopenharmony_ci        for callback in self.callbacks:
477db96d56Sopenharmony_ci            try:
487db96d56Sopenharmony_ci                callback()
497db96d56Sopenharmony_ci            except:
507db96d56Sopenharmony_ci                t, v, tb = sys.exc_info()
517db96d56Sopenharmony_ci                print("warning: callback failed in WindowList", t, ":", v)
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ciregistry = WindowList()
557db96d56Sopenharmony_ci
567db96d56Sopenharmony_ciadd_windows_to_menu = registry.add_windows_to_menu
577db96d56Sopenharmony_ciregister_callback = registry.register_callback
587db96d56Sopenharmony_ciunregister_callback = registry.unregister_callback
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ciclass ListedToplevel(Toplevel):
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci    def __init__(self, master, **kw):
647db96d56Sopenharmony_ci        Toplevel.__init__(self, master, kw)
657db96d56Sopenharmony_ci        registry.add(self)
667db96d56Sopenharmony_ci        self.focused_widget = self
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ci    def destroy(self):
697db96d56Sopenharmony_ci        registry.delete(self)
707db96d56Sopenharmony_ci        Toplevel.destroy(self)
717db96d56Sopenharmony_ci        # If this is Idle's last window then quit the mainloop
727db96d56Sopenharmony_ci        # (Needed for clean exit on Windows 98)
737db96d56Sopenharmony_ci        if not registry.dict:
747db96d56Sopenharmony_ci            self.quit()
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ci    def update_windowlist_registry(self, window):
777db96d56Sopenharmony_ci        registry.call_callbacks()
787db96d56Sopenharmony_ci
797db96d56Sopenharmony_ci    def get_title(self):
807db96d56Sopenharmony_ci        # Subclass can override
817db96d56Sopenharmony_ci        return self.wm_title()
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci    def wakeup(self):
847db96d56Sopenharmony_ci        try:
857db96d56Sopenharmony_ci            if self.wm_state() == "iconic":
867db96d56Sopenharmony_ci                self.wm_withdraw()
877db96d56Sopenharmony_ci                self.wm_deiconify()
887db96d56Sopenharmony_ci            self.tkraise()
897db96d56Sopenharmony_ci            self.focused_widget.focus_set()
907db96d56Sopenharmony_ci        except TclError:
917db96d56Sopenharmony_ci            # This can happen when the Window menu was torn off.
927db96d56Sopenharmony_ci            # Simply ignore it.
937db96d56Sopenharmony_ci            pass
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_ciif __name__ == "__main__":
977db96d56Sopenharmony_ci    from unittest import main
987db96d56Sopenharmony_ci    main('idlelib.idle_test.test_window', verbosity=2)
99