mirror of
https://github.com/python/cpython.git
synced 2025-08-30 13:38:43 +00:00
Issue #17654: Ensure IDLE menus are customized properly on OS X for
non-framework builds and for all variants of Tk.
This commit is contained in:
parent
e7d532fbc9
commit
b7601676b0
12 changed files with 130 additions and 94 deletions
|
@ -1,48 +1,70 @@
|
|||
"""
|
||||
A number of function that enhance IDLE on MacOSX when it used as a normal
|
||||
GUI application (as opposed to an X11 application).
|
||||
A number of functions that enhance IDLE on Mac OSX.
|
||||
"""
|
||||
import sys
|
||||
import tkinter
|
||||
from os import path
|
||||
|
||||
|
||||
_appbundle = None
|
||||
import warnings
|
||||
|
||||
def runningAsOSXApp():
|
||||
"""
|
||||
Returns True if Python is running from within an app on OSX.
|
||||
If so, the various OS X customizations will be triggered later (menu
|
||||
fixup, et al). (Originally, this test was supposed to condition
|
||||
behavior on whether IDLE was running under Aqua Tk rather than
|
||||
under X11 Tk but that does not work since a framework build
|
||||
could be linked with X11. For several releases, this test actually
|
||||
differentiates between whether IDLE is running from a framework or
|
||||
not. As a future enhancement, it should be considered whether there
|
||||
should be a difference based on framework and any needed X11 adaptions
|
||||
should be made dependent on a new function that actually tests for X11.)
|
||||
"""
|
||||
global _appbundle
|
||||
if _appbundle is None:
|
||||
_appbundle = sys.platform == 'darwin'
|
||||
if _appbundle:
|
||||
import sysconfig
|
||||
_appbundle = bool(sysconfig.get_config_var('PYTHONFRAMEWORK'))
|
||||
return _appbundle
|
||||
|
||||
_carbonaquatk = None
|
||||
warnings.warn("runningAsOSXApp() is deprecated, use isAquaTk()",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return isAquaTk()
|
||||
|
||||
def isCarbonAquaTk(root):
|
||||
warnings.warn("isCarbonAquaTk(root) is deprecated, use isCarbonTk()",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return isCarbonTk()
|
||||
|
||||
_tk_type = None
|
||||
|
||||
def _initializeTkVariantTests(root):
|
||||
"""
|
||||
Initializes OS X Tk variant values for
|
||||
isAquaTk(), isCarbonTk(), isCocoaTk(), and isXQuartz().
|
||||
"""
|
||||
global _tk_type
|
||||
if sys.platform == 'darwin':
|
||||
ws = root.tk.call('tk', 'windowingsystem')
|
||||
if 'x11' in ws:
|
||||
_tk_type = "xquartz"
|
||||
elif 'aqua' not in ws:
|
||||
_tk_type = "other"
|
||||
elif 'AppKit' in root.tk.call('winfo', 'server', '.'):
|
||||
_tk_type = "cocoa"
|
||||
else:
|
||||
_tk_type = "carbon"
|
||||
else:
|
||||
_tk_type = "other"
|
||||
|
||||
def isAquaTk():
|
||||
"""
|
||||
Returns True if IDLE is using a native OS X Tk (Cocoa or Carbon).
|
||||
"""
|
||||
assert _tk_type is not None
|
||||
return _tk_type == "cocoa" or _tk_type == "carbon"
|
||||
|
||||
def isCarbonTk():
|
||||
"""
|
||||
Returns True if IDLE is using a Carbon Aqua Tk (instead of the
|
||||
newer Cocoa Aqua Tk).
|
||||
"""
|
||||
global _carbonaquatk
|
||||
if _carbonaquatk is None:
|
||||
_carbonaquatk = (runningAsOSXApp() and
|
||||
'aqua' in root.tk.call('tk', 'windowingsystem') and
|
||||
'AppKit' not in root.tk.call('winfo', 'server', '.'))
|
||||
return _carbonaquatk
|
||||
assert _tk_type is not None
|
||||
return _tk_type == "carbon"
|
||||
|
||||
def isCocoaTk():
|
||||
"""
|
||||
Returns True if IDLE is using a Cocoa Aqua Tk.
|
||||
"""
|
||||
assert _tk_type is not None
|
||||
return _tk_type == "cocoa"
|
||||
|
||||
def isXQuartz():
|
||||
"""
|
||||
Returns True if IDLE is using an OS X X11 Tk.
|
||||
"""
|
||||
assert _tk_type is not None
|
||||
return _tk_type == "xquartz"
|
||||
|
||||
def tkVersionWarning(root):
|
||||
"""
|
||||
|
@ -53,8 +75,7 @@ def tkVersionWarning(root):
|
|||
can still crash unexpectedly.
|
||||
"""
|
||||
|
||||
if (runningAsOSXApp() and
|
||||
('AppKit' in root.tk.call('winfo', 'server', '.')) ):
|
||||
if isCocoaTk():
|
||||
patchlevel = root.tk.call('info', 'patchlevel')
|
||||
if patchlevel not in ('8.5.7', '8.5.9'):
|
||||
return False
|
||||
|
@ -88,8 +109,8 @@ def hideTkConsole(root):
|
|||
|
||||
def overrideRootMenu(root, flist):
|
||||
"""
|
||||
Replace the Tk root menu by something that's more appropriate for
|
||||
IDLE.
|
||||
Replace the Tk root menu by something that is more appropriate for
|
||||
IDLE with an Aqua Tk.
|
||||
"""
|
||||
# The menu that is attached to the Tk root (".") is also used by AquaTk for
|
||||
# all windows that don't specify a menu of their own. The default menubar
|
||||
|
@ -108,6 +129,22 @@ def overrideRootMenu(root, flist):
|
|||
from idlelib import WindowList
|
||||
from idlelib.MultiCall import MultiCallCreator
|
||||
|
||||
closeItem = Bindings.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 Bindings.menudefs[0][1][-3:]
|
||||
Bindings.menudefs[0][1].insert(6, closeItem)
|
||||
|
||||
# Remove the 'About' entry from the help menu, it is in the application
|
||||
# menu
|
||||
del Bindings.menudefs[-1][1][0:2]
|
||||
|
||||
# Remove the 'Configure' entry from the options menu, it is in the
|
||||
# application menu as 'Preferences'
|
||||
del Bindings.menudefs[-2][1][0:2]
|
||||
|
||||
menubar = Menu(root)
|
||||
root.configure(menu=menubar)
|
||||
menudict = {}
|
||||
|
@ -156,7 +193,7 @@ def overrideRootMenu(root, flist):
|
|||
# right thing for now.
|
||||
root.createcommand('exit', flist.close_all_callback)
|
||||
|
||||
if isCarbonAquaTk(root):
|
||||
if isCarbonTk():
|
||||
# for Carbon AquaTk, replace the default Tk apple menu
|
||||
menudict['application'] = menu = Menu(menubar, name='apple')
|
||||
menubar.add_cascade(label='IDLE', menu=menu)
|
||||
|
@ -171,8 +208,7 @@ def overrideRootMenu(root, flist):
|
|||
Bindings.menudefs[0][1].append(
|
||||
('_Preferences....', '<<open-config-dialog>>'),
|
||||
)
|
||||
else:
|
||||
# assume Cocoa AquaTk
|
||||
if isCocoaTk():
|
||||
# replace default About dialog with About IDLE one
|
||||
root.createcommand('tkAboutDialog', about_dialog)
|
||||
# replace default "Help" item in Help menu
|
||||
|
@ -182,10 +218,22 @@ def overrideRootMenu(root, flist):
|
|||
|
||||
def setupApp(root, flist):
|
||||
"""
|
||||
Perform setup for the OSX application bundle.
|
||||
"""
|
||||
if not runningAsOSXApp(): return
|
||||
Perform initial OS X customizations if needed.
|
||||
Called from PyShell.main() after initial calls to Tk()
|
||||
|
||||
hideTkConsole(root)
|
||||
overrideRootMenu(root, flist)
|
||||
addOpenEventSupport(root, flist)
|
||||
There are currently three major versions of Tk in use on OS X:
|
||||
1. Aqua Cocoa Tk (native default since OS X 10.6)
|
||||
2. Aqua Carbon Tk (original native, 32-bit only, deprecated)
|
||||
3. X11 (supported by some third-party distributors, deprecated)
|
||||
There are various differences among the three that affect IDLE
|
||||
behavior, primarily with menus, mouse key events, and accelerators.
|
||||
Some one-time customizations are performed here.
|
||||
Others are dynamically tested throughout idlelib by calls to the
|
||||
isAquaTk(), isCarbonTk(), isCocoaTk(), isXQuartz() functions which
|
||||
are initialized here as well.
|
||||
"""
|
||||
_initializeTkVariantTests(root)
|
||||
if isAquaTk():
|
||||
hideTkConsole(root)
|
||||
overrideRootMenu(root, flist)
|
||||
addOpenEventSupport(root, flist)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue