Skip to content

Commit 44d46e3

Browse files
bpo-37325: Fix focus traversal for 2 IDLE dialogs (GH-14209)
Tab now moves focus across and down for Help Source and Custom Run. (cherry picked from commit 54cf2e0) Co-authored-by: Terry Jan Reedy <[email protected]>
1 parent c730211 commit 44d46e3

File tree

4 files changed

+42
-23
lines changed

4 files changed

+42
-23
lines changed

Lib/idlelib/NEWS.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ Released on 2019-06-24?
33
======================================
44

55

6+
bpo-37325: Fix tab focus traversal order for help source and custom
7+
run dialogs.
8+
69
bpo-37321: Both subprocess connection error messages now refer to
710
the 'Startup failure' section of the IDLE doc.
811

Lib/idlelib/idle_test/htest.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,11 @@ def _wrapper(parent): # htest #
110110

111111
CustomRun_spec = {
112112
'file': 'query',
113-
'kwds': {'title': 'Custom Run Args',
113+
'kwds': {'title': 'Customize query.py Run',
114114
'_htest': True},
115-
'msg': "Enter with <Return> or [Ok]. Print valid entry to Shell\n"
115+
'msg': "Enter with <Return> or [Run]. Print valid entry to Shell\n"
116116
"Arguments are parsed into a list\n"
117+
"Mode is currently restart True or False\n"
117118
"Close dialog with valid entry, <Escape>, [Cancel], [X]"
118119
}
119120

Lib/idlelib/query.py

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ class Query(Toplevel):
3636
"""
3737
def __init__(self, parent, title, message, *, text0='', used_names={},
3838
_htest=False, _utest=False):
39-
"""Create popup, do not return until tk widget destroyed.
39+
"""Create modal popup, return when destroyed.
4040
41-
Additional subclass init must be done before calling this
42-
unless _utest=True is passed to suppress wait_window().
41+
Additional subclass init must be done before this unless
42+
_utest=True is passed to suppress wait_window().
4343
4444
title - string, title of popup dialog
4545
message - string, informational message to display
@@ -48,15 +48,17 @@ def __init__(self, parent, title, message, *, text0='', used_names={},
4848
_htest - bool, change box location when running htest
4949
_utest - bool, leave window hidden and not modal
5050
"""
51-
Toplevel.__init__(self, parent)
52-
self.withdraw() # Hide while configuring, especially geometry.
53-
self.parent = parent
54-
self.title(title)
51+
self.parent = parent # Needed for Font call.
5552
self.message = message
5653
self.text0 = text0
5754
self.used_names = used_names
55+
56+
Toplevel.__init__(self, parent)
57+
self.withdraw() # Hide while configuring, especially geometry.
58+
self.title(title)
5859
self.transient(parent)
5960
self.grab_set()
61+
6062
windowingsystem = self.tk.call('tk', 'windowingsystem')
6163
if windowingsystem == 'aqua':
6264
try:
@@ -69,9 +71,9 @@ def __init__(self, parent, title, message, *, text0='', used_names={},
6971
self.protocol("WM_DELETE_WINDOW", self.cancel)
7072
self.bind('<Key-Return>', self.ok)
7173
self.bind("<KP_Enter>", self.ok)
72-
self.resizable(height=False, width=False)
74+
7375
self.create_widgets()
74-
self.update_idletasks() # Needed here for winfo_reqwidth below.
76+
self.update_idletasks() # Need here for winfo_reqwidth below.
7577
self.geometry( # Center dialog over parent (or below htest box).
7678
"+%d+%d" % (
7779
parent.winfo_rootx() +
@@ -80,12 +82,19 @@ def __init__(self, parent, title, message, *, text0='', used_names={},
8082
((parent.winfo_height()/2 - self.winfo_reqheight()/2)
8183
if not _htest else 150)
8284
) )
85+
self.resizable(height=False, width=False)
86+
8387
if not _utest:
8488
self.deiconify() # Unhide now that geometry set.
8589
self.wait_window()
8690

87-
def create_widgets(self, ok_text='OK'): # Call from override, if any.
88-
# Bind to self widgets needed for entry_ok or unittest.
91+
def create_widgets(self, ok_text='OK'): # Do not replace.
92+
"""Create entry (rows, extras, buttons.
93+
94+
Entry stuff on rows 0-2, spanning cols 0-2.
95+
Buttons on row 99, cols 1, 2.
96+
"""
97+
# Bind to self the widgets needed for entry_ok or unittest.
8998
self.frame = frame = Frame(self, padding=10)
9099
frame.grid(column=0, row=0, sticky='news')
91100
frame.grid_columnconfigure(0, weight=1)
@@ -99,19 +108,24 @@ def create_widgets(self, ok_text='OK'): # Call from override, if any.
99108
exists=True, root=self.parent)
100109
self.entry_error = Label(frame, text=' ', foreground='red',
101110
font=self.error_font)
102-
self.button_ok = Button(
103-
frame, text=ok_text, default='active', command=self.ok)
104-
self.button_cancel = Button(
105-
frame, text='Cancel', command=self.cancel)
106-
107111
entrylabel.grid(column=0, row=0, columnspan=3, padx=5, sticky=W)
108112
self.entry.grid(column=0, row=1, columnspan=3, padx=5, sticky=W+E,
109113
pady=[10,0])
110114
self.entry_error.grid(column=0, row=2, columnspan=3, padx=5,
111115
sticky=W+E)
116+
117+
self.create_extra()
118+
119+
self.button_ok = Button(
120+
frame, text=ok_text, default='active', command=self.ok)
121+
self.button_cancel = Button(
122+
frame, text='Cancel', command=self.cancel)
123+
112124
self.button_ok.grid(column=1, row=99, padx=5)
113125
self.button_cancel.grid(column=2, row=99, padx=5)
114126

127+
def create_extra(self): pass # Override to add widgets.
128+
115129
def showerror(self, message, widget=None):
116130
#self.bell(displayof=self)
117131
(widget or self.entry_error)['text'] = 'ERROR: ' + message
@@ -227,8 +241,8 @@ def __init__(self, parent, title, *, menuitem='', filepath='',
227241
parent, title, message, text0=menuitem,
228242
used_names=used_names, _htest=_htest, _utest=_utest)
229243

230-
def create_widgets(self):
231-
super().create_widgets()
244+
def create_extra(self):
245+
"Add path widjets to rows 10-12."
232246
frame = self.frame
233247
pathlabel = Label(frame, anchor='w', justify='left',
234248
text='Help File Path: Enter URL or browse for file')
@@ -319,16 +333,16 @@ def __init__(self, parent, title, *, cli_args='',
319333
parent, title, message, text0=cli_args,
320334
_htest=_htest, _utest=_utest)
321335

322-
def create_widgets(self):
323-
super().create_widgets(ok_text='Run')
336+
def create_extra(self):
337+
"Add run mode on rows 10-12."
324338
frame = self.frame
325339
self.restartvar = BooleanVar(self, value=True)
326340
restart = Checkbutton(frame, variable=self.restartvar, onvalue=True,
327341
offvalue=False, text='Restart shell')
328342
self.args_error = Label(frame, text=' ', foreground='red',
329343
font=self.error_font)
330344

331-
restart.grid(column=0, row=4, columnspan=3, padx=5, sticky='w')
345+
restart.grid(column=0, row=10, columnspan=3, padx=5, sticky='w')
332346
self.args_error.grid(column=0, row=12, columnspan=3, padx=5,
333347
sticky='we')
334348

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix tab focus traversal order for help source and custom run dialogs.

0 commit comments

Comments
 (0)