-
-
Notifications
You must be signed in to change notification settings - Fork 35k
gh-154511: IDLE - Update mousewheel event handling #154512
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,52 @@ | ||
| """Test util, coverage 100%""" | ||
| """Test util, coverage %""" | ||
|
|
||
| import unittest | ||
| from idlelib import util | ||
| from test.support import requires | ||
| requires('gui') | ||
| from idlelib import util # Creates root and widget. | ||
|
|
||
|
|
||
| class UtilTest(unittest.TestCase): | ||
| def test_extensions(self): | ||
| for extension in {'.pyi', '.py', '.pyw'}: | ||
| self.assertIn(extension, util.py_extensions) | ||
|
|
||
| class ScrollTest(unittest.TestCase): | ||
|
|
||
| @classmethod | ||
| def setUpClass(cls): | ||
| cls.orig_x11 = util.x11_buttons | ||
|
|
||
| @classmethod | ||
| def tearDownClass(cls): | ||
| util.x11_buttons = cls.orig_x11 | ||
|
|
||
| def test_wheel_event(self): | ||
| # Fake widget class containing `yview` only. | ||
| class _Widget: | ||
| def yview(widget, scroll, lines, units): | ||
| self.assertTupleEqual((scroll, lines, units), | ||
| ('scroll', widget.lines, 'units')) | ||
| # Fake event class | ||
| class _Event: | ||
| pass | ||
|
|
||
| event = _Event() | ||
| event.widget = widget = _Widget() | ||
| tests = ((False, 120, -5), | ||
| (False, -120, 5), | ||
| (True, 4, -5), | ||
| (True, 5, 5)) | ||
| for x11, value, lines in tests: | ||
| util.x11_buttons = x11 | ||
| event.delta, event.num = (None, value) if x11 else (value, None) | ||
| widget.lines = lines | ||
| self.assertEqual(util.wheel_event(event), "break") | ||
|
|
||
| (widget2 := _Widget()).lines = widget.lines | ||
| widget.lines = 0 # Make assert fail if widget.yview called. | ||
| util.wheel_event(event, widget2) # Test delagation to passed widget. | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| unittest.main(verbosity=2) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,13 +13,14 @@ | |
| * warning stuff (pyshell, run). | ||
| """ | ||
| import sys | ||
| import tkinter # This module requires gui to run (import). | ||
|
|
||
| # .pyw is for Windows; .pyi is for typing stub files. | ||
| # The extension order is needed for iomenu open/save dialogs. | ||
| py_extensions = ('.py', '.pyw', '.pyi') | ||
|
|
||
|
|
||
| # fix_x functions seem only needed once per process. | ||
| # fix_x functions seem needed only once per process. | ||
|
|
||
| def fix_scaling(root): # Called in filelist _test, pyshell, and run. | ||
| """Scale fonts on HiDPI displays, once per process.""" | ||
|
|
@@ -45,6 +46,7 @@ def fix_win_hidpi(): # Called in pyshell and turtledemo. | |
| 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. | ||
|
|
@@ -65,6 +67,36 @@ def fix_x11_paste(root): | |
| root.bind_class(cls, '<<Paste>>')) | ||
|
|
||
|
|
||
| # On X11, Tk 8.6- signals mouse wheel rotations with <Button-4> and | ||
| # <Button-5> events. With 8.7+, it generates <Mousewheel events | ||
| # as on other systems. Used here, editor, tree, and test_sidebar. | ||
| root = tkinter.Tk() # Use this as process root? | ||
| root.withdraw() | ||
| x11_buttons = root._windowingsystem == 'x11' and tkinter.TkVersion <= 8.6 | ||
| root.destroy() | ||
|
Comment on lines
+73
to
+76
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Simply do not make it a global variable. If you want to share a code, make it a function that takes a widget as argument.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which? x11_buttons is just False/True. Creating root at top level is a standard idiom for non-class tkinter code. Is tcl/tk broken on macOS? I'm not sure I understand the second sentence. Are you suggesting something like below? A function makes no sense to me since the windowing system does not depend on the widget, so it seems sensible to cache it (which, I just read, tkinter does).
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The lines above run fine from IDLE editor or Terminal on macOS 10.5 with 3.15.0b4. In Shell, the second line fails with "AttributeError: _windowingsystem property ... has no setter", which is odd since the line does not set.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The issue is with creation of the root at import time. |
||
|
|
||
| def wheel_event(event, widget=None): # Bound in editor and tree. | ||
| """Handle scrollwheel event. | ||
|
|
||
| For MouseWheel up events, event.delta is generally= 120*n, but -1*n | ||
| on darwin (or just Aqua?), where n can be > 1 if one scrolls fast. | ||
| Macs use wheel down (delta = 1*n) to scroll up, so positive | ||
| delta means to scroll up on both systems. | ||
|
|
||
| When x11_buttons is True, Button-4,5 events signal up and down. | ||
|
|
||
| The widget parameter is needed in tree so browser events can be | ||
| passed to the underlying canvas vertical scrollbar. If tree is | ||
| replaced by ttk.Treeview, 'widget' can go. | ||
| """ | ||
| up = event.num == 4 if x11_buttons else event.delta > 0 | ||
| # The following works, though +-4*n might be more standard, | ||
| lines = -5 if up else 5 | ||
| widget = event.widget if widget is None else widget | ||
| widget.yview('scroll', lines, 'units') | ||
| return 'break' | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| from unittest import main | ||
| main('idlelib.idle_test.test_util', verbosity=2) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These 5 lines of code are repeated. What if instead of sharing the
x11_buttonsconstant, share thebind_wheel()function?