mirror of https://github.com/liamg/aminal.git
306 lines
5.8 KiB
Go
306 lines
5.8 KiB
Go
package gui
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/go-gl/glfw/v3.3/glfw"
|
|
)
|
|
|
|
// send typed runes straight through to the pty
|
|
func (gui *GUI) char(w *glfw.Window, r rune) {
|
|
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 getModStr(mods glfw.ModifierKey) string {
|
|
switch true {
|
|
case modsPressed(mods, glfw.ModControl, glfw.ModShift, glfw.ModAlt):
|
|
return "8"
|
|
case modsPressed(mods, glfw.ModControl, glfw.ModAlt):
|
|
return "7"
|
|
case modsPressed(mods, glfw.ModControl, glfw.ModShift):
|
|
return "6"
|
|
case modsPressed(mods, glfw.ModControl):
|
|
return "5"
|
|
case modsPressed(mods, glfw.ModAlt, glfw.ModShift):
|
|
return "4"
|
|
case modsPressed(mods, glfw.ModAlt):
|
|
return "3"
|
|
case modsPressed(mods, glfw.ModShift):
|
|
return "2"
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
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 gui.overlay != nil {
|
|
if key == glfw.KeyEscape {
|
|
gui.setOverlay(nil)
|
|
}
|
|
}
|
|
|
|
// get key name to handle alternative keyboard layouts
|
|
name := glfw.GetKeyName(key, scancode)
|
|
if len(name) == 1 {
|
|
r := rune(strings.ToLower(name)[0])
|
|
for userAction, shortcut := range gui.keyboardShortcuts {
|
|
if shortcut.Match(mods, r) {
|
|
f, ok := actionMap[userAction]
|
|
if ok {
|
|
f(gui)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// standard ctrl codes e.g. ^C
|
|
if modsPressed(mods, glfw.ModControl) {
|
|
if r >= 97 && r < 123 {
|
|
gui.terminal.Write([]byte{byte(r) - 96})
|
|
return
|
|
} else if r >= 65 && r < 91 {
|
|
gui.terminal.Write([]byte{byte(r) - 64})
|
|
return
|
|
}
|
|
}
|
|
|
|
// pass through alt codes
|
|
if modsPressed(mods, glfw.ModAlt) {
|
|
if r >= 97 && r < 123 || r >= 65 && r < 91 {
|
|
gui.terminal.Write([]byte{0x1b, byte(r)})
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
modStr := getModStr(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() {
|
|
if modStr == "" {
|
|
gui.terminal.Write([]byte("\x1b[1~"))
|
|
} else {
|
|
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[1;%s~", modStr)))
|
|
}
|
|
} else {
|
|
gui.terminal.Write([]byte("\x1b[H"))
|
|
}
|
|
case glfw.KeyEnd:
|
|
if modStr == "" {
|
|
gui.terminal.Write([]byte("\x1b[4~"))
|
|
} else {
|
|
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[4;%s~", modStr)))
|
|
}
|
|
case glfw.KeyPageUp:
|
|
if modStr == "" {
|
|
gui.terminal.Write([]byte("\x1b[5~"))
|
|
} else {
|
|
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[5;%s~", modStr)))
|
|
}
|
|
case glfw.KeyPageDown:
|
|
if modStr == "" {
|
|
gui.terminal.Write([]byte("\x1b[6~"))
|
|
} else {
|
|
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[6;%s~", modStr)))
|
|
}
|
|
case glfw.KeyEscape:
|
|
gui.terminal.Write([]byte{
|
|
0x1b,
|
|
})
|
|
case glfw.KeyTab:
|
|
gui.terminal.Write([]byte{
|
|
0x09,
|
|
})
|
|
case glfw.KeyEnter:
|
|
gui.terminal.WriteReturn()
|
|
case glfw.KeyKPEnter:
|
|
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
|
|
gui.terminal.Write([]byte{
|
|
0x1b,
|
|
'O',
|
|
'M',
|
|
})
|
|
} else {
|
|
gui.terminal.WriteReturn()
|
|
}
|
|
case glfw.KeyBackspace:
|
|
if modsPressed(mods, glfw.ModAlt) {
|
|
gui.terminal.Write([]byte{0x17}) // ctrl-w/delete word
|
|
} else {
|
|
gui.terminal.Write([]byte{0x7f}) // 0x7f is DEL
|
|
}
|
|
case glfw.KeyUp:
|
|
if modStr != "" {
|
|
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[1;%sA", modStr)))
|
|
}
|
|
|
|
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
|
|
gui.terminal.Write([]byte{
|
|
0x1b,
|
|
'O',
|
|
'A',
|
|
})
|
|
} else {
|
|
gui.terminal.Write([]byte{
|
|
0x1b,
|
|
'[',
|
|
'A',
|
|
})
|
|
}
|
|
case glfw.KeyDown:
|
|
|
|
if modStr != "" {
|
|
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[1;%sB", modStr)))
|
|
}
|
|
|
|
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
|
|
gui.terminal.Write([]byte{
|
|
0x1b,
|
|
'O',
|
|
'B',
|
|
})
|
|
} else {
|
|
gui.terminal.Write([]byte{
|
|
0x1b,
|
|
'[',
|
|
'B',
|
|
})
|
|
}
|
|
case glfw.KeyLeft:
|
|
if modStr != "" {
|
|
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[1;%sD", modStr)))
|
|
}
|
|
|
|
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
|
|
gui.terminal.Write([]byte{
|
|
0x1b,
|
|
'O',
|
|
'D',
|
|
})
|
|
} else {
|
|
gui.terminal.Write([]byte{
|
|
0x1b,
|
|
'[',
|
|
'D',
|
|
})
|
|
}
|
|
case glfw.KeyRight:
|
|
if modStr != "" {
|
|
gui.terminal.Write([]byte(fmt.Sprintf("\x1b[1;%sC", modStr)))
|
|
}
|
|
|
|
if gui.terminal.IsApplicationCursorKeysModeEnabled() {
|
|
gui.terminal.Write([]byte{
|
|
0x1b,
|
|
'O',
|
|
'C',
|
|
})
|
|
} else {
|
|
gui.terminal.Write([]byte{
|
|
0x1b,
|
|
'[',
|
|
'C',
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|