better input handling

This commit is contained in:
Liam Galvin 2018-08-14 17:44:25 +01:00
parent f185f655d1
commit bb38d22a60
3 changed files with 248 additions and 58 deletions

View File

@ -7,68 +7,250 @@ func (gui *GUI) char(w *glfw.Window, r rune) {
gui.terminal.Write([]byte(string(r))) gui.terminal.Write([]byte(string(r)))
} }
func modsPressed(pressed glfw.ModifierKey, mods ...glfw.ModifierKey) bool {
for _, mod := range mods {
if pressed&mod == 0 {
return false
}
pressed ^= mod
}
return pressed == 0
}
func (gui *GUI) key(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) { func (gui *GUI) key(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) {
if action == glfw.Repeat || action == glfw.Press { if action == glfw.Repeat || action == glfw.Press {
gui.logger.Debugf("KEY PRESS: key=0x%X scan=0x%X", key, scancode) gui.logger.Debugf("KEY PRESS: key=0x%X scan=0x%X", key, scancode)
switch true { switch true {
case mods&glfw.ModControl > 0:
if mods&glfw.ModShift > 0 { case modsPressed(mods, glfw.ModControl, glfw.ModShift):
// ctrl + shift + switch key {
switch key { case glfw.KeyV:
case glfw.KeyV: // todo handle both these errors
// todo handle both these errors if buf, err := gui.window.GetClipboardString(); err == nil {
if buf, err := gui.window.GetClipboardString(); err == nil { _ = gui.terminal.Write([]byte(buf))
_ = gui.terminal.Write([]byte(buf))
}
case glfw.KeySemicolon:
gui.config.Slomo = !gui.config.Slomo
} }
} else { case glfw.KeySemicolon:
// ctrl + gui.config.Slomo = !gui.config.Slomo
switch key { }
case glfw.KeyC: // ctrl^c case modsPressed(mods, glfw.ModControl):
gui.logger.Debugf("Sending CTRL^C") switch key {
gui.terminal.Write([]byte{0x3}) // send EOT case glfw.KeyC: // ctrl^c
gui.logger.Debugf("Sending CTRL^C")
gui.terminal.Write([]byte{0x3}) // send EOT
}
default: // no mods
switch key {
case glfw.KeyF1:
gui.terminal.Write([]byte{
0x1b,
'O',
'P',
})
case glfw.KeyF2:
gui.terminal.Write([]byte{
0x1b,
'O',
'Q',
})
case glfw.KeyF3:
gui.terminal.Write([]byte{
0x1b,
'O',
'R',
})
case glfw.KeyF4:
gui.terminal.Write([]byte{
0x1b,
'O',
'S',
})
case glfw.KeyF5:
gui.terminal.Write([]byte{
0x1b,
'[',
'1', '5', '~',
})
case glfw.KeyF6:
gui.terminal.Write([]byte{
0x1b,
'[',
'1', '7', '~',
})
case glfw.KeyF7:
gui.terminal.Write([]byte{
0x1b,
'[',
'1', '8', '~',
})
case glfw.KeyF8:
gui.terminal.Write([]byte{
0x1b,
'[',
'1', '9', '~',
})
case glfw.KeyF9:
gui.terminal.Write([]byte{
0x1b,
'[',
'2', '0', '~',
})
case glfw.KeyF10:
gui.terminal.Write([]byte{
0x1b,
'[',
'2', '1', '~',
})
case glfw.KeyF11:
gui.terminal.Write([]byte{
0x1b,
'[',
'2', '3', '~',
})
case glfw.KeyF12:
gui.terminal.Write([]byte{
0x1b,
'[',
'2', '4', '~',
})
case glfw.KeyInsert:
gui.terminal.Write([]byte{
0x1b,
'[',
'2', '~',
})
case glfw.KeyDelete:
gui.terminal.Write([]byte{
0x1b,
'[',
'3', '~',
})
case glfw.KeyHome:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'H',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'H',
})
}
case glfw.KeyEnd:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'F',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'F',
})
}
case glfw.KeyEscape:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
0x1b,
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
0x1b,
})
}
case glfw.KeyTab:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'I',
})
} else {
gui.terminal.Write([]byte{
0x09,
})
}
case glfw.KeyEnter:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'M',
})
} else {
gui.terminal.Write([]byte{0x0a})
}
case glfw.KeyBackspace:
gui.terminal.Write([]byte{0x08})
case glfw.KeyUp:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'A',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'A',
})
}
case glfw.KeyDown:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'B',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'B',
})
}
case glfw.KeyLeft:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'D',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'D',
})
}
case glfw.KeyRight:
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
gui.terminal.Write([]byte{
0x1b,
'O',
'C',
})
} else {
gui.terminal.Write([]byte{
0x1b,
'[',
'C',
})
} }
} }
}
switch key {
case glfw.KeyEnter:
gui.terminal.Write([]byte{0x0a})
case glfw.KeyBackspace:
gui.terminal.Write([]byte{0x08})
case glfw.KeyUp:
gui.terminal.Write([]byte{
0x1b,
'[',
'A',
})
case glfw.KeyDown:
gui.terminal.Write([]byte{
0x1b,
'[',
'B',
})
case glfw.KeyLeft:
gui.terminal.Write([]byte{
0x1b,
'[',
'D',
})
case glfw.KeyRight:
gui.terminal.Write([]byte{
0x1b,
'[',
'C',
})
case glfw.KeyTab:
gui.terminal.Write([]byte{
0x09,
})
} }
//gui.logger.Debugf("Key pressed: 0x%X %q", key, string([]byte{byte(key)})) //gui.logger.Debugf("Key pressed: 0x%X %q", key, string([]byte{byte(key)}))

