[Python-checkins] bpo-37325: Fix focus traversal for 2 IDLE dialogs (#14209)

Terry Jan Reedy webhook-mailer at python.org
Tue Jun 18 17:08:29 EDT 2019


https://github.com/python/cpython/commit/54cf2e0780ca137dd9abea5d3d974578ce0c18a9
commit: 54cf2e0780ca137dd9abea5d3d974578ce0c18a9
branch: master
author: Terry Jan Reedy <tjreedy at udel.edu>
committer: GitHub <noreply at github.com>
date: 2019-06-18T17:08:24-04:00
summary:

bpo-37325: Fix focus traversal for 2 IDLE dialogs (#14209)

Tab now moves focus across and down for Help Source and Custom Run.

files:
A Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst
M Lib/idlelib/NEWS.txt
M Lib/idlelib/idle_test/htest.py
M Lib/idlelib/query.py

diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index 64636df957e4..689539e73c12 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -3,6 +3,9 @@ Released on 2019-10-20?
 ======================================
 
 
+bpo-37325: Fix tab focus traversal order for help source and custom
+run dialogs.
+
 bpo-37321: Both subprocess connection error messages now refer to
 the 'Startup failure' section of the IDLE doc.
 
diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py
index 6ce8cc8a5f60..20e5e9014ee7 100644
--- a/Lib/idlelib/idle_test/htest.py
+++ b/Lib/idlelib/idle_test/htest.py
@@ -110,10 +110,11 @@ def _wrapper(parent):  # htest #
 
 CustomRun_spec = {
     'file': 'query',
-    'kwds': {'title': 'Custom Run Args',
+    'kwds': {'title': 'Customize query.py Run',
              '_htest': True},
-    'msg': "Enter with <Return> or [Ok].  Print valid entry to Shell\n"
+    'msg': "Enter with <Return> or [Run].  Print valid entry to Shell\n"
            "Arguments are parsed into a list\n"
+           "Mode is currently restart True or False\n"
            "Close dialog with valid entry, <Escape>, [Cancel], [X]"
     }
 
diff --git a/Lib/idlelib/query.py b/Lib/idlelib/query.py
index 9b3bb1d186b8..d74084feed76 100644
--- a/Lib/idlelib/query.py
+++ b/Lib/idlelib/query.py
@@ -36,10 +36,10 @@ class Query(Toplevel):
     """
     def __init__(self, parent, title, message, *, text0='', used_names={},
                  _htest=False, _utest=False):
-        """Create popup, do not return until tk widget destroyed.
+        """Create modal popup, return when destroyed.
 
-        Additional subclass init must be done before calling this
-        unless  _utest=True is passed to suppress wait_window().
+        Additional subclass init must be done before this unless
+        _utest=True is passed to suppress wait_window().
 
         title - string, title of popup dialog
         message - string, informational message to display
@@ -48,15 +48,17 @@ def __init__(self, parent, title, message, *, text0='', used_names={},
         _htest - bool, change box location when running htest
         _utest - bool, leave window hidden and not modal
         """
-        Toplevel.__init__(self, parent)
-        self.withdraw()  # Hide while configuring, especially geometry.
-        self.parent = parent
-        self.title(title)
+        self.parent = parent  # Needed for Font call.
         self.message = message
         self.text0 = text0
         self.used_names = used_names
+
+        Toplevel.__init__(self, parent)
+        self.withdraw()  # Hide while configuring, especially geometry.
+        self.title(title)
         self.transient(parent)
         self.grab_set()
+
         windowingsystem = self.tk.call('tk', 'windowingsystem')
         if windowingsystem == 'aqua':
             try:
@@ -69,9 +71,9 @@ def __init__(self, parent, title, message, *, text0='', used_names={},
         self.protocol("WM_DELETE_WINDOW", self.cancel)
         self.bind('<Key-Return>', self.ok)
         self.bind("<KP_Enter>", self.ok)
-        self.resizable(height=False, width=False)
+
         self.create_widgets()
-        self.update_idletasks()  # Needed here for winfo_reqwidth below.
+        self.update_idletasks()  # Need here for winfo_reqwidth below.
         self.geometry(  # Center dialog over parent (or below htest box).
                 "+%d+%d" % (
                     parent.winfo_rootx() +
@@ -80,12 +82,19 @@ def __init__(self, parent, title, message, *, text0='', used_names={},
                     ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
                     if not _htest else 150)
                 ) )
+        self.resizable(height=False, width=False)
+
         if not _utest:
             self.deiconify()  # Unhide now that geometry set.
             self.wait_window()
 
-    def create_widgets(self, ok_text='OK'):  # Call from override, if any.
-        # Bind to self widgets needed for entry_ok or unittest.
+    def create_widgets(self, ok_text='OK'):  # Do not replace.
+        """Create entry (rows, extras, buttons.
+
+        Entry stuff on rows 0-2, spanning cols 0-2.
+        Buttons on row 99, cols 1, 2.
+        """
+        # Bind to self the widgets needed for entry_ok or unittest.
         self.frame = frame = Frame(self, padding=10)
         frame.grid(column=0, row=0, sticky='news')
         frame.grid_columnconfigure(0, weight=1)
@@ -99,19 +108,24 @@ def create_widgets(self, ok_text='OK'):  # Call from override, if any.
                                exists=True, root=self.parent)
         self.entry_error = Label(frame, text=' ', foreground='red',
                                  font=self.error_font)
-        self.button_ok = Button(
-                frame, text=ok_text, default='active', command=self.ok)
-        self.button_cancel = Button(
-                frame, text='Cancel', command=self.cancel)
-
         entrylabel.grid(column=0, row=0, columnspan=3, padx=5, sticky=W)
         self.entry.grid(column=0, row=1, columnspan=3, padx=5, sticky=W+E,
                         pady=[10,0])
         self.entry_error.grid(column=0, row=2, columnspan=3, padx=5,
                               sticky=W+E)
+
+        self.create_extra()
+
+        self.button_ok = Button(
+                frame, text=ok_text, default='active', command=self.ok)
+        self.button_cancel = Button(
+                frame, text='Cancel', command=self.cancel)
+
         self.button_ok.grid(column=1, row=99, padx=5)
         self.button_cancel.grid(column=2, row=99, padx=5)
 
+    def create_extra(self): pass  # Override to add widgets.
+
     def showerror(self, message, widget=None):
         #self.bell(displayof=self)
         (widget or self.entry_error)['text'] = 'ERROR: ' + message
@@ -227,8 +241,8 @@ def __init__(self, parent, title, *, menuitem='', filepath='',
                 parent, title, message, text0=menuitem,
                 used_names=used_names, _htest=_htest, _utest=_utest)
 
-    def create_widgets(self):
-        super().create_widgets()
+    def create_extra(self):
+        "Add path widjets to rows 10-12."
         frame = self.frame
         pathlabel = Label(frame, anchor='w', justify='left',
                           text='Help File Path: Enter URL or browse for file')
@@ -319,8 +333,8 @@ def __init__(self, parent, title, *, cli_args='',
                 parent, title, message, text0=cli_args,
                 _htest=_htest, _utest=_utest)
 
-    def create_widgets(self):
-        super().create_widgets(ok_text='Run')
+    def create_extra(self):
+        "Add run mode on rows 10-12."
         frame = self.frame
         self.restartvar = BooleanVar(self, value=True)
         restart = Checkbutton(frame, variable=self.restartvar, onvalue=True,
@@ -328,7 +342,7 @@ def create_widgets(self):
         self.args_error = Label(frame, text=' ', foreground='red',
                                 font=self.error_font)
 
-        restart.grid(column=0, row=4, columnspan=3, padx=5, sticky='w')
+        restart.grid(column=0, row=10, columnspan=3, padx=5, sticky='w')
         self.args_error.grid(column=0, row=12, columnspan=3, padx=5,
                              sticky='we')
 
diff --git a/Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst b/Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst
new file mode 100644
index 000000000000..edfffbefe884
--- /dev/null
+++ b/Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst
@@ -0,0 +1 @@
+Fix tab focus traversal order for help source and custom run dialogs.



More information about the Python-checkins mailing list