diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 8e15319b5baab2..1d5e181f42f764 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -34,6 +34,10 @@ TK_TABWIDTH_DEFAULT = 8 darwin = sys.platform == 'darwin' +# A letter keysym in a key sequence, such as "s" in "". +_letter_key_re = re.compile(r'(?<=-Key-)[a-zA-Z](?=>)') + + class EditorWindow: is_shell = False # PyShell overrides. from idlelib.percolator import Percolator @@ -1186,6 +1190,12 @@ def apply_bindings(self, keydefs=None): for event, keylist in keydefs.items(): if keylist: text.event_add(event, *keylist) + # Caps Lock changes the case of letter keysyms, so bind + # the sequences with the other case too (gh-56596). + for keys in keylist: + other = _letter_key_re.sub(lambda m: m[0].swapcase(), keys) + if other not in keylist: + text.event_add(event, other) def fill_menus(self, menudefs=None, keydefs=None): """Fill in dropdown menus used by this window. diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py index e32981091b72a6..2aaeb5037901b8 100644 --- a/Lib/idlelib/idle_test/test_editor.py +++ b/Lib/idlelib/idle_test/test_editor.py @@ -31,6 +31,26 @@ def test_init(self): self.assertEqual(e.root, self.root) e._close() + def test_apply_bindings_caps_lock(self): + # gh-56596: Caps Lock changes the case of letter keysyms, so the + # sequences are bound with both cases. + e = Editor(root=self.root) + try: + e.apply_bindings({'<>': ('', ''), + '<>': ('',), + '<>': ('', '')}) + self.assertEqual(set(e.text.event_info('<>')), + {'', '', + ''}) + # Existing variants are not added again. + self.assertEqual(e.text.event_info('<>'), + ('', '')) + self.assertEqual(set(e.text.event_info('<>')), + {'', + ''}) + finally: + e._close() + def test_set_width_zero_char_width(self): # A zero-width '0' must not raise ZeroDivisionError (gh-90304). e = Editor(root=self.root) diff --git a/Misc/NEWS.d/next/IDLE/2026-09-17-23-00-00.gh-issue-56596.capslock.rst b/Misc/NEWS.d/next/IDLE/2026-09-17-23-00-00.gh-issue-56596.capslock.rst new file mode 100644 index 00000000000000..70878e4f801263 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2026-09-17-23-00-00.gh-issue-56596.capslock.rst @@ -0,0 +1,2 @@ +Make IDLE keyboard shortcuts with ascii letters work when Caps Lock is on even when only one +of the upper and lowercase versions are defined.