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,178 @@
|
||||
package xorg
|
||||
|
||||
/*
|
||||
#include "commands_native.h"
|
||||
#include <X11/XKBlib.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.stormux.org/storm/cthulhu/internal/input"
|
||||
)
|
||||
|
||||
// Wait for the complete chord: Shift+CapsLock+V remains a version command.
|
||||
func is_caps_lock_toggle(keys []C.CommandKey) bool {
|
||||
caps, shift := false, false
|
||||
for _, key := range keys {
|
||||
if key.modifiers & ^C.int(1) != 0 {
|
||||
return false
|
||||
}
|
||||
shift = shift || key.modifiers&1 != 0
|
||||
switch key.symbol {
|
||||
case 0xffe5:
|
||||
caps = true
|
||||
case 0xffe1, 0xffe2:
|
||||
shift = true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
return caps && shift
|
||||
}
|
||||
|
||||
func (owner *commandOwner) handleKey(key C.CommandKey) bool {
|
||||
owner.listener.grabActive.Store(true)
|
||||
// Focus policy can change while the native owner waits for an X
|
||||
// event. Replay a stale browse-only press against the requested
|
||||
// policy, including custom symbols outside the default key list.
|
||||
if !owner.learnMode && owner.uiSession == 0 && len(owner.held) == 0 && key.pressed != 0 && !owner.listener.browse.Load() && !owner.ocrReview &&
|
||||
!owner.router.IsModifier(uint32(key.symbol)) && owner.globalBindings[input.CommandChord{Symbol: uint32(key.symbol), Modifiers: uint16(key.modifiers)}] == "" {
|
||||
owner.passThrough = true
|
||||
}
|
||||
if key.pressed != 0 {
|
||||
owner.held[int(key.code)] = true
|
||||
} else {
|
||||
delete(owner.held, int(key.code))
|
||||
}
|
||||
owner.buffered = append(owner.buffered, key)
|
||||
if owner.uiSession != 0 {
|
||||
if !owner.handle_internal_key(key) {
|
||||
return false
|
||||
}
|
||||
} else if owner.learnMode {
|
||||
if !owner.handleLearnKey(key) {
|
||||
return false
|
||||
}
|
||||
} else if !owner.passThrough && !owner.handleRoutedKey(key) {
|
||||
return false
|
||||
}
|
||||
if len(owner.held) == 0 && !owner.finishChord() {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (owner *commandOwner) handleLearnKey(key C.CommandKey) bool {
|
||||
owner.bound = true
|
||||
if key.pressed == 0 {
|
||||
owner.router.Handle(uint32(key.symbol), uint16(key.code), uint16(key.modifiers), false)
|
||||
return true
|
||||
}
|
||||
chord := owner.router.Chord(uint32(key.symbol), uint16(key.modifiers))
|
||||
_, command := owner.router.Handle(uint32(key.symbol), uint16(key.code), uint16(key.modifiers), true)
|
||||
action := input.LearnKey
|
||||
switch {
|
||||
case uint32(key.symbol) == 0xff1b || command == input.ToggleLearnMode:
|
||||
action = input.ToggleLearnMode
|
||||
case chord.Symbol == 0xffbe && chord.Modifiers == 0 && !chord.CthulhuModifier:
|
||||
action = input.LearnDocumentation
|
||||
case chord.Symbol == 0xffbf && chord.Modifiers == 0 && !chord.CthulhuModifier:
|
||||
action = input.LearnDefaultShortcuts
|
||||
case chord.Symbol == 0xffc0 && chord.Modifiers == 0 && !chord.CthulhuModifier:
|
||||
action = input.LearnApplicationShortcuts
|
||||
}
|
||||
if action != input.LearnKey {
|
||||
owner.learnMode = false
|
||||
owner.listener.learnMode.Store(false)
|
||||
}
|
||||
name := ""
|
||||
if nativeName := C.XKeysymToString(C.KeySym(key.symbol)); nativeName != nil {
|
||||
name = C.GoString(nativeName)
|
||||
}
|
||||
if owner.workerContext.Err() == nil && !owner.listener.enqueueSecureCommand(input.CommandEvent{Command: action, Timestamp: uint32(key.timestamp), Chord: chord, KeyName: name}) {
|
||||
owner.listener.failures <- errors.New("X11 learn mode queue overflow")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (owner *commandOwner) handleRoutedKey(key C.CommandKey) bool {
|
||||
consumed, command := owner.router.Handle(uint32(key.symbol), uint16(key.code), uint16(key.modifiers), key.pressed != 0)
|
||||
if key.pressed != 0 && !owner.router.IsModifier(uint32(key.symbol)) {
|
||||
if consumed {
|
||||
owner.bound = true
|
||||
} else if !owner.bound {
|
||||
owner.passThrough = true
|
||||
}
|
||||
}
|
||||
if command != "" {
|
||||
if owner.ocrReview && (command == input.OCRDismiss || command == input.OCRDismissAndPass) {
|
||||
owner.dismissOCR = true
|
||||
if command == input.OCRDismissAndPass {
|
||||
owner.bound = false
|
||||
owner.passThrough = true
|
||||
}
|
||||
}
|
||||
if command == input.ToggleLearnMode {
|
||||
if owner.ocrReview {
|
||||
owner.dismissOCR = true
|
||||
}
|
||||
owner.learnMode = true
|
||||
owner.listener.learnMode.Store(true)
|
||||
owner.listener.learnEcho.Store(true)
|
||||
}
|
||||
uiSession := uint64(0)
|
||||
if command == input.ShowActions {
|
||||
if owner.ocrReview && !owner.leave_ocr_review() {
|
||||
return false
|
||||
}
|
||||
var err error
|
||||
uiSession, err = owner.begin_internal_ui()
|
||||
if err != nil {
|
||||
// An unavailable modal grab is a failed command, not a failed reader.
|
||||
uiSession = 0
|
||||
}
|
||||
}
|
||||
if owner.workerContext.Err() == nil && !owner.listener.enqueueSecureCommand(input.CommandEvent{UISession: uiSession, Command: command, Timestamp: uint32(key.timestamp), Chord: owner.router.Chord(uint32(key.symbol), uint16(key.modifiers)), LearnModeStarted: command == input.ToggleLearnMode}) {
|
||||
owner.listener.failures <- errors.New("X11 command queue overflow")
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (owner *commandOwner) finishChord() bool {
|
||||
if !owner.bound && owner.device.capsCode != 0 && is_caps_lock_toggle(owner.buffered) {
|
||||
C.toggle_command_caps_lock(owner.device)
|
||||
if result := C.replay_command_keys(owner.device, &owner.buffered[0], C.int(len(owner.buffered))); result != 0 {
|
||||
owner.listener.failures <- fmt.Errorf("release Caps Lock toggle chord: native error %d", int(result))
|
||||
return false
|
||||
}
|
||||
} else if owner.passThrough || !owner.bound {
|
||||
result := C.replay_command_keys(owner.device, &owner.buffered[0], C.int(len(owner.buffered)))
|
||||
if result != 0 {
|
||||
owner.listener.failures <- fmt.Errorf("replay unbound X11 chord: native error %d", int(result))
|
||||
return false
|
||||
}
|
||||
} else if !owner.learnMode && owner.uiSession == 0 {
|
||||
C.release_command_keyboard(owner.device)
|
||||
}
|
||||
owner.router.Reset()
|
||||
owner.buffered = owner.buffered[:0]
|
||||
owner.bound = false
|
||||
owner.passThrough = false
|
||||
if owner.dismissOCR {
|
||||
owner.dismissOCR = false
|
||||
if !owner.leave_ocr_review() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
owner.listener.grabActive.Store(owner.learnMode || owner.uiSession != 0)
|
||||
owner.listener.uiEcho.Store(owner.uiSession != 0)
|
||||
owner.listener.learnMode.Store(owner.learnMode)
|
||||
owner.listener.learnEcho.Store(owner.learnMode)
|
||||
return true
|
||||
}
|
||||
Reference in new issue
Block a user