gh-152728: IDLE - move 3 toplevel fix_xyz functions to idlelb.util (#152729)

IDLE - move 3 toplevel fix_xyz functions to idlelb.util

Move idlelib functions run.fix_scaling, editor.fixwordbreaks
(as fix_word_breaks).  All are used in at least 3 modules.
This commit is contained in:
Terry Jan Reedy authored and GitHub committed 2026-07-01 04:58:39 +00:00
1 parent fdcee4f5bd
commit 53ca52ddb0
9 files changed
+58 -49

No files matched your search

+3
View File
@@ -4,6 +4,9 @@ Released on 2026-10-01
=========================
gh-152728: Move functions run.fix_scaling, editor.fixwordbreaks (as fix_word_breaks)
and pyshell.fix_x11_paste to module util. Patch by Terry J. Reedy.
gh-85320: IDLE now reads and writes its configuration files and the
breakpoints file using UTF-8 instead of the locale encoding.
Files with non-ASCII characters and non-UTF-8 encoding may need
+4 -13
View File
@@ -1704,19 +1704,10 @@ def get_accelerator(keydefs, eventname):
return s
def fixwordbreaks(root):
# On Windows, tcl/tk breaks 'words' only on spaces, as in Command Prompt.
# We want Motif style everywhere. See #21474, msg218992 and followup.
tk = root.tk
tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded
tk.call('set', 'tcl_wordchars', r'\w')
tk.call('set', 'tcl_nonwordchars', r'\W')
def _editor_window(parent): # htest #
# error if close master window first - timer event, after script
root = parent
fixwordbreaks(root)
def _editor_window(root): # htest #
# Error if close master window first - timer event, after script
from util import fix_word_breaks
fix_word_breaks(root)
if sys.argv[1:]:
filename = sys.argv[1]
else:
+3 -3
View File
@@ -112,12 +112,12 @@ class FileList:
def _test(): # TODO check and convert to htest
# Maybe redundant with test_filelist.FileListTest.test_new_empty.
from tkinter import Tk
from idlelib.editor import fixwordbreaks
from idlelib.run import fix_scaling
from idlelib.util import fix_scaling, fix_word_breaks
root = Tk()
fix_scaling(root)
fixwordbreaks(root)
fix_word_breaks(root)
root.withdraw()
flist = FileList(root)
flist.new()
+2 -2
View File
@@ -7,7 +7,7 @@ requires('gui')
import tkinter as tk
from tkinter import ttk
import unittest
from idlelib import pyshell
from idlelib.util import fix_x11_paste
class PasteTest(unittest.TestCase):
'''Test pasting into widgets that allow pasting.
@@ -18,7 +18,7 @@ class PasteTest(unittest.TestCase):
def setUpClass(cls):
cls.root = root = tk.Tk()
cls.root.withdraw()
pyshell.fix_x11_paste(root)
fix_x11_paste(root)
cls.text = tk.Text(root)
cls.entry = tk.Entry(root)
cls.tentry = ttk.Entry(root)
+3 -4
View File
@@ -11,11 +11,10 @@ import tkinter as tk
from idlelib.idle_test.tkinter_testing_utils import run_in_tk_mainloop
from idlelib.delegator import Delegator
from idlelib.editor import fixwordbreaks
from idlelib.percolator import Percolator
import idlelib.pyshell
from idlelib.pyshell import fix_x11_paste, PyShell, PyShellFileList
from idlelib.run import fix_scaling
from idlelib.pyshell import PyShell, PyShellFileList
from idlelib.util import fix_scaling, fix_word_breaks, fix_x11_paste
import idlelib.sidebar
from idlelib.sidebar import get_end_linenumber, get_lineno
@@ -403,7 +402,7 @@ class ShellSidebarTest(unittest.TestCase):
root.withdraw()
fix_scaling(root)
fixwordbreaks(root)
fix_word_breaks(root)
fix_x11_paste(root)
cls.flist = flist = PyShellFileList(root)
+6 -16
View File
@@ -36,13 +36,14 @@ from idlelib.config import idleConf
from idlelib.delegator import Delegator
from idlelib import debugger
from idlelib import debugger_r
from idlelib.editor import EditorWindow, fixwordbreaks
from idlelib.editor import EditorWindow
from idlelib.filelist import FileList
from idlelib.outwin import OutputWindow
from idlelib import replace
from idlelib import rpc
from idlelib.run import idle_formatwarning, StdInputFile, StdOutputFile
from idlelib.undo import UndoDelegator
from idlelib.util import fix_word_breaks
# Default for testing; defaults to True in main() for running.
use_subprocess = False
@@ -881,9 +882,9 @@ class PyShell(OutputWindow):
if ms[2][0] != "shell":
ms.insert(2, ("shell", "She_ll"))
self.interp = ModifiedInterpreter(self)
if flist is None:
if flist is None: # TODO possible? root and flist in main.
root = Tk()
fixwordbreaks(root)
fix_word_breaks(root)
root.withdraw()
flist = PyShellFileList(root)
@@ -1452,17 +1453,6 @@ class PyShell(OutputWindow):
self.shell_sidebar.update_sidebar()
def fix_x11_paste(root):
"Make paste replace selection on x11. See issue #5124."
if root._windowingsystem == 'x11':
for cls in 'Text', 'Entry', 'Spinbox':
root.bind_class(
cls,
'<<Paste>>',
'catch {%W delete sel.first sel.last}\n' +
root.bind_class(cls, '<<Paste>>'))
usage_msg = """\
USAGE: idle [-deins] [-t title] [file]*
@@ -1522,6 +1512,7 @@ def main():
from platform import system
from idlelib import testing # bool value
from idlelib import macosx
from idlelib.util import fix_scaling, fix_x11_paste
global flist, root, use_subprocess
@@ -1607,7 +1598,6 @@ def main():
NoDefaultRoot()
root = Tk(className="Idle")
root.withdraw()
from idlelib.run import fix_scaling
fix_scaling(root)
# set application icon
@@ -1629,7 +1619,7 @@ def main():
root.wm_iconphoto(True, *icons)
# start editor and/or shell windows:
fixwordbreaks(root)
fix_word_breaks(root)
fix_x11_paste(root)
flist = PyShellFileList(root)
macosx.setupApp(root, flist)
+2 -11
View File
@@ -25,6 +25,7 @@ from idlelib import debugobj_r # remote_object_tree_item
from idlelib import iomenu # encoding
from idlelib import rpc # multiple objects
from idlelib import stackviewer # StackTreeItem
from idlelib import util # fix_scaling
import __main__
import tkinter # Use tcl and, if startup fails, messagebox.
@@ -216,7 +217,7 @@ def show_socket_error(err, address):
import tkinter
from tkinter.messagebox import showerror
root = tkinter.Tk()
fix_scaling(root)
util.fix_scaling(root)
root.withdraw()
showerror(
"Subprocess Connection Error",
@@ -389,16 +390,6 @@ def exit():
sys.exit(0)
def fix_scaling(root):
"""Scale fonts on HiDPI displays."""
import tkinter.font
scaling = float(root.tk.call('tk', 'scaling'))
if scaling > 1.4:
for name in tkinter.font.names(root):
font = tkinter.font.Font(root=root, name=name, exists=True)
size = int(font['size'])
if size < 0:
font['size'] = round(-0.75*size)
def fixdoc(fun, text):
+33
View File
@@ -19,6 +19,20 @@ import sys
py_extensions = ('.py', '.pyw', '.pyi')
# fix_x functions seem only needed once per process.
def fix_scaling(root): # Called in filelist _test, pyshell, and run.
"""Scale fonts on HiDPI displays, once per process."""
import tkinter.font
scaling = float(root.tk.call('tk', 'scaling'))
if scaling > 1.4:
for name in tkinter.font.names(root):
font = tkinter.font.Font(root=root, name=name, exists=True)
size = int(font['size'])
if size < 0:
font['size'] = round(-0.75*size)
# Fix for HiDPI screens on Windows. CALL BEFORE ANY TK OPERATIONS!
# URL for arguments for the ...Awareness call below.
# https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
@@ -31,6 +45,25 @@ if sys.platform == 'win32': # pragma: no cover
except (ImportError, AttributeError, OSError):
pass
def fix_word_breaks(root): # Called in editor htest, filelist _test, pyshell.
# On Windows, tcl/tk breaks 'words' only on spaces, as in Command Prompt.
# We want Motif style everywhere. See #21474, msg218992 and followup.
tk = root.tk
tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded
tk.call('set', 'tcl_wordchars', r'\w')
tk.call('set', 'tcl_nonwordchars', r'\W')
def fix_x11_paste(root):
"Make paste replace selection on x11. See issue #5124."
if root._windowingsystem == 'x11':
for cls in 'Text', 'Entry', 'Spinbox':
root.bind_class(
cls,
'<<Paste>>',
'catch {%W delete sel.first sel.last}\n' +
root.bind_class(cls, '<<Paste>>'))
if __name__ == '__main__':
from unittest import main
@@ -0,0 +1,2 @@
Move functions run.fix_scaling, editor.fixwordbreaks (as fix_word_breaks)
and pyshell.fix_x11_paste to idlelib.util.