From 9c2844927d15b2d3e21b28d62249dead02b5b597 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 13 Nov 2019 00:13:33 -0700 Subject: bpo-4630: Add cursor no-blink option for IDLE (GH-16960) This immediately toggles shell, editor, and output windows, but does not affect other input widgets. --- Lib/idlelib/NEWS.txt | 6 +++++- Lib/idlelib/config-main.def | 1 + Lib/idlelib/config.py | 2 ++ Lib/idlelib/configdialog.py | 17 +++++++++++++++++ Lib/idlelib/editor.py | 16 ++++++++++++++++ Lib/idlelib/idle_test/test_configdialog.py | 4 ++++ .../next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst | 3 +++ 7 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 938c9c7..b02a988 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,7 +3,11 @@ Released on 2020-10-05? ====================================== -bop-26353: Stop adding newline when saving an IDLE shell window. +bpo-4360: Add an option to toggle IDLE's cursor blink for shell, +editor, and output windows. See Settings, General, Window Preferences, +Cursor Blink. Patch by Zachary Spytz. + +bpo-26353: Stop adding newline when saving an IDLE shell window. bpo-38598: Do not try to compile IDLE shell or output windows. diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def index b2be625..28ae941 100644 --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -59,6 +59,7 @@ delete-exitfunc= 1 [EditorWindow] width= 80 height= 40 +cursor-blink= 1 font= TkFixedFont # For TkFixedFont, the actual size and boldness are obtained from tk # and override 10 and 0. See idlelib.config.IdleConf.GetFont diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 12e6f9f..04444a3 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -158,6 +158,8 @@ class IdleConf: self.defaultCfg = {} self.userCfg = {} self.cfg = {} # TODO use to select userCfg vs defaultCfg + # self.blink_off_time = ['insertofftime'] + # See https:/bugs.python.org/issue4630, msg356516. if not _utest: self.CreateConfigHandlers() diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index df21658..aaf319b 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -236,6 +236,7 @@ class ConfigDialog(Toplevel): instance.set_notabs_indentwidth() instance.ApplyKeybindings() instance.reset_help_menu_entries() + instance.update_cursor_blink() for klass in reloadables: klass.reload() @@ -1820,6 +1821,9 @@ class GenPage(Frame): (*)win_width_int: Entry - win_width win_height_title: Label (*)win_height_int: Entry - win_height + frame_cursor_blink: Frame + cursor_blink_title: Label + (*)cursor_blink_bool: Checkbutton - cursor_blink frame_autocomplete: Frame auto_wait_title: Label (*)auto_wait_int: Entry - autocomplete_wait @@ -1864,6 +1868,8 @@ class GenPage(Frame): StringVar(self), ('main', 'EditorWindow', 'width')) self.win_height = tracers.add( StringVar(self), ('main', 'EditorWindow', 'height')) + self.cursor_blink = tracers.add( + BooleanVar(self), ('main', 'EditorWindow', 'cursor-blink')) self.autocomplete_wait = tracers.add( StringVar(self), ('extensions', 'AutoComplete', 'popupwait')) self.paren_style = tracers.add( @@ -1920,6 +1926,11 @@ class GenPage(Frame): validatecommand=self.digits_only, validate='key', ) + frame_cursor_blink = Frame(frame_window, borderwidth=0) + cursor_blink_title = Label(frame_cursor_blink, text='Cursor Blink') + self.cursor_blink_bool = Checkbutton(frame_cursor_blink, + variable=self.cursor_blink, width=1) + frame_autocomplete = Frame(frame_window, borderwidth=0,) auto_wait_title = Label(frame_autocomplete, text='Completions Popup Wait (milliseconds)') @@ -2024,6 +2035,10 @@ class GenPage(Frame): win_height_title.pack(side=RIGHT, anchor=E, pady=5) self.win_width_int.pack(side=RIGHT, anchor=E, padx=10, pady=5) win_width_title.pack(side=RIGHT, anchor=E, pady=5) + # frame_cursor_blink. + frame_cursor_blink.pack(side=TOP, padx=5, pady=0, fill=X) + cursor_blink_title.pack(side=LEFT, anchor=W, padx=5, pady=5) + self.cursor_blink_bool.pack(side=LEFT, padx=5, pady=5) # frame_autocomplete. frame_autocomplete.pack(side=TOP, padx=5, pady=0, fill=X) auto_wait_title.pack(side=LEFT, anchor=W, padx=5, pady=5) @@ -2078,6 +2093,8 @@ class GenPage(Frame): 'main', 'EditorWindow', 'width', type='int')) self.win_height.set(idleConf.GetOption( 'main', 'EditorWindow', 'height', type='int')) + self.cursor_blink.set(idleConf.GetOption( + 'main', 'EditorWindow', 'cursor-blink', type='bool')) self.autocomplete_wait.set(idleConf.GetOption( 'extensions', 'AutoComplete', 'popupwait', type='int')) self.paren_style.set(idleConf.GetOption( diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index adeed74..dff104f 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -241,6 +241,12 @@ class EditorWindow(object): self.indentwidth = self.tabwidth self.set_notabs_indentwidth() + # Store the current value of the insertofftime now so we can restore + # it if needed. + if not hasattr(idleConf, 'blink_off_time'): + idleConf.blink_off_time = self.text['insertofftime'] + self.update_cursor_blink() + # When searching backwards for a reliable place to begin parsing, # first start num_context_lines[0] lines back, then # num_context_lines[1] lines back if that didn't work, and so on. @@ -803,6 +809,16 @@ class EditorWindow(object): text.mark_set("insert", pos + "+1c") text.see(pos) + def update_cursor_blink(self): + "Update the cursor blink configuration." + cursorblink = idleConf.GetOption( + 'main', 'EditorWindow', 'cursor-blink', type='bool') + if not cursorblink: + self.text['insertofftime'] = 0 + else: + # Restore the original value + self.text['insertofftime'] = idleConf.blink_off_time + def ResetFont(self): "Update the text widgets' font if it is changed" # Called from configdialog.py diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 37e8343..1f14ed1 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -1135,6 +1135,10 @@ class GenPageTest(unittest.TestCase): d.win_width_int.insert(0, '11') self.assertEqual(mainpage, {'EditorWindow': {'width': '11'}}) + def test_cursor_blink(self): + self.page.cursor_blink_bool.invoke() + self.assertEqual(mainpage, {'EditorWindow': {'cursor-blink': 'False'}}) + def test_autocomplete_wait(self): self.page.auto_wait_int.delete(0, 'end') self.page.auto_wait_int.insert(0, '11') diff --git a/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst b/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst new file mode 100644 index 0000000..759b35b --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst @@ -0,0 +1,3 @@ +Add an option to toggle IDLE's cursor blink for shell, editor, and output +windows. See Settings, General, Window Preferences, Cursor Blink. +Patch by Zachary Spytz. -- cgit v0.12