Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(17)

Delta Between Two Patch Sets: Lib/idlelib/macosxSupport.py

Issue 13884: IDLE 2.6.5 Recent Files undocks
Left Patch Set: Created 8 years, 1 month ago
Right Patch Set: Created 4 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/idlelib/help.txt ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 """ 1 """
2 A number of function that enhance IDLE on MacOSX when it used as a normal 2 A number of functions that enhance IDLE on Mac OSX.
3 GUI application (as opposed to an X11 application).
4 """ 3 """
5 import sys 4 import sys
6 import tkinter 5 import Tkinter
7 from os import path 6 from os import path
8 7
9 8
10 _appbundle = None 9 import warnings
11 10
12 def runningAsOSXApp(): 11 def runningAsOSXApp():
13 """ 12 warnings.warn("runningAsOSXApp() is deprecated, use isAquaTk()",
14 Returns True if Python is running from within an app on OSX. 13 DeprecationWarning, stacklevel=2)
15 If so, assume that Python was built with Aqua Tcl/Tk rather than 14 return isAquaTk()
16 X11 Tcl/Tk.
17 """
18 global _appbundle
19 if _appbundle is None:
20 _appbundle = (sys.platform == 'darwin' and '.app' in sys.executable)
21 return _appbundle
22
23 _carbonaquatk = None
24 15
25 def isCarbonAquaTk(root): 16 def isCarbonAquaTk(root):
17 warnings.warn("isCarbonAquaTk(root) is deprecated, use isCarbonTk()",
18 DeprecationWarning, stacklevel=2)
19 return isCarbonTk()
20
21 _tk_type = None
22
23 def _initializeTkVariantTests(root):
24 """
25 Initializes OS X Tk variant values for
26 isAquaTk(), isCarbonTk(), isCocoaTk(), and isXQuartz().
27 """
28 global _tk_type
29 if sys.platform == 'darwin':
30 ws = root.tk.call('tk', 'windowingsystem')
31 if 'x11' in ws:
32 _tk_type = "xquartz"
33 elif 'aqua' not in ws:
34 _tk_type = "other"
35 elif 'AppKit' in root.tk.call('winfo', 'server', '.'):
36 _tk_type = "cocoa"
37 else:
38 _tk_type = "carbon"
39 else:
40 _tk_type = "other"
41
42 def isAquaTk():
43 """
44 Returns True if IDLE is using a native OS X Tk (Cocoa or Carbon).
45 """
46 assert _tk_type is not None
47 return _tk_type == "cocoa" or _tk_type == "carbon"
48
49 def isCarbonTk():
26 """ 50 """
27 Returns True if IDLE is using a Carbon Aqua Tk (instead of the 51 Returns True if IDLE is using a Carbon Aqua Tk (instead of the
28 newer Cocoa Aqua Tk). 52 newer Cocoa Aqua Tk).
29 """ 53 """
30 global _carbonaquatk 54 assert _tk_type is not None
31 if _carbonaquatk is None: 55 return _tk_type == "carbon"
32 _carbonaquatk = (runningAsOSXApp() and 56
33 'aqua' in root.tk.call('tk', 'windowingsystem') and 57 def isCocoaTk():
34 'AppKit' not in root.tk.call('winfo', 'server', '.')) 58 """
35 return _carbonaquatk 59 Returns True if IDLE is using a Cocoa Aqua Tk.
60 """
61 assert _tk_type is not None
62 return _tk_type == "cocoa"
63
64 def isXQuartz():
65 """
66 Returns True if IDLE is using an OS X X11 Tk.
67 """
68 assert _tk_type is not None
69 return _tk_type == "xquartz"
36 70
37 def tkVersionWarning(root): 71 def tkVersionWarning(root):
38 """ 72 """
39 Returns a string warning message if the Tk version in use appears to 73 Returns a string warning message if the Tk version in use appears to
40 be one known to cause problems with IDLE. The Apple Cocoa-based Tk 8.5 74 be one known to cause problems with IDLE.
41 that was shipped with Mac OS X 10.6. 75 1. Apple Cocoa-based Tk 8.5.7 shipped with Mac OS X 10.6 is unusable.
42 """ 76 2. Apple Cocoa-based Tk 8.5.9 in OS X 10.7 and 10.8 is better but
43 77 can still crash unexpectedly.
44 if (runningAsOSXApp() and 78 """
45 ('AppKit' in root.tk.call('winfo', 'server', '.')) and 79
46 (root.tk.call('info', 'patchlevel') == '8.5.7') ): 80 if isCocoaTk():
47 return (r"WARNING: The version of Tcl/Tk (8.5.7) in use may" 81 patchlevel = root.tk.call('info', 'patchlevel')
82 if patchlevel not in ('8.5.7', '8.5.9'):
83 return False
84 return (r"WARNING: The version of Tcl/Tk ({0}) in use may"
48 r" be unstable.\n" 85 r" be unstable.\n"
49 r"Visit http://www.python.org/download/mac/tcltk/" 86 r"Visit http://www.python.org/download/mac/tcltk/"
50 r" for current information.") 87 r" for current information.".format(patchlevel))
51 else: 88 else:
52 return False 89 return False
53 90
54 def addOpenEventSupport(root, flist): 91 def addOpenEventSupport(root, flist):
55 """ 92 """
56 This ensures that the application will respond to open AppleEvents, which 93 This ensures that the application will respond to open AppleEvents, which
57 makes is feasible to use IDLE as the default application for python files. 94 makes is feasible to use IDLE as the default application for python files.
58 """ 95 """
59 def doOpenFile(*args): 96 def doOpenFile(*args):
60 for fn in args: 97 for fn in args:
61 flist.open(fn) 98 flist.open(fn)
62 99
63 # The command below is a hook in aquatk that is called whenever the app 100 # The command below is a hook in aquatk that is called whenever the app
64 # receives a file open event. The callback can have multiple arguments, 101 # receives a file open event. The callback can have multiple arguments,
65 # one for every file that should be opened. 102 # one for every file that should be opened.
66 root.createcommand("::tk::mac::OpenDocument", doOpenFile) 103 root.createcommand("::tk::mac::OpenDocument", doOpenFile)
67 104
68 def hideTkConsole(root): 105 def hideTkConsole(root):
69 try: 106 try:
70 root.tk.call('console', 'hide') 107 root.tk.call('console', 'hide')
71 except tkinter.TclError: 108 except Tkinter.TclError:
72 # Some versions of the Tk framework don't have a console object 109 # Some versions of the Tk framework don't have a console object
73 pass 110 pass
74 111
75 def overrideRootMenu(root, flist): 112 def overrideRootMenu(root, flist):
76 """ 113 """
77 Replace the Tk root menu by something that's more appropriate for 114 Replace the Tk root menu by something that is more appropriate for
78 IDLE. 115 IDLE with an Aqua Tk.
79 """ 116 """
80 # The menu that is attached to the Tk root (".") is also used by AquaTk for 117 # The menu that is attached to the Tk root (".") is also used by AquaTk for
81 # all windows that don't specify a menu of their own. The default menubar 118 # all windows that don't specify a menu of their own. The default menubar
82 # contains a number of menus, none of which are appropriate for IDLE. The 119 # contains a number of menus, none of which are appropriate for IDLE. The
83 # Most annoying of those is an 'About Tck/Tk...' menu in the application 120 # Most annoying of those is an 'About Tck/Tk...' menu in the application
84 # menu. 121 # menu.
85 # 122 #
86 # This function replaces the default menubar by a mostly empty one, it 123 # This function replaces the default menubar by a mostly empty one, it
87 # should only contain the correct application menu and the window menu. 124 # should only contain the correct application menu and the window menu.
88 # 125 #
89 # Due to a (mis-)feature of TkAqua the user will also see an empty Help 126 # Due to a (mis-)feature of TkAqua the user will also see an empty Help
90 # menu. 127 # menu.
91 from tkinter import Menu, Text, Text 128 from Tkinter import Menu
92 from idlelib.EditorWindow import prepstr, get_accelerator
93 from idlelib import Bindings 129 from idlelib import Bindings
94 from idlelib import WindowList 130 from idlelib import WindowList
95 from idlelib.MultiCall import MultiCallCreator 131
96 132 closeItem = Bindings.menudefs[0][1][-2]
133
134 # Remove the last 3 items of the file menu: a separator, close window and
135 # quit. Close window will be reinserted just above the save item, where
136 # it should be according to the HIG. Quit is in the application menu.
137 del Bindings.menudefs[0][1][-3:]
138 Bindings.menudefs[0][1].insert(6, closeItem)
139
140 # Remove the 'About' entry from the help menu, it is in the application
141 # menu
142 del Bindings.menudefs[-1][1][0:2]
143 # Remove the 'Configure Idle' entry from the options menu, it is in the
144 # application menu as 'Preferences'
145 del Bindings.menudefs[-2][1][0]
97 menubar = Menu(root) 146 menubar = Menu(root)
98 root.configure(menu=menubar) 147 root.configure(menu=menubar)
99 menudict = {} 148 menudict = {}
100 149
101 menudict['windows'] = menu = Menu(menubar, name='windows', tearoff=0) 150 menudict['windows'] = menu = Menu(menubar, name='windows', tearoff=0)
102 menubar.add_cascade(label='Window', menu=menu, underline=0) 151 menubar.add_cascade(label='Window', menu=menu, underline=0)
103 152
104 def postwindowsmenu(menu=menu): 153 def postwindowsmenu(menu=menu):
105 end = menu.index('end') 154 end = menu.index('end')
106 if end is None: 155 if end is None:
107 end = -1 156 end = -1
108 157
109 if end > 0: 158 if end > 0:
110 menu.delete(0, end) 159 menu.delete(0, end)
111 WindowList.add_windows_to_menu(menu) 160 WindowList.add_windows_to_menu(menu)
112 WindowList.register_callback(postwindowsmenu) 161 WindowList.register_callback(postwindowsmenu)
113 162
114 def about_dialog(event=None): 163 def about_dialog(event=None):
115 from idlelib import aboutDialog 164 from idlelib import aboutDialog
116 aboutDialog.AboutDialog(root, 'About IDLE') 165 aboutDialog.AboutDialog(root, 'About IDLE')
117 166
118 def config_dialog(event=None): 167 def config_dialog(event=None):
119 from idlelib import configDialog 168 from idlelib import configDialog
120
121 # Ensure that the root object has an instance_dict attribute,
122 # mirrors code in EditorWindow (although that sets the attribute
123 # on an EditorWindow instance that is then passed as the first
124 # argument to ConfigDialog)
125 root.instance_dict = flist.inversedict
126 root.instance_dict = flist.inversedict 169 root.instance_dict = flist.inversedict
127 configDialog.ConfigDialog(root, 'Settings') 170 configDialog.ConfigDialog(root, 'Settings')
128 171
129 def help_dialog(event=None): 172 def help_dialog(event=None):
130 from idlelib import textView 173 from idlelib import textView
131 fn = path.join(path.abspath(path.dirname(__file__)), 'help.txt') 174 fn = path.join(path.abspath(path.dirname(__file__)), 'help.txt')
132 textView.view_file(root, 'Help', fn) 175 textView.view_file(root, 'Help', fn)
133 176
134 root.bind('<<about-idle>>', about_dialog) 177 root.bind('<<about-idle>>', about_dialog)
135 root.bind('<<open-config-dialog>>', config_dialog) 178 root.bind('<<open-config-dialog>>', config_dialog)
136 root.createcommand('::tk::mac::ShowPreferences', config_dialog) 179 root.createcommand('::tk::mac::ShowPreferences', config_dialog)
137 if flist: 180 if flist:
138 root.bind('<<close-all-windows>>', flist.close_all_callback) 181 root.bind('<<close-all-windows>>', flist.close_all_callback)
139 182
140 # The binding above doesn't reliably work on all versions of Tk 183 # The binding above doesn't reliably work on all versions of Tk
141 # on MacOSX. Adding command definition below does seem to do the 184 # on MacOSX. Adding command definition below does seem to do the
142 # right thing for now. 185 # right thing for now.
143 root.createcommand('exit', flist.close_all_callback) 186 root.createcommand('exit', flist.close_all_callback)
144 187
145 if isCarbonAquaTk(root): 188 if isCarbonTk():
146 # for Carbon AquaTk, replace the default Tk apple menu 189 # for Carbon AquaTk, replace the default Tk apple menu
147 menudict['application'] = menu = Menu(menubar, name='apple', 190 menudict['application'] = menu = Menu(menubar, name='apple',
148 tearoff=0) 191 tearoff=0)
149 menubar.add_cascade(label='IDLE', menu=menu) 192 menubar.add_cascade(label='IDLE', menu=menu)
150 Bindings.menudefs.insert(0, 193 Bindings.menudefs.insert(0,
151 ('application', [ 194 ('application', [
152 ('About IDLE', '<<about-idle>>'), 195 ('About IDLE', '<<about-idle>>'),
153 None, 196 None,
154 ])) 197 ]))
155 tkversion = root.tk.eval('info patchlevel') 198 tkversion = root.tk.eval('info patchlevel')
156 if tuple(map(int, tkversion.split('.'))) < (8, 4, 14): 199 if tuple(map(int, tkversion.split('.'))) < (8, 4, 14):
157 # for earlier AquaTk versions, supply a Preferences menu item 200 # for earlier AquaTk versions, supply a Preferences menu item
158 Bindings.menudefs[0][1].append( 201 Bindings.menudefs[0][1].append(
159 ('_Preferences....', '<<open-config-dialog>>'), 202 ('_Preferences....', '<<open-config-dialog>>'),
160 ) 203 )
161 else: 204 if isCocoaTk():
162 # assume Cocoa AquaTk
163 # replace default About dialog with About IDLE one 205 # replace default About dialog with About IDLE one
164 root.createcommand('tkAboutDialog', about_dialog) 206 root.createcommand('tkAboutDialog', about_dialog)
165 # replace default "Help" item in Help menu 207 # replace default "Help" item in Help menu
166 root.createcommand('::tk::mac::ShowHelp', help_dialog) 208 root.createcommand('::tk::mac::ShowHelp', help_dialog)
167 # remove redundant "IDLE Help" from menu 209 # remove redundant "IDLE Help" from menu
168 del Bindings.menudefs[-1][1][0] 210 del Bindings.menudefs[-1][1][0]
169 211
170 def setupApp(root, flist): 212 def setupApp(root, flist):
171 """ 213 """
172 Perform setup for the OSX application bundle. 214 Perform initial OS X customizations if needed.
173 """ 215 Called from PyShell.main() after initial calls to Tk()
174 if not runningAsOSXApp(): return 216
175 217 There are currently three major versions of Tk in use on OS X:
176 hideTkConsole(root) 218 1. Aqua Cocoa Tk (native default since OS X 10.6)
177 overrideRootMenu(root, flist) 219 2. Aqua Carbon Tk (original native, 32-bit only, deprecated)
178 addOpenEventSupport(root, flist) 220 3. X11 (supported by some third-party distributors, deprecated)
221 There are various differences among the three that affect IDLE
222 behavior, primarily with menus, mouse key events, and accelerators.
223 Some one-time customizations are performed here.
224 Others are dynamically tested throughout idlelib by calls to the
225 isAquaTk(), isCarbonTk(), isCocoaTk(), isXQuartz() functions which
226 are initialized here as well.
227 """
228 _initializeTkVariantTests(root)
229 if isAquaTk():
230 hideTkConsole(root)
231 overrideRootMenu(root, flist)
232 addOpenEventSupport(root, flist)
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+