Index: Lib/idlelib/Bindings.py =================================================================== --- Lib/idlelib/Bindings.py (revision 46048) +++ Lib/idlelib/Bindings.py (working copy) @@ -80,6 +80,32 @@ ]), ] +import sys +if sys.platform == 'darwin' and '.app' in sys.executable: + # Running as a proper MacOS application bundle. This block restructures + # the menus a little to make them conform better to the HIG. + + quitItem = menudefs[0][1][-1] + closeItem = menudefs[0][1][-2] + + # Remove the last 3 items of the file menu: a separator, close window and + # quit. Close window will be reinserted just above the save item, where + # it should be according to the HIG. Quit is in the application menu. + del menudefs[0][1][-3:] + menudefs[0][1].insert(6, closeItem) + + # Remove the 'About' entry from the help menu, it is in the application + # menu + del menudefs[-1][1][0:2] + + menudefs.insert(0, + ('application', [ + ('About IDLE', '<>'), + None, + ('_Preferences....', '<>'), + ])) + + default_keydefs = idleConf.GetCurrentKeySet() del sys Index: Lib/idlelib/PyShell.py =================================================================== --- Lib/idlelib/PyShell.py (revision 46048) +++ Lib/idlelib/PyShell.py (working copy) @@ -777,6 +777,10 @@ ("help", "_Help"), ] + if sys.platform in 'darwin' and 'IDLE.app' in sys.argv[0]: + del menu_specs[-3] + + # New classes from IdleHistory import History @@ -1289,6 +1293,21 @@ and "foobar" in sys.argv[1]. """ +def macosxAddOpenEvent(root, flist): + """ + This ensures that the application will respont to open AppleEvents, which + makes is feaseable to use IDLE as the default application for python files. + """ + + def doOpenFile(*args): + for fn in args: + flist.open(fn) + + # The command below is a hook in aquatk that is called whenever the app + # receives a file open event. The callback can have multiple arguments, + # one for every file that should be opened. + root.createcommand("::tk::mac::OpenDocument", doOpenFile) + def main(): global flist, root, use_subprocess @@ -1371,9 +1390,19 @@ enable_shell = enable_shell or not edit_start # start editor and/or shell windows: root = Tk(className="Idle") + + if sys.platform == 'darwin' and 'IDLE.app' in sys.argv[0]: + # The Aqua version of Tcl/Tk on MacOS will open a console window + # when stdin is an empty file, as it is in application bundles. Close + # the window as soon as possible to avoid actually showing it to the + # user. + root.tk.call('console', 'hide') fixwordbreaks(root) root.withdraw() flist = PyShellFileList(root) + + if sys.platform == 'darwin' and 'IDLE.app' in sys.argv[0]: + macosxAddOpenEvent(root, flist) if enable_edit: if not (cmd or script): for filename in args: @@ -1403,6 +1432,7 @@ elif script: shell.interp.prepend_syspath(script) shell.interp.execfile(script) + root.mainloop() root.destroy() Index: Lib/idlelib/keybindingDialog.py =================================================================== --- Lib/idlelib/keybindingDialog.py (revision 46048) +++ Lib/idlelib/keybindingDialog.py (working copy) @@ -133,7 +133,7 @@ config-keys.def must use the same ordering. """ import sys - if sys.platform == 'darwin' and sys.executable.count('.app'): + if sys.platform == 'darwin' and sys.argv[0].count('.app'): self.modifiers = ['Shift', 'Control', 'Option', 'Command'] else: self.modifiers = ['Control', 'Alt', 'Shift'] Index: Lib/idlelib/EditorWindow.py =================================================================== --- Lib/idlelib/EditorWindow.py (revision 46048) +++ Lib/idlelib/EditorWindow.py (working copy) @@ -66,9 +66,18 @@ 'Python%d%d.chm' % sys.version_info[:2]) if os.path.isfile(chmfile): dochome = chmfile + + elif sys.platform == 'darwin' and 'IDLE.app' in sys.argv[0]: + # documentation is stored inside the python framework + dochome = os.path.join(sys.prefix, + 'Resources/English.lproj/Documentation/index.html') + dochome = os.path.normpath(dochome) if os.path.isfile(dochome): EditorWindow.help_url = dochome + if sys.platform == 'darwin': + # Safari requires real file:-URLs + EditorWindow.help_url = 'file://' + EditorWindow.help_url else: EditorWindow.help_url = "http://www.python.org/doc/current" currentTheme=idleConf.CurrentTheme() @@ -278,6 +287,10 @@ def set_status_bar(self): self.status_bar = self.MultiStatusBar(self.top) + if sys.platform == 'darwin' and 'IDLE.app' in sys.argv[0]: + # Insert some padding to avoid obscuring some of the statusbar + # by the resize widget. + self.status_bar.set_label('_padding1', ' ', side=RIGHT) self.status_bar.set_label('column', 'Col: ?', side=RIGHT) self.status_bar.set_label('line', 'Ln: ?', side=RIGHT) self.status_bar.pack(side=BOTTOM, fill=X) @@ -301,6 +314,9 @@ ("help", "_Help"), ] + if sys.platform == 'darwin' and 'IDLE.app' in sys.argv[0]: + del menu_specs[-3] + def createmenubar(self): mbar = self.menubar self.menudict = menudict = {} @@ -308,6 +324,12 @@ underline, label = prepstr(label) menudict[name] = menu = Menu(mbar, name=name) mbar.add_cascade(label=label, menu=menu, underline=underline) + + if sys.platform == 'darwin' and '.framework' in sys.executable: + # Insert the application menu + menudict['application'] = menu = Menu(mbar, name='apple') + mbar.add_cascade(label='IDLE', menu=menu) + self.fill_menus() self.base_helpmenu_length = self.menudict['help'].index(END) self.reset_help_menu_entries()