Skip to content
Open
Show file tree
Hide file tree
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
54 changes: 54 additions & 0 deletions docs/keyboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,60 @@ divided using commas. For example, the shortcut `Ctrl + Alt + x, x` is
activated by holding control, alt, and x at the same time, releasing all keys,
and then hitting the x key again by itself.

## Control + Shift Key Bindings

The default key bindings using control and shift for most commands, to avoid
conflicting with entering international characters in some keyboard layouts.

| Keys | Command |
| ---- | ------- |
| Ctrl + Shift + a | addCommand |
| Ctrl + Shift + b | addCommandToBeginning |
| Ctrl + Shift + e | addCommandToEnd |
| Ctrl + Shift + d | deleteCurrentStep |
| Ctrl + Shift + i | announceScene |
| < | decreaseProgramSpeed |
| > | increaseProgramSpeed |
| Ctrl + Shift + p | playPauseProgram |
| Ctrl + Shift + r | refreshScene |
| ? | showHide |
| Ctrl + Shift + s | stopProgram |
| Ctrl + Shift + x, a, b, 1 | selectBackward1 |
| Ctrl + Shift + x, a, b, 2 | selectBackward2 |
| Ctrl + Shift + x, a, b, 3 | selectBackward3 |
| Ctrl + Shift + x, a, f, 1 | selectForward1 |
| Ctrl + Shift + x, a, f, 2 | selectForward2 |
| Ctrl + Shift + x, a, f, 3 | selectForward3 |
| Ctrl + Shift + x, a, l, 1 | selectLeft45 |
| Ctrl + Shift + x, a, l, 2 | selectLeft90 |
| Ctrl + Shift + x, a, l, 3 | selectLeft180 |
| Ctrl + Shift + x, a, r, 1 | selectRight45 |
| Ctrl + Shift + x, a, r, 2 | selectRight90 |
| Ctrl + Shift + x, a, r, 3 | selectRight180 |
| Ctrl + Shift + x, c, m, d | moveCharacterDown |
| Ctrl + Shift + x, c, m, l | moveCharacterLeft |
| Ctrl + Shift + x, c, m, r | moveCharacterRight |
| Ctrl + Shift + x, c, m, u | moveCharacterUp |
| Ctrl + Shift + x, c, t, l | turnCharacterLeft |
| Ctrl + Shift + x, c, t, r | turnCharacterRight |
| Ctrl + Shift + x, d | deleteAll |
| Ctrl + Shift + x, f, a | focusActions |
| Ctrl + Shift + x, f, c | focusCharacterPositionControls |
| Ctrl + Shift + x, f, h | focusAppHeader |
| Ctrl + Shift + x, f, p | focusPlayShare |
| Ctrl + Shift + x, f, q | focusProgramSequence |
| Ctrl + Shift + x, f, s | focusScene |
| Ctrl + Shift + x, f, t | focusAddNodeToggle |
| Ctrl + Shift + x, f, w | focusWorldSelector |
| Ctrl + Shift + x, f, x | focusCharacterColumnInput |
| Ctrl + Shift + x, f, y | focusCharacterRowInput |
| Ctrl + Shift + x, t, 1 | changeToDefaultTheme |
| Ctrl + Shift + x, t, 2 | changeToLightTheme |
| Ctrl + Shift + x, t, 3 | changeToDarkTheme |
| Ctrl + Shift + x, t, 4 | changeToGrayscaleTheme |
| Ctrl + Shift + x, t, 5 | changeToHighContrastTheme |
| Ctrl + Shift + x, x | toggleFeedbackAnnouncements |

## Control+Alt (Apple: Control+Option) Key Bindings

NVDA has many commands that make use of the alt key, to avoid conflicting with
Expand Down
2 changes: 1 addition & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ export class App extends React.Component<AppProps, AppState> {
showWorldSelector: false,
showShareModal: false,
showActionsSimplificationMenu: false,
keyboardInputSchemeName: "controlalt"
keyboardInputSchemeName: "controlshift"
};

// For FakeRobotDriver, replace with:
Expand Down
13 changes: 7 additions & 6 deletions src/App.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,24 @@ it('Should be able to handle escaping out of a sequence', () => {

app.setState({ keyBindingsEnabled: true});

expect(app.state().announcementsEnabled).toBe(true);
expect(app.state().settings.theme).toBe("default");

const sequenceWithEscape = [
new KeyboardEvent('keydown', { code: "KeyX", ctrlKey: true, altKey: true }),
new KeyboardEvent('keydown', { code: "KeyA" }),
new KeyboardEvent('keydown', { code: "KeyX", ctrlKey: true, shiftKey: true }),
new KeyboardEvent('keydown', { code: "KeyA", ctrlKey: true, shiftKey: true }),
// At this point our sequence of (Ctrl+Alt+x, a) matches the beginning
// part of the 'select action' group of sequences.
// Sending an Escape will break us out of the in-progress sequence.
new KeyboardEvent('keydown', { key: "Escape" }),
// So that we can send the key sequence to toggle the announcements
new KeyboardEvent('keydown', { code: "KeyX", ctrlKey: true, altKey: true }),
new KeyboardEvent('keydown', { code: "KeyX" }),
new KeyboardEvent('keydown', { code: "KeyX", ctrlKey: true, shiftKey: true }),
new KeyboardEvent('keydown', { code: "KeyT", ctrlKey: true, shiftKey: true }),
new KeyboardEvent('keydown', { key: "5", ctrlKey: true, shiftKey: true })
];

for (const keyboardEvent of sequenceWithEscape) {
window.document.dispatchEvent(keyboardEvent);
}

expect(app.state().announcementsEnabled).toBe(false);
expect(app.state().settings.theme).toBe("contrast");
});
14 changes: 14 additions & 0 deletions src/KeyboardInputModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ class KeyboardInputModal extends React.Component<KeyboardInputModalProps, Keyboa
{singleKeyString}
</div>);

if (keyDef.shiftKey) {
const shiftKeyLabel = this.props.intl.formatMessage(
{ id: "KeyboardInputModal.KeyLabels.Shift" }
);
labelKeySegments.unshift(shiftKeyLabel);

const shiftKeyIcon = this.props.intl.formatMessage(
{ id: "KeyboardInputModal.KeyIcons.Shift" }
);
icons.unshift(<div key="shift-modifier" className="KeyboardInputModal__binding__icon">
{shiftKeyIcon}
</div>);
}

if (keyDef.altKey) {
const altKeyLabel = this.props.intl.formatMessage(
{ id: "KeyboardInputModal.KeyLabels.Alt" }
Expand Down
4 changes: 2 additions & 2 deletions src/KeyboardInputModal.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function createShallowKeyboardInputModal(props) {

const defaultWrapperProps = {
keyBindingsEnabled: true,
keyboardInputSchemeName: "controlalt",
keyboardInputSchemeName: "controlshift",
onChangeKeyBindingsEnabled: onChangeKeyBindingsEnabled,
onChangeKeyboardInputScheme: onChangeKeyboardInputScheme,
onHide: onHide,
Expand Down Expand Up @@ -100,7 +100,7 @@ it('should be able to cancel changes.', () => {
expect(wrappedModal.state.keyBindingsEnabled).toBe(false);

wrappedModal.cancelChanges();
expect(wrappedModal.state.keyboardInputSchemeName).toBe("controlalt");
expect(wrappedModal.state.keyboardInputSchemeName).toBe("controlshift");
expect(wrappedModal.state.keyBindingsEnabled).toBe(true);

expect(onChangeKeyBindingsEnabled.mock.calls.length).toBe(0);
Expand Down
Loading