Fix for issue5194, based on a patch by Ned Deily.

This commit is contained in:
Ronald Oussoren 2009-02-12 15:01:44 +00:00
parent de09acf298
commit 827822ef3f
8 changed files with 65 additions and 15 deletions

View File

@ -10,6 +10,7 @@ windows.
""" """
import sys import sys
from idlelib.configHandler import idleConf from idlelib.configHandler import idleConf
from idlelib import macosxSupport
menudefs = [ menudefs = [
# underscore prefixes character to underscore # underscore prefixes character to underscore
@ -80,7 +81,7 @@ menudefs = [
]), ]),
] ]
if sys.platform == 'darwin' and '.app' in sys.executable: if macosxSupport.runningAsOSXApp():
# Running as a proper MacOS application bundle. This block restructures # Running as a proper MacOS application bundle. This block restructures
# the menus a little to make them conform better to the HIG. # the menus a little to make them conform better to the HIG.

View File

@ -363,7 +363,7 @@ class EditorWindow(object):
underline, label = prepstr(label) underline, label = prepstr(label)
menudict[name] = menu = Menu(mbar, name=name) menudict[name] = menu = Menu(mbar, name=name)
mbar.add_cascade(label=label, menu=menu, underline=underline) mbar.add_cascade(label=label, menu=menu, underline=underline)
if sys.platform == 'darwin' and '.framework' in sys.executable: if macosxSupport.runningAsOSXApp():
# Insert the application menu # Insert the application menu
menudict['application'] = menu = Menu(mbar, name='apple') menudict['application'] = menu = Menu(mbar, name='apple')
mbar.add_cascade(label='IDLE', menu=menu) mbar.add_cascade(label='IDLE', menu=menu)

View File

@ -32,6 +32,7 @@ Each function will be called at most once for each event.
import sys import sys
import re import re
import tkinter import tkinter
from idlelib import macosxSupport
# the event type constants, which define the meaning of mc_type # the event type constants, which define the meaning of mc_type
MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3; MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3;
@ -44,7 +45,7 @@ MC_SHIFT = 1<<0; MC_CONTROL = 1<<2; MC_ALT = 1<<3; MC_META = 1<<5
MC_OPTION = 1<<6; MC_COMMAND = 1<<7 MC_OPTION = 1<<6; MC_COMMAND = 1<<7
# define the list of modifiers, to be used in complex event types. # define the list of modifiers, to be used in complex event types.
if sys.platform == "darwin" and sys.executable.count(".app"): if macosxSupport.runningAsOSXApp():
_modifiers = (("Shift",), ("Control",), ("Option",), ("Command",)) _modifiers = (("Shift",), ("Control",), ("Option",), ("Command",))
_modifier_masks = (MC_SHIFT, MC_CONTROL, MC_OPTION, MC_COMMAND) _modifier_masks = (MC_SHIFT, MC_CONTROL, MC_OPTION, MC_COMMAND)
else: else:

View File

@ -4,6 +4,7 @@ Dialog for building Tkinter accelerator key bindings
from tkinter import * from tkinter import *
import tkinter.messagebox as tkMessageBox import tkinter.messagebox as tkMessageBox
import string import string
from idlelib import macosxSupport
class GetKeysDialog(Toplevel): class GetKeysDialog(Toplevel):
def __init__(self,parent,title,action,currentKeySequences): def __init__(self,parent,title,action,currentKeySequences):
@ -133,7 +134,7 @@ class GetKeysDialog(Toplevel):
config-keys.def must use the same ordering. config-keys.def must use the same ordering.
""" """
import sys import sys
if sys.platform == 'darwin' and sys.argv[0].count('.app'): if macosxSupport.runningAsOSXApp():
self.modifiers = ['Shift', 'Control', 'Option', 'Command'] self.modifiers = ['Shift', 'Control', 'Option', 'Command']
else: else:
self.modifiers = ['Control', 'Alt', 'Shift'] self.modifiers = ['Control', 'Alt', 'Shift']

View File

@ -6,8 +6,12 @@ import sys
import tkinter import tkinter
def runningAsOSXApp(): def runningAsOSXApp():
""" Returns True iff running from the IDLE.app bundle on OSX """ """
return (sys.platform == 'darwin' and 'IDLE.app' in sys.argv[0]) Returns True if Python is running from within an app on OSX.
If so, assume that Python was built with Aqua Tcl/Tk rather than
X11 Tck/Tk.
"""
return (sys.platform == 'darwin' and '.app' in sys.executable)
def addOpenEventSupport(root, flist): def addOpenEventSupport(root, flist):
""" """

View File

@ -1,4 +1,4 @@
#!%prefix%/Resources/Python.app/Contents/MacOS/Python3 #!%prefix%/Resources/Python.app/Contents/MacOS/%exe%
import sys, os import sys, os
execdir = os.path.dirname(sys.argv[0]) execdir = os.path.dirname(sys.argv[0])

View File

