Reset master to testing content
This commit is contained in:
1 parent
0f2587b719
commit
42afa2a56c
1483 files changed
+145308
-938069
No files matched your search
@@ -0,0 +1,479 @@
|
||||
package input
|
||||
|
||||
import "time"
|
||||
|
||||
// Command is a semantic request; native callbacks never execute application work.
|
||||
type Command string
|
||||
|
||||
const (
|
||||
SelectPreviousSpeechSetting Command = "select-previous-speech-setting"
|
||||
SelectNextSpeechSetting Command = "select-next-speech-setting"
|
||||
DecreaseSpeechSetting Command = "decrease-speech-setting"
|
||||
IncreaseSpeechSetting Command = "increase-speech-setting"
|
||||
SaveSpeechSettings Command = "save-speech-settings"
|
||||
PresentTime Command = "present-time"
|
||||
PresentDate Command = "present-date"
|
||||
PresentClipboard Command = "present-clipboard"
|
||||
PresentCurrentLine Command = "present-current-line"
|
||||
SpellCurrentLine Command = "spell-current-line"
|
||||
PhoneticCurrentLine Command = "phonetic-current-line"
|
||||
ShowSpeechHistory Command = "show-speech-history"
|
||||
ToggleSpeechMonitor Command = "toggle-speech-monitor"
|
||||
CycleSpeechMode Command = "cycle-speech-mode"
|
||||
CycleProgressBarOutput Command = "cycle-progress-bar-output"
|
||||
PresentVersion Command = "present-version"
|
||||
ToggleLearnMode Command = "toggle-learn-mode"
|
||||
ShowActions Command = "show-actions"
|
||||
InternalUIKey Command = "internal-ui-key"
|
||||
InternalUIDismiss Command = "internal-ui-dismiss"
|
||||
LearnKey Command = "learn-key"
|
||||
LearnDocumentation Command = "learn-documentation"
|
||||
LearnDefaultShortcuts Command = "learn-default-shortcuts"
|
||||
LearnApplicationShortcuts Command = "learn-application-shortcuts"
|
||||
StickyFocusMode Command = "sticky-focus-mode"
|
||||
StickyBrowseMode Command = "sticky-browse-mode"
|
||||
ToggleDocumentMode Command = "toggle-document-mode"
|
||||
DocumentNextHeading Command = "document-next-heading"
|
||||
DocumentPreviousHeading Command = "document-previous-heading"
|
||||
DocumentNextLink Command = "document-next-link"
|
||||
DocumentPreviousLink Command = "document-previous-link"
|
||||
DocumentNextButton Command = "document-next-button"
|
||||
DocumentPreviousButton Command = "document-previous-button"
|
||||
DocumentNextCheckBox Command = "document-next-check-box"
|
||||
DocumentPreviousCheckBox Command = "document-previous-check-box"
|
||||
DocumentNextList Command = "document-next-list"
|
||||
DocumentPreviousList Command = "document-previous-list"
|
||||
DocumentNextSeparator Command = "document-next-separator"
|
||||
DocumentPreviousSeparator Command = "document-previous-separator"
|
||||
DocumentNextHeadingAtLevel1 Command = "document-next-heading-at-level-1"
|
||||
DocumentPreviousHeadingAtLevel1 Command = "document-previous-heading-at-level-1"
|
||||
DocumentNextHeadingAtLevel2 Command = "document-next-heading-at-level-2"
|
||||
DocumentPreviousHeadingAtLevel2 Command = "document-previous-heading-at-level-2"
|
||||
DocumentNextHeadingAtLevel3 Command = "document-next-heading-at-level-3"
|
||||
DocumentPreviousHeadingAtLevel3 Command = "document-previous-heading-at-level-3"
|
||||
DocumentNextHeadingAtLevel4 Command = "document-next-heading-at-level-4"
|
||||
DocumentPreviousHeadingAtLevel4 Command = "document-previous-heading-at-level-4"
|
||||
DocumentNextHeadingAtLevel5 Command = "document-next-heading-at-level-5"
|
||||
DocumentPreviousHeadingAtLevel5 Command = "document-previous-heading-at-level-5"
|
||||
DocumentNextHeadingAtLevel6 Command = "document-next-heading-at-level-6"
|
||||
DocumentPreviousHeadingAtLevel6 Command = "document-previous-heading-at-level-6"
|
||||
DocumentNextBlockQuote Command = "document-next-block-quote"
|
||||
DocumentPreviousBlockQuote Command = "document-previous-block-quote"
|
||||
DocumentNextComboBox Command = "document-next-combo-box"
|
||||
DocumentPreviousComboBox Command = "document-previous-combo-box"
|
||||
DocumentNextEntry Command = "document-next-entry"
|
||||
DocumentPreviousEntry Command = "document-previous-entry"
|
||||
DocumentNextFormField Command = "document-next-form-field"
|
||||
DocumentPreviousFormField Command = "document-previous-form-field"
|
||||
DocumentNextImage Command = "document-next-image"
|
||||
DocumentPreviousImage Command = "document-previous-image"
|
||||
DocumentNextLandmark Command = "document-next-landmark"
|
||||
DocumentPreviousLandmark Command = "document-previous-landmark"
|
||||
DocumentNextListItem Command = "document-next-list-item"
|
||||
DocumentPreviousListItem Command = "document-previous-list-item"
|
||||
DocumentNextLiveRegion Command = "document-next-live-region"
|
||||
DocumentPreviousLiveRegion Command = "document-previous-live-region"
|
||||
DocumentNextParagraph Command = "document-next-paragraph"
|
||||
DocumentPreviousParagraph Command = "document-previous-paragraph"
|
||||
DocumentNextRadioButton Command = "document-next-radio-button"
|
||||
DocumentPreviousRadioButton Command = "document-previous-radio-button"
|
||||
DocumentNextTable Command = "document-next-table"
|
||||
DocumentPreviousTable Command = "document-previous-table"
|
||||
DocumentNextUnvisitedLink Command = "document-next-unvisited-link"
|
||||
DocumentPreviousUnvisitedLink Command = "document-previous-unvisited-link"
|
||||
DocumentNextVisitedLink Command = "document-next-visited-link"
|
||||
DocumentPreviousVisitedLink Command = "document-previous-visited-link"
|
||||
DocumentNextClickable Command = "document-next-clickable"
|
||||
DocumentPreviousClickable Command = "document-previous-clickable"
|
||||
DocumentNextChunk Command = "document-next-chunk"
|
||||
DocumentPreviousChunk Command = "document-previous-chunk"
|
||||
DocumentCaretNextCharacter Command = "document-caret-next-character"
|
||||
DocumentCaretPreviousCharacter Command = "document-caret-previous-character"
|
||||
DocumentCaretNextWord Command = "document-caret-next-word"
|
||||
DocumentCaretPreviousWord Command = "document-caret-previous-word"
|
||||
DocumentCaretNextLine Command = "document-caret-next-line"
|
||||
DocumentCaretPreviousLine Command = "document-caret-previous-line"
|
||||
DocumentCaretLineStart Command = "document-caret-line-start"
|
||||
DocumentCaretLineEnd Command = "document-caret-line-end"
|
||||
DocumentCaretDocumentStart Command = "document-caret-document-start"
|
||||
DocumentCaretDocumentEnd Command = "document-caret-document-end"
|
||||
DocumentTableLeft Command = "document-table-left"
|
||||
DocumentTableRight Command = "document-table-right"
|
||||
DocumentTableUp Command = "document-table-up"
|
||||
DocumentTableDown Command = "document-table-down"
|
||||
DocumentTableFirst Command = "document-table-first"
|
||||
DocumentTableLast Command = "document-table-last"
|
||||
DocumentActivate Command = "document-activate"
|
||||
ReadAll Command = "read-all"
|
||||
DisableTentacles Command = "disable-tentacles"
|
||||
Quit Command = "quit"
|
||||
Preferences Command = "preferences"
|
||||
ApplicationPreferences Command = "application-preferences"
|
||||
ChooseApplicationPreferences Command = "choose-application-preferences"
|
||||
PresentCellFormula Command = "present-cell-formula"
|
||||
SetColumnHeadersRow Command = "set-column-headers-row"
|
||||
ClearColumnHeadersRow Command = "clear-column-headers-row"
|
||||
SetRowHeadersColumn Command = "set-row-headers-column"
|
||||
ClearRowHeadersColumn Command = "clear-row-headers-column"
|
||||
WhereAmI Command = "where-am-i"
|
||||
PresentWindowTitle Command = "present-window-title"
|
||||
PresentCharacterAttributes Command = "present-character-attributes"
|
||||
PresentLastNotification Command = "present-last-notification"
|
||||
PresentPreviousNotification Command = "present-previous-notification"
|
||||
PresentNextNotification Command = "present-next-notification"
|
||||
ShowNotificationList Command = "show-notification-list"
|
||||
ObjectParent Command = "object-parent"
|
||||
ObjectFirstChild Command = "object-first-child"
|
||||
ObjectPreviousSibling Command = "object-previous-sibling"
|
||||
ObjectNextSibling Command = "object-next-sibling"
|
||||
ReviewWindowStart Command = "review-window-start"
|
||||
ReviewWindowEnd Command = "review-window-end"
|
||||
ReviewPreviousLine Command = "review-previous-line"
|
||||
ReviewCurrentLine Command = "review-current-line"
|
||||
ReviewSpellLine Command = "review-spell-line"
|
||||
ReviewPhoneticLine Command = "review-phonetic-line"
|
||||
ReviewNextLine Command = "review-next-line"
|
||||
ReviewPreviousWord Command = "review-previous-word"
|
||||
ReviewCurrentWord Command = "review-current-word"
|
||||
ReviewSpellWord Command = "review-spell-word"
|
||||
ReviewPhoneticWord Command = "review-phonetic-word"
|
||||
ReviewNextWord Command = "review-next-word"
|
||||
ReviewPreviousCharacter Command = "review-previous-character"
|
||||
ReviewCurrentCharacter Command = "review-current-character"
|
||||
ReviewPhoneticCharacter Command = "review-phonetic-character"
|
||||
ReviewNextCharacter Command = "review-next-character"
|
||||
ReviewWordAbove Command = "review-word-above"
|
||||
ReviewWordBelow Command = "review-word-below"
|
||||
ReviewLineEnd Command = "review-line-end"
|
||||
)
|
||||
|
||||
type KeyboardLayout int
|
||||
|
||||
const (
|
||||
DesktopKeyboardLayout KeyboardLayout = 1
|
||||
LaptopKeyboardLayout KeyboardLayout = 2
|
||||
)
|
||||
|
||||
const (
|
||||
returnKeySymbol uint32 = 0xff0d
|
||||
keypadEnterKeySymbol uint32 = 0xff8d
|
||||
leftKeySymbol uint32 = 0xff51
|
||||
upKeySymbol uint32 = 0xff52
|
||||
rightKeySymbol uint32 = 0xff53
|
||||
downKeySymbol uint32 = 0xff54
|
||||
leftControlKeySymbol uint32 = 0xffe3
|
||||
rightControlKeySymbol uint32 = 0xffe4
|
||||
leftShiftKeySymbol uint32 = 0xffe1
|
||||
rightShiftKeySymbol uint32 = 0xffe2
|
||||
controlModifier uint16 = 1 << 2
|
||||
)
|
||||
|
||||
type CommandChord struct {
|
||||
Symbol uint32
|
||||
Modifiers uint16
|
||||
CthulhuModifier bool
|
||||
}
|
||||
|
||||
type CommandBindings map[CommandChord]Command
|
||||
|
||||
// CommandEvent retains the initiating X server time across asynchronous delivery.
|
||||
type CommandEvent struct {
|
||||
Command Command
|
||||
Timestamp uint32
|
||||
Chord CommandChord
|
||||
KeyName string
|
||||
LearnModeStarted bool
|
||||
UISession uint64
|
||||
Text string
|
||||
}
|
||||
|
||||
type LockState struct {
|
||||
Name string
|
||||
Locked bool
|
||||
Timestamp uint32
|
||||
}
|
||||
|
||||
func (state LockState) Text() string {
|
||||
if state.Locked {
|
||||
return state.Name + " on"
|
||||
}
|
||||
return state.Name + " off"
|
||||
}
|
||||
|
||||
func DefaultCommandBindings(layout KeyboardLayout) CommandBindings {
|
||||
bindings := CommandBindings{
|
||||
{Symbol: 'a', Modifiers: 1, CthulhuModifier: true}: ShowActions,
|
||||
{Symbol: leftKeySymbol, CthulhuModifier: true}: SelectPreviousSpeechSetting,
|
||||
{Symbol: rightKeySymbol, CthulhuModifier: true}: SelectNextSpeechSetting,
|
||||
{Symbol: downKeySymbol, CthulhuModifier: true}: DecreaseSpeechSetting,
|
||||
{Symbol: upKeySymbol, CthulhuModifier: true}: IncreaseSpeechSetting,
|
||||
{Symbol: upKeySymbol, Modifiers: 1, CthulhuModifier: true}: PresentCurrentLine,
|
||||
{Symbol: 's', Modifiers: controlModifier | 1, CthulhuModifier: true}: SaveSpeechSettings,
|
||||
{Symbol: 't', CthulhuModifier: true}: PresentTime,
|
||||
{Symbol: 'c', Modifiers: 1, CthulhuModifier: true}: PresentClipboard,
|
||||
{Symbol: 'h', Modifiers: controlModifier, CthulhuModifier: true}: ShowSpeechHistory,
|
||||
{Symbol: 'd', Modifiers: 1, CthulhuModifier: true}: ToggleSpeechMonitor,
|
||||
{Symbol: 's', CthulhuModifier: true}: CycleSpeechMode,
|
||||
{Symbol: 'u', CthulhuModifier: true}: CycleProgressBarOutput,
|
||||
{Symbol: 'v', Modifiers: 1, CthulhuModifier: true}: PresentVersion,
|
||||
{Symbol: 'a', CthulhuModifier: true}: ToggleDocumentMode,
|
||||
{Symbol: 'h', CthulhuModifier: true}: ToggleLearnMode,
|
||||
{Symbol: 0xffbe, CthulhuModifier: true}: ToggleLearnMode,
|
||||
{Symbol: 'h', Modifiers: 1, CthulhuModifier: true}: DocumentPreviousHeading,
|
||||
{Symbol: 'k', CthulhuModifier: true, Modifiers: controlModifier}: DocumentNextLink,
|
||||
{Symbol: 'k', Modifiers: controlModifier | 1, CthulhuModifier: true}: DocumentPreviousLink,
|
||||
{Symbol: 'q', CthulhuModifier: true}: Quit,
|
||||
{Symbol: 'q', Modifiers: 5, CthulhuModifier: true}: DisableTentacles,
|
||||
{Symbol: 'n', CthulhuModifier: true}: PresentLastNotification,
|
||||
{Symbol: 'n', Modifiers: controlModifier, CthulhuModifier: true}: ShowNotificationList,
|
||||
{Symbol: ' ', CthulhuModifier: true}: Preferences,
|
||||
{Symbol: ' ', Modifiers: controlModifier, CthulhuModifier: true}: ApplicationPreferences,
|
||||
{Symbol: ' ', Modifiers: 1, CthulhuModifier: true}: ApplicationPreferences,
|
||||
{Symbol: ' ', Modifiers: controlModifier | 1, CthulhuModifier: true}: ChooseApplicationPreferences,
|
||||
{Symbol: 'f', CthulhuModifier: true}: PresentCharacterAttributes,
|
||||
{Symbol: upKeySymbol, Modifiers: controlModifier, CthulhuModifier: true}: ObjectParent,
|
||||
{Symbol: downKeySymbol, Modifiers: controlModifier, CthulhuModifier: true}: ObjectFirstChild,
|
||||
{Symbol: leftKeySymbol, Modifiers: controlModifier, CthulhuModifier: true}: ObjectPreviousSibling,
|
||||
{Symbol: rightKeySymbol, Modifiers: controlModifier, CthulhuModifier: true}: ObjectNextSibling,
|
||||
}
|
||||
if layout == DesktopKeyboardLayout {
|
||||
bindings[CommandChord{Symbol: 'o', CthulhuModifier: true}] = OCRWindow
|
||||
bindings[CommandChord{Symbol: 0xffab}] = ReadAll // KP_Add
|
||||
bindings[CommandChord{Symbol: keypadEnterKeySymbol}] = WhereAmI
|
||||
bindings[CommandChord{Symbol: keypadEnterKeySymbol, CthulhuModifier: true}] = PresentWindowTitle
|
||||
bindings[CommandChord{Symbol: '=', CthulhuModifier: true}] = PresentCellFormula
|
||||
bindings[CommandChord{Symbol: 0xff95, CthulhuModifier: true}] = ReviewWindowStart
|
||||
bindings[CommandChord{Symbol: 0xff9a, CthulhuModifier: true}] = ReviewWindowEnd
|
||||
bindings[CommandChord{Symbol: 0xff96, CthulhuModifier: true}] = ReviewWordAbove
|
||||
bindings[CommandChord{Symbol: 0xff98, CthulhuModifier: true}] = ReviewWordBelow
|
||||
bindings[CommandChord{Symbol: 0xff9c, CthulhuModifier: true}] = ReviewLineEnd
|
||||
} else if layout == LaptopKeyboardLayout {
|
||||
bindings[CommandChord{Symbol: 'o', Modifiers: 1, CthulhuModifier: true}] = OCRWindow
|
||||
bindings[CommandChord{Symbol: 'u', Modifiers: 1, CthulhuModifier: true}] = CycleProgressBarOutput
|
||||
bindings[CommandChord{Symbol: ';', CthulhuModifier: true}] = ReadAll
|
||||
bindings[CommandChord{Symbol: returnKeySymbol, CthulhuModifier: true}] = WhereAmI
|
||||
bindings[CommandChord{Symbol: '/', CthulhuModifier: true}] = PresentWindowTitle
|
||||
bindings[CommandChord{Symbol: 'u', Modifiers: controlModifier, CthulhuModifier: true}] = ReviewWindowStart
|
||||
bindings[CommandChord{Symbol: 'o', Modifiers: controlModifier, CthulhuModifier: true}] = ReviewWindowEnd
|
||||
bindings[CommandChord{Symbol: 'j', Modifiers: controlModifier, CthulhuModifier: true}] = ReviewWordAbove
|
||||
bindings[CommandChord{Symbol: 'l', Modifiers: controlModifier, CthulhuModifier: true}] = ReviewWordBelow
|
||||
bindings[CommandChord{Symbol: 'm', Modifiers: controlModifier, CthulhuModifier: true}] = ReviewLineEnd
|
||||
}
|
||||
for _, binding := range []struct {
|
||||
desktop, laptop uint32
|
||||
command Command
|
||||
}{
|
||||
{0xff95, 'u', ReviewPreviousLine}, {0xff97, 'i', ReviewCurrentLine}, {0xff9a, 'o', ReviewNextLine},
|
||||
{0xff96, 'j', ReviewPreviousWord}, {0xff9d, 'k', ReviewCurrentWord}, {0xff98, 'l', ReviewNextWord},
|
||||
{0xff9c, 'm', ReviewPreviousCharacter}, {0xff99, ',', ReviewCurrentCharacter}, {0xff9b, '.', ReviewNextCharacter},
|
||||
} {
|
||||
if layout == DesktopKeyboardLayout {
|
||||
bindings[CommandChord{Symbol: binding.desktop}] = binding.command
|
||||
}
|
||||
if layout == LaptopKeyboardLayout {
|
||||
bindings[CommandChord{Symbol: binding.laptop, CthulhuModifier: true}] = binding.command
|
||||
}
|
||||
}
|
||||
return bindings
|
||||
}
|
||||
|
||||
// CommandRouter owns the pressed state of screen-reader modifiers and consumed
|
||||
// command keys. Commands are emitted on press; native owners retain the grab
|
||||
// independently until the chord releases, including during handler shutdown.
|
||||
type CommandRouter struct {
|
||||
now func() time.Time
|
||||
lastTimePress time.Time
|
||||
lastModePress time.Time
|
||||
modePresses int
|
||||
lastReviewPress time.Time
|
||||
lastReviewChord CommandChord
|
||||
reviewPresses int
|
||||
modifiers map[uint32]bool
|
||||
bindings CommandBindings
|
||||
down map[uint16]bool
|
||||
consumed map[uint16]bool
|
||||
}
|
||||
|
||||
func NewCommandRouter(modifiers []uint32, bindings CommandBindings) *CommandRouter {
|
||||
router := &CommandRouter{
|
||||
now: time.Now,
|
||||
modifiers: make(map[uint32]bool),
|
||||
bindings: make(CommandBindings, len(bindings)),
|
||||
down: make(map[uint16]bool),
|
||||
consumed: make(map[uint16]bool),
|
||||
}
|
||||
for _, symbol := range modifiers {
|
||||
router.modifiers[symbol] = true
|
||||
}
|
||||
for chord, command := range bindings {
|
||||
router.bindings[chord] = command
|
||||
}
|
||||
return router
|
||||
}
|
||||
|
||||
func (router *CommandRouter) Handle(symbol uint32, code uint16, modifiers uint16, pressed bool) (bool, Command) {
|
||||
consume := false
|
||||
if !pressed {
|
||||
consume = router.down[code] || router.consumed[code]
|
||||
delete(router.down, code)
|
||||
delete(router.consumed, code)
|
||||
} else if router.modifiers[symbol] {
|
||||
router.down[code] = true
|
||||
consume = true
|
||||
} else if router.consumed[code] {
|
||||
consume = true
|
||||
} else {
|
||||
chord := CommandChord{
|
||||
Symbol: symbol,
|
||||
Modifiers: modifiers &^ uint16(2|16),
|
||||
CthulhuModifier: len(router.down) != 0,
|
||||
}
|
||||
if command := router.bindings[chord]; command != "" {
|
||||
router.consumed[code] = true
|
||||
command = router.review_press(command, chord)
|
||||
if command == ToggleDocumentMode {
|
||||
now := router.now()
|
||||
if !router.lastModePress.IsZero() && now.Sub(router.lastModePress) >= 0 && now.Sub(router.lastModePress) <= 500*time.Millisecond {
|
||||
router.modePresses++
|
||||
} else {
|
||||
router.modePresses = 1
|
||||
}
|
||||
router.lastModePress = now
|
||||
switch router.modePresses {
|
||||
case 2:
|
||||
command = StickyFocusMode
|
||||
case 3:
|
||||
command = StickyBrowseMode
|
||||
router.lastModePress = time.Time{}
|
||||
}
|
||||
} else {
|
||||
router.lastModePress = time.Time{}
|
||||
}
|
||||
if command == PresentTime {
|
||||
now := router.now()
|
||||
if !router.lastTimePress.IsZero() && now.Sub(router.lastTimePress) >= 0 && now.Sub(router.lastTimePress) <= 500*time.Millisecond {
|
||||
command = PresentDate
|
||||
router.lastTimePress = time.Time{}
|
||||
} else {
|
||||
router.lastTimePress = now
|
||||
}
|
||||
} else {
|
||||
router.lastTimePress = time.Time{}
|
||||
}
|
||||
return true, command
|
||||
}
|
||||
router.lastTimePress = time.Time{}
|
||||
router.lastModePress = time.Time{}
|
||||
router.lastReviewPress = time.Time{}
|
||||
}
|
||||
return consume, ""
|
||||
}
|
||||
|
||||
func (router *CommandRouter) IsModifier(symbol uint32) bool {
|
||||
switch symbol {
|
||||
case leftControlKeySymbol, rightControlKeySymbol, leftShiftKeySymbol, rightShiftKeySymbol,
|
||||
0xffe7, 0xffe8, 0xffe9, 0xffea, 0xffeb, 0xffec, 0xffed, 0xffee: // Meta, Alt, Super, Hyper.
|
||||
return true
|
||||
}
|
||||
return router.modifiers[symbol]
|
||||
}
|
||||
|
||||
// Chord reports the keys currently held before handling the next press.
|
||||
func (router *CommandRouter) Chord(symbol uint32, modifiers uint16) CommandChord {
|
||||
return CommandChord{Symbol: symbol, Modifiers: modifiers &^ uint16(2|16), CthulhuModifier: len(router.down) != 0}
|
||||
}
|
||||
|
||||
func (router *CommandRouter) Reset() {
|
||||
clear(router.down)
|
||||
clear(router.consumed)
|
||||
}
|
||||
|
||||
// Browse bindings are installed only while the runtime owns live web content.
|
||||
func BrowseCommandBindings(layout KeyboardLayout) CommandBindings {
|
||||
bindings := DefaultCommandBindings(layout)
|
||||
caretBindings := CommandBindings{
|
||||
{Symbol: leftKeySymbol, Modifiers: 1 | 8}: DocumentTableLeft,
|
||||
{Symbol: rightKeySymbol, Modifiers: 1 | 8}: DocumentTableRight,
|
||||
{Symbol: upKeySymbol, Modifiers: 1 | 8}: DocumentTableUp,
|
||||
{Symbol: downKeySymbol, Modifiers: 1 | 8}: DocumentTableDown,
|
||||
{Symbol: 0xff50, Modifiers: 1 | 8}: DocumentTableFirst,
|
||||
{Symbol: 0xff57, Modifiers: 1 | 8}: DocumentTableLast,
|
||||
{Symbol: rightKeySymbol}: DocumentCaretNextCharacter,
|
||||
{Symbol: leftKeySymbol}: DocumentCaretPreviousCharacter,
|
||||
{Symbol: rightKeySymbol, Modifiers: controlModifier}: DocumentCaretNextWord,
|
||||
{Symbol: leftKeySymbol, Modifiers: controlModifier}: DocumentCaretPreviousWord,
|
||||
{Symbol: downKeySymbol}: DocumentCaretNextLine,
|
||||
{Symbol: upKeySymbol}: DocumentCaretPreviousLine,
|
||||
{Symbol: 0xff50}: DocumentCaretLineStart,
|
||||
{Symbol: 0xff57}: DocumentCaretLineEnd,
|
||||
{Symbol: 0xff50, Modifiers: controlModifier}: DocumentCaretDocumentStart,
|
||||
{Symbol: 0xff57, Modifiers: controlModifier}: DocumentCaretDocumentEnd,
|
||||
{Symbol: returnKeySymbol}: DocumentActivate,
|
||||
}
|
||||
for chord, command := range caretBindings {
|
||||
bindings[chord] = command
|
||||
}
|
||||
documentBindings := []struct {
|
||||
symbol uint32
|
||||
next Command
|
||||
previous Command
|
||||
}{
|
||||
{'h', DocumentNextHeading, DocumentPreviousHeading},
|
||||
{'k', DocumentNextLink, DocumentPreviousLink},
|
||||
{'b', DocumentNextButton, DocumentPreviousButton},
|
||||
{'x', DocumentNextCheckBox, DocumentPreviousCheckBox},
|
||||
{'l', DocumentNextList, DocumentPreviousList},
|
||||
{'s', DocumentNextSeparator, DocumentPreviousSeparator},
|
||||
{'q', DocumentNextBlockQuote, DocumentPreviousBlockQuote},
|
||||
{'c', DocumentNextComboBox, DocumentPreviousComboBox},
|
||||
{'e', DocumentNextEntry, DocumentPreviousEntry},
|
||||
{'f', DocumentNextFormField, DocumentPreviousFormField},
|
||||
{'g', DocumentNextImage, DocumentPreviousImage},
|
||||
{'m', DocumentNextLandmark, DocumentPreviousLandmark},
|
||||
{'i', DocumentNextListItem, DocumentPreviousListItem},
|
||||
{'d', DocumentNextLiveRegion, DocumentPreviousLiveRegion},
|
||||
{'p', DocumentNextParagraph, DocumentPreviousParagraph},
|
||||
{'r', DocumentNextRadioButton, DocumentPreviousRadioButton},
|
||||
{'t', DocumentNextTable, DocumentPreviousTable},
|
||||
{'u', DocumentNextUnvisitedLink, DocumentPreviousUnvisitedLink},
|
||||
{'v', DocumentNextVisitedLink, DocumentPreviousVisitedLink},
|
||||
{'a', DocumentNextClickable, DocumentPreviousClickable},
|
||||
{'o', DocumentNextChunk, DocumentPreviousChunk},
|
||||
}
|
||||
for _, binding := range documentBindings {
|
||||
bindings[CommandChord{Symbol: binding.symbol}] = binding.next
|
||||
bindings[CommandChord{Symbol: binding.symbol, Modifiers: 1}] = binding.previous
|
||||
}
|
||||
for _, binding := range DocumentListBindings() {
|
||||
if binding.Symbol != 0 {
|
||||
bindings[CommandChord{Symbol: binding.Symbol, Modifiers: 1 | 8}] = binding.Command
|
||||
}
|
||||
}
|
||||
headingLevels := []struct {
|
||||
level int
|
||||
next Command
|
||||
previous Command
|
||||
}{
|
||||
{1, DocumentNextHeadingAtLevel1, DocumentPreviousHeadingAtLevel1},
|
||||
{2, DocumentNextHeadingAtLevel2, DocumentPreviousHeadingAtLevel2},
|
||||
{3, DocumentNextHeadingAtLevel3, DocumentPreviousHeadingAtLevel3},
|
||||
{4, DocumentNextHeadingAtLevel4, DocumentPreviousHeadingAtLevel4},
|
||||
{5, DocumentNextHeadingAtLevel5, DocumentPreviousHeadingAtLevel5},
|
||||
{6, DocumentNextHeadingAtLevel6, DocumentPreviousHeadingAtLevel6},
|
||||
}
|
||||
for _, binding := range headingLevels {
|
||||
symbol := uint32('0' + binding.level)
|
||||
bindings[CommandChord{Symbol: symbol}] = binding.next
|
||||
bindings[CommandChord{Symbol: symbol, Modifiers: 1}] = binding.previous
|
||||
}
|
||||
return bindings
|
||||
}
|
||||
|
||||
// ReplaceBindings preserves multi-press timing across browse grab changes.
|
||||
// Native owners call this only after every consumed key has been released.
|
||||
func (router *CommandRouter) ReplaceBindings(bindings CommandBindings) {
|
||||
router.bindings = make(CommandBindings, len(bindings))
|
||||
for chord, command := range bindings {
|
||||
router.bindings[chord] = command
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user