From d40ddf40730cec044a11c8da6b545ff8d718d019 Mon Sep 17 00:00:00 2001 From: GeeTransit Date: Wed, 21 Aug 2019 16:37:02 -0400 Subject: [PATCH 01/13] bpo-37902: IDLE: Add scrolling for IDLE browsers. --- Lib/idlelib/NEWS.txt | 2 + Lib/idlelib/tree.py | 38 +++++++++++++++++++ .../2019-08-21-16-02-49.bpo-37902._R_adE.rst | 1 + 3 files changed, 41 insertions(+) create mode 100644 Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 45918cf36b4193..1947e36cc7acba 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-10-20? ====================================== +bpo-37902: Add scrolling for IDLE browsers. + bpo-37849: Fix completions list appearing too high or low when shown above the current line. diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py index 21426cbb33e0da..ef27655b3cd37a 100644 --- a/Lib/idlelib/tree.py +++ b/Lib/idlelib/tree.py @@ -260,8 +260,20 @@ def drawtext(self): anchor="nw", window=self.label) self.label.bind("<1>", self.select_or_edit) self.label.bind("", self.flip) + self.label.bind("", self.mousescroll) + self.label.bind("", self.mousescroll) + self.label.bind("", self.mousescroll) self.text_id = id + def mousescroll(self, event): + up = { + EventType.MouseWheel: event.delta > 0, + EventType.Button: event.num == 4, + } + lines = (-5 if up[event.type] else 5) + self.canvas.yview_scroll(lines, "units") + return "break" + def select_or_edit(self, event=None): if self.selected and self.item.IsEditable(): self.edit(event) @@ -410,42 +422,68 @@ def GetSubList(self): # A canvas widget with scroll bars and some useful bindings class ScrolledCanvas: + def __init__(self, master, **opts): if 'yscrollincrement' not in opts: opts['yscrollincrement'] = 17 + self.master = master + self.frame = Frame(master) self.frame.rowconfigure(0, weight=1) self.frame.columnconfigure(0, weight=1) + self.canvas = Canvas(self.frame, **opts) self.canvas.grid(row=0, column=0, sticky="nsew") + self.vbar = Scrollbar(self.frame, name="vbar") self.vbar.grid(row=0, column=1, sticky="nse") self.hbar = Scrollbar(self.frame, name="hbar", orient="horizontal") self.hbar.grid(row=1, column=0, sticky="ews") + self.canvas['yscrollcommand'] = self.vbar.set self.vbar['command'] = self.canvas.yview self.canvas['xscrollcommand'] = self.hbar.set self.hbar['command'] = self.canvas.xview + self.canvas.bind("", self.page_up) self.canvas.bind("", self.page_down) self.canvas.bind("", self.unit_up) self.canvas.bind("", self.unit_down) + + self.canvas.bind("", self.mousescroll) + self.canvas.bind("", self.mousescroll) + self.canvas.bind("", self.mousescroll) + #if isinstance(master, Toplevel) or isinstance(master, Tk): self.canvas.bind("", self.zoom_height) self.canvas.focus_set() + def page_up(self, event): self.canvas.yview_scroll(-1, "page") return "break" + def page_down(self, event): self.canvas.yview_scroll(1, "page") return "break" + def unit_up(self, event): self.canvas.yview_scroll(-1, "unit") return "break" + def unit_down(self, event): self.canvas.yview_scroll(1, "unit") return "break" + + def mousescroll(self, event): + up = { + EventType.MouseWheel: event.delta > 0, + EventType.Button: event.num == 4, + } + lines = (-5 if up[event.type] else 5) + self.canvas.yview_scroll(lines, "units") + return "break" + def zoom_height(self, event): zoomheight.zoom_height(self.master) return "break" diff --git a/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst b/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst new file mode 100644 index 00000000000000..03966b433b7e40 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst @@ -0,0 +1 @@ +Add scrolling for IDLE browsers. From c86f487b92217097cf835e9c07acfd4809e54352 Mon Sep 17 00:00:00 2001 From: GeeTransit Date: Wed, 21 Aug 2019 18:09:57 -0400 Subject: [PATCH 02/13] Update Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst Co-Authored-By: Terry Jan Reedy --- Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst b/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst index 03966b433b7e40..c21d94a4cd3b67 100644 --- a/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst +++ b/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst @@ -1 +1 @@ -Add scrolling for IDLE browsers. +Add mousewheel scrolling for IDLE class, path, and stack browsers. From ad7bb287c47b4e84403afa35c643464b882d6d48 Mon Sep 17 00:00:00 2001 From: GeeTransit Date: Wed, 21 Aug 2019 18:15:05 -0400 Subject: [PATCH 03/13] Update NEWS.txt --- Lib/idlelib/NEWS.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 1947e36cc7acba..45918cf36b4193 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,8 +3,6 @@ Released on 2019-10-20? ====================================== -bpo-37902: Add scrolling for IDLE browsers. - bpo-37849: Fix completions list appearing too high or low when shown above the current line. From d1bf4d95e1798ee652c80312b14789353a2ca54e Mon Sep 17 00:00:00 2001 From: GeeTransit Date: Thu, 22 Aug 2019 12:18:33 -0400 Subject: [PATCH 04/13] Refactor code using handlescroll and added tests. --- Lib/idlelib/editor.py | 24 ++------- Lib/idlelib/idle_test/test_multicall.py | 8 +++ Lib/idlelib/idle_test/test_tree.py | 29 ++++++++++- Lib/idlelib/tree.py | 68 +++++++++++-------------- 4 files changed, 71 insertions(+), 58 deletions(-) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 35027da76bce2f..9cf230f07724b8 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -60,6 +60,7 @@ class EditorWindow(object): from idlelib.parenmatch import ParenMatch from idlelib.squeezer import Squeezer from idlelib.zoomheight import ZoomHeight + from idlelib.tree import handlescroll filesystemencoding = sys.getfilesystemencoding() # for file names help_url = None @@ -151,9 +152,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): else: # Elsewhere, use right-click for popup menus. text.bind("<3>",self.right_menu_event) - text.bind('', self.mousescroll) - text.bind('', self.mousescroll) - text.bind('', self.mousescroll) + text.bind('', handlescroll) + text.bind('', handlescroll) + text.bind('', handlescroll) text.bind("<>", self.cut) text.bind("<>", self.copy) text.bind("<>", self.paste) @@ -484,23 +485,6 @@ def handle_yview(self, event, *args): self.text.yview(event, *args) return 'break' - def mousescroll(self, event): - """Handle scrollwheel event. - - For wheel up, event.delta = 120*n on Windows, -1*n on darwin, - where n can be > 1 if one scrolls fast. Flicking the wheel - generates up to maybe 20 events with n up to 10 or more 1. - Macs use wheel down (delta = 1*n) to scroll up, so positive - delta means to scroll up on both systems. - - X-11 sends Control-Button-4 event instead. - """ - up = {EventType.MouseWheel: event.delta > 0, - EventType.Button: event.num == 4} - lines = -5 if up[event.type] else 5 - self.text.yview_scroll(lines, 'units') - return 'break' - rmenu = None def right_menu_event(self, event): diff --git a/Lib/idlelib/idle_test/test_multicall.py b/Lib/idlelib/idle_test/test_multicall.py index 68156a743d7b9b..121c5400e2d143 100644 --- a/Lib/idlelib/idle_test/test_multicall.py +++ b/Lib/idlelib/idle_test/test_multicall.py @@ -35,6 +35,14 @@ def test_init(self): mctext = self.mc(self.root) self.assertIsInstance(mctext._MultiCall__binders, list) + def test_yview(self): + # Added for tree.handlescroll + # (it depends on yview to not be overriden) + mc = self.mc + self.assertIs(mc.yview, Text.yview) + mctext = self.mc(self.root) + self.assertIs(mctext.yview.__func__, Text.yview) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_tree.py b/Lib/idlelib/idle_test/test_tree.py index 9be9abee361f08..c92799c5a77886 100644 --- a/Lib/idlelib/idle_test/test_tree.py +++ b/Lib/idlelib/idle_test/test_tree.py @@ -4,7 +4,7 @@ import unittest from test.support import requires requires('gui') -from tkinter import Tk +from tkinter import Tk, EventType class TreeTest(unittest.TestCase): @@ -29,5 +29,32 @@ def test_init(self): node.expand() +class TestHandleScroll(unittest.TestCase): + + def test_handlescroll(self): + # Fake widget class containing `yview` only. + class _Widget: + def __init__(widget, *expected): + widget.expected = expected + def yview(widget, *args): + self.assertTupleEqual(widget.expected, args) + # Fake event class + class _Event: + pass + # (type, delta, num, amount) + tests = ((EventType.MouseWheel, 120, -1, -5), + (EventType.MouseWheel, -120, -1, 5), + (EventType.ButtonPress, -1, 4, -5), + (EventType.ButtonPress, -1, 5, 5)) + + event = _Event() + for ty, delta, num, amount in tests: + event.type = ty + event.delta = delta + event.num = num + res = tree.handlescroll(event, _Widget(SCROLL, amount, "units")) + test.assertEqual(res, "break") + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py index ef27655b3cd37a..dec0bb9b535c50 100644 --- a/Lib/idlelib/tree.py +++ b/Lib/idlelib/tree.py @@ -56,6 +56,31 @@ def listicons(icondir=ICONDIR): column = 0 root.images = images +def handlescroll(event, widget=None): + """Handle scrollwheel event. + + For wheel up, event.delta = 120*n on Windows, -1*n on darwin, + where n can be > 1 if one scrolls fast. Flicking the wheel + generates up to maybe 20 events with n up to 10 or more 1. + Macs use wheel down (delta = 1*n) to scroll up, so positive + delta means to scroll up on both systems. + + X-11 sends Control-Button-4 event instead. + + If widget is passed as an argument, its yview command will be + called (instead of event.widget's). + + This function depends on widget.yview to not be overridden by + a subclass. + """ + up = {EventType.MouseWheel: event.delta > 0, + EventType.ButtonPress: event.num == 4} + lines = (-5 if up[event.type] else 5) + if widget is None: + widget = event.widget + widget.yview(SCROLL, lines, 'units') + return 'break' + class TreeNode: @@ -260,20 +285,11 @@ def drawtext(self): anchor="nw", window=self.label) self.label.bind("<1>", self.select_or_edit) self.label.bind("", self.flip) - self.label.bind("", self.mousescroll) - self.label.bind("", self.mousescroll) - self.label.bind("", self.mousescroll) + self.label.bind("", lambda e: handlescroll(e, self.canvas)) + self.label.bind("", lambda e: handlescroll(e, self.canvas)) + self.label.bind("", lambda e: handlescroll(e, self.canvas)) self.text_id = id - def mousescroll(self, event): - up = { - EventType.MouseWheel: event.delta > 0, - EventType.Button: event.num == 4, - } - lines = (-5 if up[event.type] else 5) - self.canvas.yview_scroll(lines, "units") - return "break" - def select_or_edit(self, event=None): if self.selected and self.item.IsEditable(): self.edit(event) @@ -426,64 +442,42 @@ class ScrolledCanvas: def __init__(self, master, **opts): if 'yscrollincrement' not in opts: opts['yscrollincrement'] = 17 - self.master = master - self.frame = Frame(master) self.frame.rowconfigure(0, weight=1) self.frame.columnconfigure(0, weight=1) - self.canvas = Canvas(self.frame, **opts) self.canvas.grid(row=0, column=0, sticky="nsew") - self.vbar = Scrollbar(self.frame, name="vbar") self.vbar.grid(row=0, column=1, sticky="nse") self.hbar = Scrollbar(self.frame, name="hbar", orient="horizontal") self.hbar.grid(row=1, column=0, sticky="ews") - self.canvas['yscrollcommand'] = self.vbar.set self.vbar['command'] = self.canvas.yview self.canvas['xscrollcommand'] = self.hbar.set self.hbar['command'] = self.canvas.xview - self.canvas.bind("", self.page_up) self.canvas.bind("", self.page_down) self.canvas.bind("", self.unit_up) self.canvas.bind("", self.unit_down) - - self.canvas.bind("", self.mousescroll) - self.canvas.bind("", self.mousescroll) - self.canvas.bind("", self.mousescroll) - + self.canvas.bind("", handlescroll) + self.canvas.bind("", handlescroll) + self.canvas.bind("", handlescroll) #if isinstance(master, Toplevel) or isinstance(master, Tk): self.canvas.bind("", self.zoom_height) self.canvas.focus_set() - def page_up(self, event): self.canvas.yview_scroll(-1, "page") return "break" - def page_down(self, event): self.canvas.yview_scroll(1, "page") return "break" - def unit_up(self, event): self.canvas.yview_scroll(-1, "unit") return "break" - def unit_down(self, event): self.canvas.yview_scroll(1, "unit") return "break" - - def mousescroll(self, event): - up = { - EventType.MouseWheel: event.delta > 0, - EventType.Button: event.num == 4, - } - lines = (-5 if up[event.type] else 5) - self.canvas.yview_scroll(lines, "units") - return "break" - def zoom_height(self, event): zoomheight.zoom_height(self.master) return "break" From eadc45e6949249126016ed4a0c92fabfe01fbed7 Mon Sep 17 00:00:00 2001 From: GeeTransit Date: Thu, 22 Aug 2019 12:27:50 -0400 Subject: [PATCH 05/13] Make news more specific. --- Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst b/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst index c21d94a4cd3b67..e17390c6c19adb 100644 --- a/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst +++ b/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst @@ -1 +1 @@ -Add mousewheel scrolling for IDLE class, path, and stack browsers. +Add mousewheel scrolling for IDLE module, path, and stack browsers. From c4fb9af0e88c888ff75921ba004a433ab14bc6ed Mon Sep 17 00:00:00 2001 From: GeeTransit Date: Thu, 22 Aug 2019 13:01:16 -0400 Subject: [PATCH 06/13] Fix missing variables and namespace issues. --- Lib/idlelib/editor.py | 6 +++--- Lib/idlelib/idle_test/test_tree.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 9cf230f07724b8..e671c6c38b26ae 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -152,9 +152,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): else: # Elsewhere, use right-click for popup menus. text.bind("<3>",self.right_menu_event) - text.bind('', handlescroll) - text.bind('', handlescroll) - text.bind('', handlescroll) + text.bind('', self.handlescroll) + text.bind('', self.handlescroll) + text.bind('', self.handlescroll) text.bind("<>", self.cut) text.bind("<>", self.copy) text.bind("<>", self.paste) diff --git a/Lib/idlelib/idle_test/test_tree.py b/Lib/idlelib/idle_test/test_tree.py index c92799c5a77886..c44f4128bcc532 100644 --- a/Lib/idlelib/idle_test/test_tree.py +++ b/Lib/idlelib/idle_test/test_tree.py @@ -4,7 +4,7 @@ import unittest from test.support import requires requires('gui') -from tkinter import Tk, EventType +from tkinter import Tk, EventType, SCROLL class TreeTest(unittest.TestCase): From dd7044e46124a0f626fce6bee5b1a65a7359d409 Mon Sep 17 00:00:00 2001 From: GeeTransit Date: Thu, 22 Aug 2019 13:27:46 -0400 Subject: [PATCH 07/13] Fix name error. --- Lib/idlelib/idle_test/test_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/idle_test/test_tree.py b/Lib/idlelib/idle_test/test_tree.py index c44f4128bcc532..f25208e3be3e09 100644 --- a/Lib/idlelib/idle_test/test_tree.py +++ b/Lib/idlelib/idle_test/test_tree.py @@ -53,7 +53,7 @@ class _Event: event.delta = delta event.num = num res = tree.handlescroll(event, _Widget(SCROLL, amount, "units")) - test.assertEqual(res, "break") + self.assertEqual(res, "break") if __name__ == '__main__': From b59f103941c40abd934df62f55220c1f8089454f Mon Sep 17 00:00:00 2001 From: GeeTransit Date: Thu, 22 Aug 2019 14:46:24 -0400 Subject: [PATCH 08/13] Rename handlescroll to wheel_event --- Lib/idlelib/editor.py | 8 ++++---- Lib/idlelib/idle_test/test_multicall.py | 2 +- Lib/idlelib/idle_test/test_tree.py | 6 +++--- Lib/idlelib/tree.py | 14 +++++++------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index e671c6c38b26ae..defd56b1dcc3c9 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -60,7 +60,7 @@ class EditorWindow(object): from idlelib.parenmatch import ParenMatch from idlelib.squeezer import Squeezer from idlelib.zoomheight import ZoomHeight - from idlelib.tree import handlescroll + from idlelib.tree import wheel_event filesystemencoding = sys.getfilesystemencoding() # for file names help_url = None @@ -152,9 +152,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): else: # Elsewhere, use right-click for popup menus. text.bind("<3>",self.right_menu_event) - text.bind('', self.handlescroll) - text.bind('', self.handlescroll) - text.bind('', self.handlescroll) + text.bind('', self.wheel_event) + text.bind('', self.wheel_event) + text.bind('', self.wheel_event) text.bind("<>", self.cut) text.bind("<>", self.copy) text.bind("<>", self.paste) diff --git a/Lib/idlelib/idle_test/test_multicall.py b/Lib/idlelib/idle_test/test_multicall.py index 121c5400e2d143..ba582bb3ca51b4 100644 --- a/Lib/idlelib/idle_test/test_multicall.py +++ b/Lib/idlelib/idle_test/test_multicall.py @@ -36,7 +36,7 @@ def test_init(self): self.assertIsInstance(mctext._MultiCall__binders, list) def test_yview(self): - # Added for tree.handlescroll + # Added for tree.wheel_event # (it depends on yview to not be overriden) mc = self.mc self.assertIs(mc.yview, Text.yview) diff --git a/Lib/idlelib/idle_test/test_tree.py b/Lib/idlelib/idle_test/test_tree.py index f25208e3be3e09..b3e4c10cf9e38e 100644 --- a/Lib/idlelib/idle_test/test_tree.py +++ b/Lib/idlelib/idle_test/test_tree.py @@ -29,9 +29,9 @@ def test_init(self): node.expand() -class TestHandleScroll(unittest.TestCase): +class TestScrollEvent(unittest.TestCase): - def test_handlescroll(self): + def test_wheel_event(self): # Fake widget class containing `yview` only. class _Widget: def __init__(widget, *expected): @@ -52,7 +52,7 @@ class _Event: event.type = ty event.delta = delta event.num = num - res = tree.handlescroll(event, _Widget(SCROLL, amount, "units")) + res = tree.wheel_event(event, _Widget(SCROLL, amount, "units")) self.assertEqual(res, "break") diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py index dec0bb9b535c50..c4e6ea50262b76 100644 --- a/Lib/idlelib/tree.py +++ b/Lib/idlelib/tree.py @@ -56,7 +56,7 @@ def listicons(icondir=ICONDIR): column = 0 root.images = images -def handlescroll(event, widget=None): +def wheel_event(event, widget=None): """Handle scrollwheel event. For wheel up, event.delta = 120*n on Windows, -1*n on darwin, @@ -285,9 +285,9 @@ def drawtext(self): anchor="nw", window=self.label) self.label.bind("<1>", self.select_or_edit) self.label.bind("", self.flip) - self.label.bind("", lambda e: handlescroll(e, self.canvas)) - self.label.bind("", lambda e: handlescroll(e, self.canvas)) - self.label.bind("", lambda e: handlescroll(e, self.canvas)) + self.label.bind("", lambda e: wheel_event(e, self.canvas)) + self.label.bind("", lambda e: wheel_event(e, self.canvas)) + self.label.bind("", lambda e: wheel_event(e, self.canvas)) self.text_id = id def select_or_edit(self, event=None): @@ -460,9 +460,9 @@ def __init__(self, master, **opts): self.canvas.bind("", self.page_down) self.canvas.bind("", self.unit_up) self.canvas.bind("", self.unit_down) - self.canvas.bind("", handlescroll) - self.canvas.bind("", handlescroll) - self.canvas.bind("", handlescroll) + self.canvas.bind("", wheel_event) + self.canvas.bind("", wheel_event) + self.canvas.bind("", wheel_event) #if isinstance(master, Toplevel) or isinstance(master, Tk): self.canvas.bind("", self.zoom_height) self.canvas.focus_set() From c2359b4a97da61844f1ab068ee5822c667a1f674 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 4 Sep 2019 18:20:00 -0400 Subject: [PATCH 09/13] Add back 'self' mistakenly removed in conflit resolution. --- Lib/idlelib/editor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index f029c460fa37ff..9d1276883f5d04 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -153,9 +153,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): # Elsewhere, use right-click for popup menus. text.bind("<3>",self.right_menu_event) - text.bind('', wheel_event) - text.bind('', wheel_event) - text.bind('', wheel_event) + text.bind('', self.wheel_event) + text.bind('', self.wheel_event) + text.bind('', self.wheel_event) text.bind('', self.handle_winconfig) text.bind("<>", self.cut) text.bind("<>", self.copy) From 516664aad2d77237cf9363b9c6dbb7bb939c2f4e Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 4 Sep 2019 19:33:29 -0400 Subject: [PATCH 10/13] Move wheel_event import in editor. --- Lib/idlelib/editor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 9d1276883f5d04..5cbf704ab27b6a 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -26,6 +26,7 @@ from idlelib import query from idlelib import replace from idlelib import search +from idlelib.tree import wheel_event from idlelib import window # The default tab setting for a Text widget, in average-width characters. @@ -61,7 +62,6 @@ class EditorWindow(object): from idlelib.parenmatch import ParenMatch from idlelib.squeezer import Squeezer from idlelib.zoomheight import ZoomHeight - from idlelib.tree import wheel_event filesystemencoding = sys.getfilesystemencoding() # for file names help_url = None @@ -153,9 +153,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): # Elsewhere, use right-click for popup menus. text.bind("<3>",self.right_menu_event) - text.bind('', self.wheel_event) - text.bind('', self.wheel_event) - text.bind('', self.wheel_event) + text.bind('', wheel_event) + text.bind('', wheel_event) + text.bind('', wheel_event) text.bind('', self.handle_winconfig) text.bind("<>", self.cut) text.bind("<>", self.copy) From 5550395e039f6b5a5f98641effcf86582fe04ef2 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 4 Sep 2019 19:36:39 -0400 Subject: [PATCH 11/13] Tweak wheel_event. --- Lib/idlelib/tree.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py index c4e6ea50262b76..6229be4e5a8ad5 100644 --- a/Lib/idlelib/tree.py +++ b/Lib/idlelib/tree.py @@ -65,19 +65,18 @@ def wheel_event(event, widget=None): Macs use wheel down (delta = 1*n) to scroll up, so positive delta means to scroll up on both systems. - X-11 sends Control-Button-4 event instead. + X-11 sends Control-Button-4,5 events instead. - If widget is passed as an argument, its yview command will be - called (instead of event.widget's). + The widget parameter is needed so browser label bindings can pass + the underlying canvas. This function depends on widget.yview to not be overridden by a subclass. """ up = {EventType.MouseWheel: event.delta > 0, EventType.ButtonPress: event.num == 4} - lines = (-5 if up[event.type] else 5) - if widget is None: - widget = event.widget + lines = -5 if up[event.type] else 5 + widget = event.widget if widget is None else widget widget.yview(SCROLL, lines, 'units') return 'break' From bb2892ee44212c895bd7f79d4110f762a7abcf04 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 4 Sep 2019 21:07:52 -0400 Subject: [PATCH 12/13] News items. --- Lib/idlelib/NEWS.txt | 3 +++ Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst | 1 + 2 files changed, 4 insertions(+) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 47c2291d237727..c9e846a6fba667 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2019-10-20? ====================================== +bpo-37092: Add mousewheel scrolling for IDLE module, path, and stack +browsers. Patch by George Zhang. + bpo-35771: To avoid occasional spurious test_idle failures on slower machines, increase the ``hover_delay`` in test_tooltip. diff --git a/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst b/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst index e17390c6c19adb..24b4142484695c 100644 --- a/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst +++ b/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst @@ -1 +1,2 @@ Add mousewheel scrolling for IDLE module, path, and stack browsers. +Patch by George Zhang. From 0b1118b999c29d0dbca1c5e013eb9d8dd3dbcac0 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 4 Sep 2019 21:11:30 -0400 Subject: [PATCH 13/13] Add ACKS entry. --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index ce8b144900ebc0..ce427b8222ed5b 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1871,6 +1871,7 @@ Nickolai Zeldovich Yuxiao Zeng Uwe Zessin Cheng Zhang +George Zhang Kai Zhu Tarek Ziadé Jelle Zijlstra