Skip to content

Commit d94c679

Browse files
committed
Correct button, text widget and entry bugs in accessibility
2 parents a12234e + 3f35fda commit d94c679

2 files changed

Lines changed: 34 additions & 10 deletions

File tree

library/accessibility.tcl

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,27 @@ if {[info commands ::tk::accessible::check_screenreader] eq "" || [::tk::accessi
200200
}
201201

202202
# Core binding tag (shared by text, entry, ttk::entry).
203-
bind KeyCaptureTag <KeyPress> {+::tk::accessible::_handle_keypress %W %K}
203+
bind KeyCaptureTag <KeyPress> {+::tk::accessible::_handle_keypress %W %K %s}
204204
bind KeyCaptureTag <KeyRelease-space> {+ after 10 [list ::tk::accessible::_get_prev_word %W]}
205205

206+
# Bitmask of modifier flags (from the %s state field) that indicate
207+
# a keyboard shortcut/chord rather than literal text entry. %K does
208+
# not encode modifiers, so a Control-a or Command-a (Select All)
209+
# keypress still reports the keysym "a" - without this check it
210+
# would be treated as if the user had typed the letter "a",
211+
# clobbering the accessible value and racing with the real
212+
# <<SelectAll>> handling that runs later on the class bindtag.
213+
# 0x4 = Control
214+
# 0x8 = Mod1/Alt (X11); Option on aqua
215+
# 0x10 = Mod2 (varies)
216+
# 0x40 = Mod4 (often Super/Windows key)
217+
# 0x8 = Command on aqua is reported via Mod1 in Tk's state field
218+
variable modifierMask [expr {0x4 | 0x8 | 0x10 | 0x40}]
219+
206220
# Handle each keypress event.
207-
proc _handle_keypress {w key} {
221+
proc _handle_keypress {w key state} {
222+
variable modifierMask
223+
208224
# Ignore modifier keys and non-printables
209225
if {$key eq "" || [string length $key] > 1} {
210226
return
@@ -215,6 +231,13 @@ if {[info commands ::tk::accessible::check_screenreader] eq "" || [::tk::accessi
215231
return
216232
}
217233

234+
# Ignore keystrokes that are part of a modifier chord (e.g.
235+
# Control-a / Command-a for Select All) - these are shortcuts,
236+
# not typed text, and must not overwrite the accessible value.
237+
if {$state & $modifierMask} {
238+
return
239+
}
240+
218241
# Otherwise emit single-character updates.
219242
::tk::accessible::set_acc_value $w $key
220243
if {[tk windowingsystem] eq "x11"} {
@@ -416,6 +439,7 @@ if {[info commands ::tk::accessible::check_screenreader] eq "" || [::tk::accessi
416439
if {[winfo class $w] eq "Text"} {
417440
set data [::tk::accessible::_gettext $w]
418441
::tk::accessible::set_acc_value $w $data
442+
::tk::accessible::emit_selection_change $w
419443
if {[tk windowingsystem] eq "x11"} {
420444
::tk::accessible::speak $data
421445
}
@@ -618,7 +642,7 @@ if {[info commands ::tk::accessible::check_screenreader] eq "" || [::tk::accessi
618642
# Check to make sure window is not destroyed.
619643
if {[winfo exists $w]} {
620644
if {[tk windowingsystem] eq "aqua"} {
621-
if {[winfo class $w] in {Scale TScale Spinbox TSpinbox Listbox Treeview TProgressbar}} {
645+
if {[winfo class $w] in {Entry TEntry TCombobox Scale TScale Spinbox TSpinbox Listbox Treeview TProgressbar}} {
622646
if {[focus] ne $w} {
623647
focus -force $w
624648
}
@@ -1140,10 +1164,6 @@ if {[info commands ::tk::accessible::check_screenreader] eq "" || [::tk::accessi
11401164
bind TCheckbutton <<Invoke>> {+after idle [list ::tk::accessible::_announce_button_state %W]}
11411165
bind Toggleswitch <<Invoke>> {+after idle [list ::tk::accessible::_announce_button_state %W]}
11421166

1143-
# Entry widgets - announce content on focus
1144-
bind Entry <FocusIn> {+::tk::accessible::_updateselection %W}
1145-
bind TEntry <FocusIn> {+::tk::accessible::_updateselection %W}
1146-
11471167
# Other X11 focus bindings
11481168
bind Listbox <FocusIn> {+::tk::accessible::_updateselection %W}
11491169
bind Treeview <FocusIn> {+::tk::accessible::_updateselection %W}
@@ -1209,10 +1229,8 @@ if {[info commands ::tk::accessible::check_screenreader] eq "" || [::tk::accessi
12091229
bind TNotebook <<NotebookTabChanged>> {+::tk::accessible::_updateselection %W}
12101230

12111231
# Capture text selection in entry widgets.
1212-
bind Entry <KeyPress> {+::tk::accessible::_updateselection %W}
1213-
bind TEntry <KeyPress> {+::tk::accessible::_updateselection %W}
12141232
bind Entry <FocusIn> {+::tk::accessible::_updateselection %W}
1215-
bind TEntry <FocusIn> {+::tk::accessible::_updateselection %W}
1233+
bind TEntry <FocusIn> {+::tk::accessible::_updateselection %W}
12161234
bind Entry <<SelectAll>> {+::tk::accessible::_updateselection %W}
12171235
bind TEntry <<SelectAll>> {+::tk::accessible::_updateselection %W}
12181236

macosx/tkMacOSXAccessibility.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,12 @@ void PostAccessibilityAnnouncement(NSString *message)
362362
return value;
363363
}
364364

365+
/* Return label for buttons. */
366+
if (role && CFStringCompare(role, kAXButtonRole, 0) == kCFCompareEqualTo) {
367+
NSString *value = self.accessibilityLabel;
368+
return value;
369+
}
370+
365371
Tk_Window win = self.tk_win;
366372
if (!win) {
367373
return @"";

0 commit comments

Comments
 (0)