Skip to content

Tools Boards menu scroll updates for accessibility #9168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 26, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions app/src/processing/app/tools/MenuScroller.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*/
package processing.app.tools;

import processing.app.PreferencesData;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
Expand Down Expand Up @@ -567,6 +569,43 @@ public MenuScrollTimer(final int increment, int interval) {
public void actionPerformed(ActionEvent e) {
firstIndex += increment * accelerator;
refreshMenu();
if (PreferencesData.getBoolean("ide.accessible")) {
// If the user has chosen to use accessibility features, it means that they are using a screen reader
// to assist them in development of their project. This scroller is very unfriendly toward screen readers
// because it does not tell the user that it is scrolling through the board options, and it does not read
// the name of the boards as they scroll by. It is possible that the desired board will never become
// accessible.
// Because this scroller is quite nice for the sighted user, the idea here is to continue to use the
// scroller, but to fool it into scrolling one item at a time for accessible features users so that the
// screen readers work well, too.
// It's not the prettiest of code, but it works.
String itemClassName;
int keyEvent;

// The blind user likely used an arrow key to get to the scroller. Determine which arrow key
// so we can send an event for the opposite arrow key. This fools the scroller into scrolling
// a single item. Get the class name of the new item while we're here
if (increment > 0) {
itemClassName = menuItems[firstIndex + scrollCount - 1].getClass().getName();
keyEvent = KeyEvent.VK_UP;
}
else {
itemClassName = menuItems[firstIndex].getClass().getName();
keyEvent = KeyEvent.VK_DOWN;
}

// Use the class name to check if the next item is a separator. If it is, just let it scroll on like
// normal, otherwise move the cursor back with the opposite key event to the new item so that item is read
// by a screen reader and the user can use their arrow keys to navigate the list one item at a time
if (!itemClassName.equals(JSeparator.class.getName()) ) {
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
Component comp = manager.getFocusOwner();
KeyEvent event = new KeyEvent(comp,
KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0,
keyEvent, KeyEvent.CHAR_UNDEFINED);
comp.dispatchEvent(event);
}
}
}
});
}
Expand Down