blob: 460d5b67948dde2e1eee32fa548fdd289e3512de [file] [log] [blame]
Cheryl Sabella11303dd2019-01-06 15:55:52 -05001from tkinter import Toplevel, TclError
2import sys
David Scherer7aced172000-08-15 01:13:23 +00003
Terry Jan Reedybfbaa6b2016-08-31 00:50:55 -04004
David Scherer7aced172000-08-15 01:13:23 +00005class WindowList:
6
7 def __init__(self):
8 self.dict = {}
9 self.callbacks = []
10
11 def add(self, window):
12 window.after_idle(self.call_callbacks)
13 self.dict[str(window)] = window
14
15 def delete(self, window):
16 try:
17 del self.dict[str(window)]
18 except KeyError:
19 # Sometimes, destroy() is called twice
20 pass
21 self.call_callbacks()
22
23 def add_windows_to_menu(self, menu):
24 list = []
Kurt B. Kaisere0712772007-08-23 05:25:55 +000025 for key in self.dict:
David Scherer7aced172000-08-15 01:13:23 +000026 window = self.dict[key]
27 try:
28 title = window.get_title()
29 except TclError:
30 continue
Amaury Forgeot d'Arc47c2b602008-11-28 23:28:42 +000031 list.append((title, key, window))
David Scherer7aced172000-08-15 01:13:23 +000032 list.sort()
Amaury Forgeot d'Arc47c2b602008-11-28 23:28:42 +000033 for title, key, window in list:
David Scherer7aced172000-08-15 01:13:23 +000034 menu.add_command(label=title, command=window.wakeup)
35
36 def register_callback(self, callback):
37 self.callbacks.append(callback)
38
39 def unregister_callback(self, callback):
40 try:
Steven M. Gava817a76c2001-07-12 05:35:17 +000041 self.callbacks.remove(callback)
David Scherer7aced172000-08-15 01:13:23 +000042 except ValueError:
43 pass
44
45 def call_callbacks(self):
46 for callback in self.callbacks:
47 try:
48 callback()
49 except:
Guido van Rossum69e80842006-04-17 23:13:00 +000050 t, v, tb = sys.exc_info()
Guido van Rossumbe19ed72007-02-09 05:37:30 +000051 print("warning: callback failed in WindowList", t, ":", v)
David Scherer7aced172000-08-15 01:13:23 +000052
Terry Jan Reedybfbaa6b2016-08-31 00:50:55 -040053
David Scherer7aced172000-08-15 01:13:23 +000054registry = WindowList()
55
56add_windows_to_menu = registry.add_windows_to_menu
57register_callback = registry.register_callback
58unregister_callback = registry.unregister_callback
59
60
61class ListedToplevel(Toplevel):
62
63 def __init__(self, master, **kw):
64 Toplevel.__init__(self, master, kw)
65 registry.add(self)
Kurt B. Kaiser183403a2004-08-22 05:14:32 +000066 self.focused_widget = self
David Scherer7aced172000-08-15 01:13:23 +000067
68 def destroy(self):
69 registry.delete(self)
70 Toplevel.destroy(self)
Kurt B. Kaiserbeb6bd92002-10-04 21:54:41 +000071 # If this is Idle's last window then quit the mainloop
72 # (Needed for clean exit on Windows 98)
73 if not registry.dict:
74 self.quit()
David Scherer7aced172000-08-15 01:13:23 +000075
Kurt B. Kaiser260cb902003-06-06 21:58:38 +000076 def update_windowlist_registry(self, window):
77 registry.call_callbacks()
78
David Scherer7aced172000-08-15 01:13:23 +000079 def get_title(self):
80 # Subclass can override
81 return self.wm_title()
82
83 def wakeup(self):
84 try:
85 if self.wm_state() == "iconic":
Kurt B. Kaiser183403a2004-08-22 05:14:32 +000086 self.wm_withdraw()
David Scherer7aced172000-08-15 01:13:23 +000087 self.wm_deiconify()
Kurt B. Kaiser183403a2004-08-22 05:14:32 +000088 self.tkraise()
89 self.focused_widget.focus_set()
David Scherer7aced172000-08-15 01:13:23 +000090 except TclError:
Terry Jan Reedya361e892018-06-20 21:25:59 -040091 # This can happen when the Window menu was torn off.
David Scherer7aced172000-08-15 01:13:23 +000092 # Simply ignore it.
93 pass
Terry Jan Reedy4d921582018-06-19 19:12:52 -040094
95
96if __name__ == "__main__":
97 from unittest import main
Terry Jan Reedya361e892018-06-20 21:25:59 -040098 main('idlelib.idle_test.test_window', verbosity=2)