View File

@ -41,7 +41,7 @@ func (terminal *Terminal) processInput(ctx context.Context, pty chan rune) {
if ok { if ok {
if err := handler(pty, terminal); err != nil { if err := handler(pty, terminal); err != nil {
terminal.logger.Errorf("Error handling escape sequence 0x%X: %s", b, err) terminal.logger.Errorf("Error handling escape sequence: %s", err)
} }
continue continue
} }
@ -49,18 +49,22 @@ func (terminal *Terminal) processInput(ctx context.Context, pty chan rune) {
terminal.logger.Debugf("Received character 0x%X: %q", b, string(b)) terminal.logger.Debugf("Received character 0x%X: %q", b, string(b))
switch b { switch b {
case 0x0a: case 0x0a, 0x0c, 0x0b: // LF, FF, VT
terminal.ActiveBuffer().NewLine() terminal.ActiveBuffer().NewLine()
case 0x0d: case 0x0d: // CR
terminal.ActiveBuffer().CarriageReturn() terminal.ActiveBuffer().CarriageReturn()
case 0x08: case 0x08: // BS
// backspace // backspace
terminal.ActiveBuffer().Backspace() terminal.ActiveBuffer().Backspace()
case 0x07: case 0x07: // BEL
// @todo ring bell - flash red or some shit? // @todo ring bell - flash red or some shit?
case 0x05: // ENQ
terminal.logger.Errorf("Received ENQ!")
case 0xe, 0xf:
terminal.logger.Errorf("Received SI/SO")
case 0x09:
terminal.logger.Errorf("Received TAB")
default: default:
// render character at current location
// fmt.Printf("%s\n", string([]byte{b}))
if b >= 0x20 { if b >= 0x20 {
terminal.ActiveBuffer().Write(b) terminal.ActiveBuffer().Write(b)
} else { } else {

View File

@ -90,6 +90,10 @@ func New(pty *os.File, logger *zap.SugaredLogger, config *config.Config) *Termin
} }
} }
func (terminal *Terminal) IsApplicationCursorKeysModeEnabled() bool {
return terminal.modes.ApplicationCursorKeys
}
func (terminal *Terminal) SetMouseMode(mode MouseMode) { func (terminal *Terminal) SetMouseMode(mode MouseMode) {
terminal.mouseMode = mode terminal.mouseMode = mode
} }