Skip to content

Commit cfc12ec

Browse files
bpo-33664: Scroll IDLE editor text by lines (GH-7351)
Previously, the mouse wheel and scrollbar slider moved text by a fixed number of pixels, resulting in partial lines at the top of the editor box. The change also applies to the shell and grep output windows, but not to read-only text views. (cherry picked from commit d49dbd9) Co-authored-by: Cheryl Sabella <[email protected]>
1 parent 1d3395f commit cfc12ec

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

Lib/idlelib/editor.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
# The default tab setting for a Text widget, in average-width characters.
3131
TK_TABWIDTH_DEFAULT = 8
3232
_py_version = ' (%s)' % platform.python_version()
33+
darwin = sys.platform == 'darwin'
3334

3435
def _sphinx_version():
3536
"Format sys.version_info to produce the Sphinx version string used to install the chm docs"
@@ -49,7 +50,7 @@ class EditorWindow(object):
4950
from idlelib.undo import UndoDelegator
5051
from idlelib.iomenu import IOBinding, encoding
5152
from idlelib import mainmenu
52-
from tkinter import Toplevel
53+
from tkinter import Toplevel, EventType
5354
from idlelib.statusbar import MultiStatusBar
5455
from idlelib.autocomplete import AutoComplete
5556
from idlelib.autoexpand import AutoExpand
@@ -147,6 +148,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None):
147148
else:
148149
# Elsewhere, use right-click for popup menus.
149150
text.bind("<3>",self.right_menu_event)
151+
text.bind('<MouseWheel>', self.mousescroll)
152+
text.bind('<Button-4>', self.mousescroll)
153+
text.bind('<Button-5>', self.mousescroll)
150154
text.bind("<<cut>>", self.cut)
151155
text.bind("<<copy>>", self.copy)
152156
text.bind("<<paste>>", self.paste)
@@ -193,7 +197,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None):
193197
text.bind("<<open-turtle-demo>>", self.open_turtle_demo)
194198

195199
self.set_status_bar()
196-
vbar['command'] = text.yview
200+
vbar['command'] = self.handle_yview
197201
vbar.pack(side=RIGHT, fill=Y)
198202
text['yscrollcommand'] = vbar.set
199203
text['font'] = idleConf.GetFont(self.root, 'main', 'EditorWindow')
@@ -441,6 +445,27 @@ def postwindowsmenu(self):
441445
menu.delete(self.wmenu_end+1, end)
442446
windows.add_windows_to_menu(menu)
443447

448+
def handle_yview(self, event, *args):
449+
"Handle scrollbar."
450+
if event == 'moveto':
451+
fraction = float(args[0])
452+
lines = (round(self.getlineno('end') * fraction) -
453+
self.getlineno('@0,0'))
454+
event = 'scroll'
455+
args = (lines, 'units')
456+
self.text.yview(event, *args)
457+
return 'break'
458+
459+
def mousescroll(self, event):
460+
"Handle scroll wheel."
461+
up = {EventType.MouseWheel: event.delta >= 0 == darwin,
462+
EventType.Button: event.num == 4}
463+
lines = 5
464+
if up[event.type]:
465+
lines = -lines
466+
self.text.yview_scroll(lines, 'units')
467+
return 'break'
468+
444469
rmenu = None
445470

446471
def right_menu_event(self, event):
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Scroll IDLE editor text by lines.
2+
Previously, the mouse wheel and scrollbar slider moved text by a fixed
3+
number of pixels, resulting in partial lines at the top of the editor
4+
box. The change also applies to the shell and grep output windows,
5+
but not to read-only text views.

0 commit comments

Comments
 (0)