Skip to content

Commit b6ae32c

Browse files
[3.14] gh-152728: IDLE - move 3 toplevel fix_xyz functions to idlelb.util (GH-152729) (#152731)
gh-152728: IDLE - move 3 toplevel fix_xyz functions to idlelb.util (GH-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. (cherry picked from commit 53ca52d) Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
1 parent 51cacbe commit b6ae32c

9 files changed

Lines changed: 58 additions & 49 deletions

File tree

Lib/idlelib/News3.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ Released after 2025-10-07
44
=========================
55

66

7+
gh-152728: Move functions run.fix_scaling, editor.fixwordbreaks (as fix_word_breaks)
8+
and pyshell.fix_x11_paste to module util. Patch by Terry J. Reedy.
9+
710
gh-85320: IDLE now reads and writes its configuration files and the
811
breakpoints file using UTF-8 instead of the locale encoding.
912
Files with non-ASCII characters and non-UTF-8 encoding may need

Lib/idlelib/editor.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,19 +1685,10 @@ def get_accelerator(keydefs, eventname):
16851685
return s
16861686

16871687

1688-
def fixwordbreaks(root):
1689-
# On Windows, tcl/tk breaks 'words' only on spaces, as in Command Prompt.
1690-
# We want Motif style everywhere. See #21474, msg218992 and followup.
1691-
tk = root.tk
1692-
tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded
1693-
tk.call('set', 'tcl_wordchars', r'\w')
1694-
tk.call('set', 'tcl_nonwordchars', r'\W')
1695-
1696-
1697-
def _editor_window(parent): # htest #
1698-
# error if close master window first - timer event, after script
1699-
root = parent
1700-
fixwordbreaks(root)
1688+
def _editor_window(root): # htest #
1689+
# Error if close master window first - timer event, after script
1690+
from util import fix_word_breaks
1691+
fix_word_breaks(root)
17011692
if sys.argv[1:]:
17021693
filename = sys.argv[1]
17031694
else:

Lib/idlelib/filelist.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ def canonize(self, filename):
112112

113113

114114
def _test(): # TODO check and convert to htest
115+
# Maybe redundant with test_filelist.FileListTest.test_new_empty.
115116
from tkinter import Tk
116-
from idlelib.editor import fixwordbreaks
117-
from idlelib.run import fix_scaling
117+
from idlelib.util import fix_scaling, fix_word_breaks
118118
root = Tk()
119119
fix_scaling(root)
120-
fixwordbreaks(root)
120+
fix_word_breaks(root)
121121
root.withdraw()
122122
flist = FileList(root)
123123
flist.new()

Lib/idlelib/idle_test/test_editmenu.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import tkinter as tk
88
from tkinter import ttk
99
import unittest
10-
from idlelib import pyshell
10+
from idlelib.util import fix_x11_paste
1111

1212
class PasteTest(unittest.TestCase):
1313
'''Test pasting into widgets that allow pasting.
@@ -18,7 +18,7 @@ class PasteTest(unittest.TestCase):
1818
def setUpClass(cls):
1919
cls.root = root = tk.Tk()
2020
cls.root.withdraw()
21-
pyshell.fix_x11_paste(root)
21+
fix_x11_paste(root)
2222
cls.text = tk.Text(root)
2323
cls.entry = tk.Entry(root)
2424
cls.tentry = ttk.Entry(root)

Lib/idlelib/idle_test/test_sidebar.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@
1111
from idlelib.idle_test.tkinter_testing_utils import run_in_tk_mainloop
1212

1313
from idlelib.delegator import Delegator
14-
from idlelib.editor import fixwordbreaks
1514
from idlelib.percolator import Percolator
1615
import idlelib.pyshell
17-
from idlelib.pyshell import fix_x11_paste, PyShell, PyShellFileList
18-
from idlelib.run import fix_scaling
16+
from idlelib.pyshell import PyShell, PyShellFileList
17+
from idlelib.util import fix_scaling, fix_word_breaks, fix_x11_paste
1918
import idlelib.sidebar
2019
from idlelib.sidebar import get_end_linenumber, get_lineno
2120

@@ -403,7 +402,7 @@ def setUpClass(cls):
403402
root.withdraw()
404403

405404
fix_scaling(root)
406-
fixwordbreaks(root)
405+
fix_word_breaks(root)
407406
fix_x11_paste(root)
408407

409408
cls.flist = flist = PyShellFileList(root)

Lib/idlelib/pyshell.py

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,14 @@
3636
from idlelib.delegator import Delegator
3737
from idlelib import debugger
3838
from idlelib import debugger_r
39-
from idlelib.editor import EditorWindow, fixwordbreaks
39+
from idlelib.editor import EditorWindow
4040
from idlelib.filelist import FileList
4141
from idlelib.outwin import OutputWindow
4242
from idlelib import replace
4343
from idlelib import rpc
4444
from idlelib.run import idle_formatwarning, StdInputFile, StdOutputFile
4545
from idlelib.undo import UndoDelegator
46+
from idlelib.util import fix_word_breaks
4647

4748
# Default for testing; defaults to True in main() for running.
4849
use_subprocess = False
@@ -882,9 +883,9 @@ def __init__(self, flist=None):
882883
if ms[2][0] != "shell":
883884
ms.insert(2, ("shell", "She_ll"))
884885
self.interp = ModifiedInterpreter(self)
885-
if flist is None:
886+
if flist is None: # TODO possible? root and flist in main.
886887
root = Tk()
887-
fixwordbreaks(root)
888+
fix_word_breaks(root)
888889
root.withdraw()
889890
flist = PyShellFileList(root)
890891

@@ -1453,17 +1454,6 @@ def on_squeezed_expand(self, index, text, tags):
14531454
self.shell_sidebar.update_sidebar()
14541455

14551456

1456-
def fix_x11_paste(root):
1457-
"Make paste replace selection on x11. See issue #5124."
1458-
if root._windowingsystem == 'x11':
1459-
for cls in 'Text', 'Entry', 'Spinbox':
1460-
root.bind_class(
1461-
cls,
1462-
'<<Paste>>',
1463-
'catch {%W delete sel.first sel.last}\n' +
1464-
root.bind_class(cls, '<<Paste>>'))
1465-
1466-
14671457
usage_msg = """\
14681458
14691459
USAGE: idle [-deins] [-t title] [file]*
@@ -1523,6 +1513,7 @@ def main():
15231513
from platform import system
15241514
from idlelib import testing # bool value
15251515
from idlelib import macosx
1516+
from idlelib.util import fix_scaling, fix_x11_paste
15261517

15271518
global flist, root, use_subprocess
15281519

@@ -1608,7 +1599,6 @@ def main():
16081599
NoDefaultRoot()
16091600
root = Tk(className="Idle")
16101601
root.withdraw()
1611-
from idlelib.run import fix_scaling
16121602
fix_scaling(root)
16131603

16141604
# set application icon
@@ -1630,7 +1620,7 @@ def main():
16301620
root.wm_iconphoto(True, *icons)
16311621

16321622
# start editor and/or shell windows:
1633-
fixwordbreaks(root)
1623+
fix_word_breaks(root)
16341624
fix_x11_paste(root)
16351625
flist = PyShellFileList(root)
16361626
macosx.setupApp(root, flist)

Lib/idlelib/run.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from idlelib import iomenu # encoding
2626
from idlelib import rpc # multiple objects
2727
from idlelib import stackviewer # StackTreeItem
28+
from idlelib import util # fix_scaling
2829
import __main__
2930

3031
import tkinter # Use tcl and, if startup fails, messagebox.
@@ -216,7 +217,7 @@ def show_socket_error(err, address):
216217
import tkinter
217218
from tkinter.messagebox import showerror
218219
root = tkinter.Tk()
219-
fix_scaling(root)
220+
util.fix_scaling(root)
220221
root.withdraw()
221222
showerror(
222223
"Subprocess Connection Error",
@@ -326,16 +327,6 @@ def exit():
326327
sys.exit(0)
327328

328329

329-
def fix_scaling(root):
330-
"""Scale fonts on HiDPI displays."""
331-
import tkinter.font
332-
scaling = float(root.tk.call('tk', 'scaling'))
333-
if scaling > 1.4:
334-
for name in tkinter.font.names(root):
335-
font = tkinter.font.Font(root=root, name=name, exists=True)
336-
size = int(font['size'])
337-
if size < 0:
338-
font['size'] = round(-0.75*size)
339330

340331

341332
def fixdoc(fun, text):

Lib/idlelib/util.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@
1919
py_extensions = ('.py', '.pyw', '.pyi')
2020

2121

22+
# fix_x functions seem only needed once per process.
23+
24+
def fix_scaling(root): # Called in filelist _test, pyshell, and run.
25+
"""Scale fonts on HiDPI displays, once per process."""
26+
import tkinter.font
27+
scaling = float(root.tk.call('tk', 'scaling'))
28+
if scaling > 1.4:
29+
for name in tkinter.font.names(root):
30+
font = tkinter.font.Font(root=root, name=name, exists=True)
31+
size = int(font['size'])
32+
if size < 0:
33+
font['size'] = round(-0.75*size)
34+
35+
2236
# Fix for HiDPI screens on Windows. CALL BEFORE ANY TK OPERATIONS!
2337
# URL for arguments for the ...Awareness call below.
2438
# https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
@@ -31,6 +45,25 @@ def fix_win_hidpi(): # Called in pyshell and turtledemo.
3145
except (ImportError, AttributeError, OSError):
3246
pass
3347

48+
def fix_word_breaks(root): # Called in editor htest, filelist _test, pyshell.
49+
# On Windows, tcl/tk breaks 'words' only on spaces, as in Command Prompt.
50+
# We want Motif style everywhere. See #21474, msg218992 and followup.
51+
tk = root.tk
52+
tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded
53+
tk.call('set', 'tcl_wordchars', r'\w')
54+
tk.call('set', 'tcl_nonwordchars', r'\W')
55+
56+
57+
def fix_x11_paste(root):
58+
"Make paste replace selection on x11. See issue #5124."
59+
if root._windowingsystem == 'x11':
60+
for cls in 'Text', 'Entry', 'Spinbox':
61+
root.bind_class(
62+
cls,
63+
'<<Paste>>',
64+
'catch {%W delete sel.first sel.last}\n' +
65+
root.bind_class(cls, '<<Paste>>'))
66+
3467

3568
if __name__ == '__main__':
3669
from unittest import main
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Move functions run.fix_scaling, editor.fixwordbreaks (as fix_word_breaks)
2+
and pyshell.fix_x11_paste to idlelib.util.

0 commit comments

Comments
 (0)