@ -3,8 +3,6 @@ Bootstrap script for IDLE as an application bundle.
""" """
import sys, os import sys, os
from idlelib.PyShell import main
# Change the current directory the user's home directory, that way we'll get # Change the current directory the user's home directory, that way we'll get
# a more useful default location in the open/save dialogs. # a more useful default location in the open/save dialogs.
os.chdir(os.path.expanduser('~/Documents')) os.chdir(os.path.expanduser('~/Documents'))
@ -13,10 +11,54 @@ os.chdir(os.path.expanduser('~/Documents'))
# Make sure sys.executable points to the python interpreter inside the # Make sure sys.executable points to the python interpreter inside the
# framework, instead of at the helper executable inside the application # framework, instead of at the helper executable inside the application
# bundle (the latter works, but doesn't allow access to the window server) # bundle (the latter works, but doesn't allow access to the window server)
if sys.executable.endswith('-32'): #
sys.executable = os.path.join(sys.prefix, 'bin', 'python-32') # .../IDLE.app/
else: # Contents/
sys.executable = os.path.join(sys.prefix, 'bin', 'python') # MacOS/
# IDLE (a python script)
# Python{-32} (symlink)
# Resources/
# idlemain.py (this module)
# ...
#
# ../IDLE.app/Contents/MacOS/Python{-32} is symlinked to
# ..Library/Frameworks/Python.framework/Versions/m.n
# /Resources/Python.app/Contents/MacOS/Python{-32}
# which is the Python interpreter executable
#
# The flow of control is as follows:
# 1. IDLE.app is launched which starts python running the IDLE script
# 2. IDLE script exports
# PYTHONEXECUTABLE = .../IDLE.app/Contents/MacOS/Python{-32}
# (the symlink to the framework python)
# 3. IDLE script alters sys.argv and uses os.execve to replace itself with
# idlemain.py running under the symlinked python.
# This is the magic step.
# 4. During interpreter initialization, because PYTHONEXECUTABLE is defined,
# sys.executable may get set to an unuseful value.
#
# (Note that the IDLE script and the setting of PYTHONEXECUTABLE is
# generated automatically by bundlebuilder in the Python 2.x build.
# Also, IDLE invoked via command line, i.e. bin/idle, bypasses all of
# this.)
#
# Now fix up the execution environment before importing idlelib.
# Reset sys.executable to its normal value, the actual path of
# the interpreter in the framework, by following the symlink
# exported in PYTHONEXECUTABLE.
pyex = os.environ['PYTHONEXECUTABLE']
sys.executable = os.path.join(os.path.dirname(pyex), os.readlink(pyex))
# Remove any sys.path entries for the Resources dir in the IDLE.app bundle.
p = pyex.partition('.app')
if p[2].startswith('/Contents/MacOS/Python'):
sys.path = [value for value in sys.path if
value.partition('.app') != (p[0], p[1], '/Contents/Resources')]
# Unexport PYTHONEXECUTABLE so that the other Python processes started
# by IDLE have a normal sys.executable.
del os.environ['PYTHONEXECUTABLE']
# Look for the -psn argument that the launcher adds and remove it, it will # Look for the -psn argument that the launcher adds and remove it, it will
# only confuse the IDLE startup code. # only confuse the IDLE startup code.
@ -25,6 +67,7 @@ for idx, value in enumerate(sys.argv):
del sys.argv[idx] del sys.argv[idx]
break break
#argvemulator.ArgvCollector().mainloop() # Now it is safe to import idlelib.
from idlelib.PyShell import main
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -215,7 +215,7 @@ install_Python4way: install_Python
install_IDLE: install_IDLE:
test -d "$(DESTDIR)$(PYTHONAPPSDIR)" || mkdir -p "$(DESTDIR)$(PYTHONAPPSDIR)" test -d "$(DESTDIR)$(PYTHONAPPSDIR)" || mkdir -p "$(DESTDIR)$(PYTHONAPPSDIR)"
-test -d "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" && rm -r "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" -test -d "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" && rm -rf "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app"
/bin/cp -PR "$(srcdir)/IDLE/IDLE.app" "$(DESTDIR)$(PYTHONAPPSDIR)" /bin/cp -PR "$(srcdir)/IDLE/IDLE.app" "$(DESTDIR)$(PYTHONAPPSDIR)"
ln -sf $(INSTALLED_PYTHONAPP) "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app/Contents/MacOS/Python" ln -sf $(INSTALLED_PYTHONAPP) "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app/Contents/MacOS/Python"
sed -e "s!%prefix%!$(prefix)!g" -e 's!%exe%!$(PYTHONFRAMEWORK)!g' < "$(srcdir)/IDLE/IDLE.app/Contents/MacOS/IDLE" > "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app/Contents/MacOS/IDLE" sed -e "s!%prefix%!$(prefix)!g" -e 's!%exe%!$(PYTHONFRAMEWORK)!g' < "$(srcdir)/IDLE/IDLE.app/Contents/MacOS/IDLE" > "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app/Contents/MacOS/IDLE"