Default laptop key set to capslock. Keys that can be set to fenrir key or script key selectable via checkbox.
This commit is contained in:
1 parent
47f18fdd28
commit
15e04aa8f8
47 files changed
+1560
-351
No files matched your search
+93
-35
@@ -37,6 +37,7 @@ const (
|
||||
KeyRightShift = 54
|
||||
KeyAlt = 56
|
||||
KeySpace = 57
|
||||
KeyCapsLock = 58
|
||||
KeyF4 = 62
|
||||
KeyKP7 = 71
|
||||
KeyKP8 = 72
|
||||
@@ -66,34 +67,37 @@ const (
|
||||
)
|
||||
|
||||
type Decision struct {
|
||||
Code uint16 // physical key code, for forwarded application press/repeat hooks
|
||||
Forward bool
|
||||
Interrupt bool
|
||||
Keypress bool // a fresh physical press, excluding repeats and state repair
|
||||
Deletion bool // forwarded Backspace/Delete, including repeats
|
||||
Typing bool // forwarded text key or repeat; the screen supplies its actual text
|
||||
WordBoundary bool // a forwarded Space, rather than cursor navigation
|
||||
Command command.ID
|
||||
UI *interaction.Key
|
||||
Learn *LearnKey // captured physical press and its inactive command
|
||||
Code uint16 // physical key code, for forwarded application press/repeat hooks
|
||||
ToggleCapsLock bool // completed Shift+Caps Lock gesture
|
||||
Forward bool
|
||||
Interrupt bool
|
||||
Keypress bool // a fresh physical press, excluding repeats and state repair
|
||||
Deletion bool // forwarded Backspace/Delete, including repeats
|
||||
Typing bool // forwarded text key or repeat; the screen supplies its actual text
|
||||
WordBoundary bool // a forwarded Space, rather than cursor navigation
|
||||
Command command.ID
|
||||
UI *interaction.Key
|
||||
Learn *LearnKey // captured physical press and its inactive command
|
||||
}
|
||||
|
||||
type Router struct {
|
||||
keys map[int]map[uint16]heldKey
|
||||
passArmed bool
|
||||
passing bool
|
||||
captured bool
|
||||
bindings map[chord]command.ID
|
||||
doubleBindings map[chord]command.ID
|
||||
tripleBindings map[chord]command.ID
|
||||
multiPressTimeout time.Duration
|
||||
pressCount int
|
||||
lastChord chord
|
||||
lastDevice int
|
||||
lastPress time.Time
|
||||
now func() time.Time
|
||||
scriptKeys map[uint16]bool
|
||||
scriptBindings map[string]command.ID
|
||||
readerKeys map[uint16]bool
|
||||
capsShift, capsUsed bool
|
||||
keys map[int]map[uint16]heldKey
|
||||
passArmed bool
|
||||
passing bool
|
||||
captured bool
|
||||
bindings map[chord]command.ID
|
||||
doubleBindings map[chord]command.ID
|
||||
tripleBindings map[chord]command.ID
|
||||
multiPressTimeout time.Duration
|
||||
pressCount int
|
||||
lastChord chord
|
||||
lastDevice int
|
||||
lastPress time.Time
|
||||
now func() time.Time
|
||||
scriptKeys map[uint16]bool
|
||||
scriptBindings map[string]command.ID
|
||||
}
|
||||
|
||||
type heldKey struct {
|
||||
@@ -104,6 +108,7 @@ type heldKey struct {
|
||||
|
||||
func (r *Router) Reset() {
|
||||
r.lastPress = time.Time{}
|
||||
r.capsShift, r.capsUsed = false, false
|
||||
r.keys = nil
|
||||
r.passArmed = false
|
||||
r.passing = false
|
||||
@@ -111,6 +116,7 @@ func (r *Router) Reset() {
|
||||
}
|
||||
|
||||
func (r *Router) Drop(device int) {
|
||||
r.capsUsed = true
|
||||
r.lastPress = time.Time{}
|
||||
delete(r.keys, device)
|
||||
if r.empty() {
|
||||
@@ -161,6 +167,7 @@ func (r *Router) key(device int, key uint16, value int32, numLock, syncEvent, re
|
||||
_, held := r.keys[device][key]
|
||||
if value == 0 && held || value == 1 && !held {
|
||||
r.lastPress = time.Time{}
|
||||
r.capsUsed = true
|
||||
}
|
||||
}
|
||||
if r.keys == nil {
|
||||
@@ -176,7 +183,11 @@ func (r *Router) key(device int, key uint16, value int32, numLock, syncEvent, re
|
||||
if r.empty() {
|
||||
r.passing = false
|
||||
}
|
||||
return Decision{Forward: exists && state.forwarded}
|
||||
toggle := key == KeyCapsLock && exists && !state.forwarded && r.Caps_modifier() && r.capsShift && !r.capsUsed && !syncEvent && !r.captured && !r.passing
|
||||
if key == KeyCapsLock {
|
||||
r.capsShift, r.capsUsed = false, false
|
||||
}
|
||||
return Decision{Forward: exists && state.forwarded, ToggleCapsLock: toggle}
|
||||
}
|
||||
if value != 1 && value != 2 {
|
||||
return Decision{}
|
||||
@@ -204,13 +215,34 @@ func (r *Router) key(device int, key uint16, value int32, numLock, syncEvent, re
|
||||
if value == 2 {
|
||||
return Decision{}
|
||||
}
|
||||
if !syncEvent && r.Caps_modifier() {
|
||||
switch key {
|
||||
case KeyCapsLock:
|
||||
r.capsShift, r.capsUsed = r.down(KeyShift) || r.down(KeyRightShift), false
|
||||
for _, held := range r.keys {
|
||||
for code := range held {
|
||||
if code != KeyShift && code != KeyRightShift {
|
||||
r.capsUsed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
case KeyShift, KeyRightShift:
|
||||
if r.down(KeyCapsLock) {
|
||||
r.capsShift = true
|
||||
}
|
||||
default:
|
||||
if r.down(KeyCapsLock) {
|
||||
r.capsUsed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if r.captured {
|
||||
var learn *LearnKey
|
||||
if !syncEvent {
|
||||
learn = r.learn_key(device, key, numLock)
|
||||
}
|
||||
held[key] = heldKey{ui: true}
|
||||
if syncEvent || pure_modifier(key) {
|
||||
if syncEvent || pure_modifier(key) || r.reader_modifier(key, numLock) {
|
||||
return Decision{Learn: learn, Keypress: !syncEvent, Interrupt: !syncEvent && (key == KeyCtrl || key == KeyRightCtrl)}
|
||||
}
|
||||
decision := r.ui_key(key)
|
||||
@@ -229,10 +261,10 @@ func (r *Router) key(device int, key uint16, value int32, numLock, syncEvent, re
|
||||
commandID = r.binding(key, numLock)
|
||||
}
|
||||
}
|
||||
if !syncEvent && !pure_modifier(key) && !reader_modifier(key, numLock) {
|
||||
if !syncEvent && !pure_modifier(key) && !r.reader_modifier(key, numLock) {
|
||||
commandID = r.multi_press(device, r.binding_chord(key, numLock), commandID, scriptChord)
|
||||
}
|
||||
forwarded := commandID == "" && !scriptChord && !(reader_modifier(key, numLock) && !r.passing)
|
||||
forwarded := commandID == "" && !scriptChord && !(r.reader_modifier(key, numLock) && !r.passing)
|
||||
held[key] = heldKey{forwarded: forwarded, commandID: commandID}
|
||||
if syncEvent {
|
||||
return Decision{Forward: forwarded}
|
||||
@@ -243,11 +275,11 @@ func (r *Router) key(device int, key uint16, value int32, numLock, syncEvent, re
|
||||
|
||||
func (r *Router) typing_key(key uint16, numLock bool) bool {
|
||||
for scriptKey := range r.scriptKeys {
|
||||
if r.down(scriptKey) {
|
||||
if r.script_modifier(scriptKey, numLock) && r.down(scriptKey) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if r.down(KeyCtrl) || r.down(KeyRightCtrl) || r.down(KeyAlt) || r.down(KeyInsert) || r.down(KeyMeta) || r.down(KeyRightMeta) {
|
||||
if r.down(KeyCtrl) || r.down(KeyRightCtrl) || r.down(KeyAlt) || r.reader_down(numLock) || r.down(KeyMeta) || r.down(KeyRightMeta) {
|
||||
return false
|
||||
}
|
||||
// Physical text-key positions, independent of keyboard layout. AltGr is
|
||||
@@ -284,8 +316,34 @@ func (r *Router) empty() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func reader_modifier(key uint16, numLock bool) bool {
|
||||
return key == KeyInsert || key == KeyMeta || key == KeyRightMeta || key == KeyKP0 && !numLock
|
||||
func (r *Router) reader_modifier(key uint16, numLock bool) bool {
|
||||
if r.readerKeys == nil {
|
||||
return key == KeyInsert || key == KeyMeta || key == KeyRightMeta || key == KeyKP0 && !numLock
|
||||
}
|
||||
return r.readerKeys[key] && (key != KeyKP0 || !numLock)
|
||||
}
|
||||
|
||||
// Caps_modifier reports whether Caps Lock is reserved for reader or script chords.
|
||||
func (r *Router) Caps_modifier() bool { return r.readerKeys[KeyCapsLock] || r.scriptKeys[KeyCapsLock] }
|
||||
|
||||
// Reader_keys supplies the X11 adapter with the physical keys to intercept.
|
||||
func (r *Router) Reader_keys() []uint16 {
|
||||
var keys []uint16
|
||||
for _, key := range []uint16{KeyInsert, KeyMeta, KeyRightMeta, KeyCapsLock, KeyKP0} {
|
||||
if r.reader_modifier(key, false) {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
func (r *Router) reader_down(numLock bool) bool {
|
||||
for _, key := range r.Reader_keys() {
|
||||
if r.reader_modifier(key, numLock) && r.down(key) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func pure_modifier(key uint16) bool {
|
||||
@@ -293,7 +351,7 @@ func pure_modifier(key uint16) bool {
|
||||
}
|
||||
|
||||
func (r *Router) binding(key uint16, numLock bool) command.ID {
|
||||
if reader_modifier(key, numLock) || pure_modifier(key) {
|
||||
if r.reader_modifier(key, numLock) || pure_modifier(key) {
|
||||
return ""
|
||||
}
|
||||
combo := r.binding_chord(key, numLock)
|
||||
@@ -311,7 +369,7 @@ func (r *Router) binding(key uint16, numLock bool) command.ID {
|
||||
|
||||
func (r *Router) binding_chord(key uint16, numLock bool) chord {
|
||||
var mods modifiers
|
||||
if r.down(KeyInsert) || r.down(KeyMeta) || r.down(KeyRightMeta) || !numLock && r.down(KeyKP0) {
|
||||
if r.reader_down(numLock) {
|
||||
mods |= fenrirModifier
|
||||
}
|
||||
if r.down(KeyCtrl) || r.down(KeyRightCtrl) {
|
||||
|
||||
Reference in new issue
Block a user