Skip to content

Commit

Permalink
improve key input handling
Browse files Browse the repository at this point in the history
  • Loading branch information
akiyosi committed Jan 29, 2024
1 parent 7d02616 commit 5f7ed25
Show file tree
Hide file tree
Showing 5 changed files with 499 additions and 358 deletions.
346 changes: 0 additions & 346 deletions editor/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"strings"
"sync"
"time"
"unicode"

"github.com/akiyosi/goneovim/util"
frameless "github.com/akiyosi/goqtframelesswindow"
Expand Down Expand Up @@ -1180,351 +1179,6 @@ func (e *Editor) workspaceUpdate() {
}
}

func (e *Editor) keyRelease(event *gui.QKeyEvent) {
if !e.isKeyAutoRepeating {
return
}

if editor.config.Editor.SmoothScroll {
ws := e.workspaces[e.active]
win, ok := ws.screen.getWindow(ws.cursor.gridid)
if !ok {
return
}
if win.scrollPixels2 != 0 {
return
}
win.grabScreenSnapshot()
}

e.isKeyAutoRepeating = false
}

func (e *Editor) keyPress(event *gui.QKeyEvent) {
if len(e.workspaces) <= e.active {
return
}
ws := e.workspaces[e.active]
if ws.nvim == nil {
return
}
if !e.isKeyAutoRepeating {
ws.getSnapshot()
}
if !e.isHideMouse && e.config.Editor.HideMouseWhenTyping {
bc := gui.NewQCursor2(core.Qt__BlankCursor)
gui.QGuiApplication_SetOverrideCursor(bc)
gui.QGuiApplication_ChangeOverrideCursor(bc)
e.isHideMouse = true
}

input := e.convertKey(event)

e.putLog("key input for nvim::", "input:", input)
if event.IsAutoRepeat() {
e.isKeyAutoRepeating = true
}
if input != "" {
ws.nvim.Input(input)
}
}

func keyToText(key int, mod core.Qt__KeyboardModifier) string {
text := string(rune(key))
if !(mod&core.Qt__ShiftModifier > 0) {
text = strings.ToLower(text)
}

return text
}

// controlModifier is
func controlModifier() (controlModifier core.Qt__KeyboardModifier) {
if runtime.GOOS == "windows" {
controlModifier = core.Qt__ControlModifier
}
if runtime.GOOS == "linux" {
controlModifier = core.Qt__ControlModifier
}
if runtime.GOOS == "darwin" {
controlModifier = core.Qt__MetaModifier
}

return
}

// cmdModifier is
func cmdModifier() (cmdModifier core.Qt__KeyboardModifier) {
if runtime.GOOS == "windows" {
cmdModifier = core.Qt__NoModifier
}
if runtime.GOOS == "linux" {
cmdModifier = core.Qt__MetaModifier
}
if runtime.GOOS == "darwin" {
cmdModifier = core.Qt__ControlModifier
}

return
}

func isAsciiCharRequiringAlt(key int, mod core.Qt__KeyboardModifier, c rune) bool {
// Ignore all key events where Alt is not pressed
if !(mod&core.Qt__AltModifier > 0) {
return false
}

// These low-ascii characters may require AltModifier on MacOS
if (c == '[' && key != int(core.Qt__Key_BracketLeft)) ||
(c == ']' && key != int(core.Qt__Key_BracketRight)) ||
(c == '{' && key != int(core.Qt__Key_BraceLeft)) ||
(c == '}' && key != int(core.Qt__Key_BraceRight)) ||
(c == '|' && key != int(core.Qt__Key_Bar)) ||
(c == '~' && key != int(core.Qt__Key_AsciiTilde)) ||
(c == '@' && key != int(core.Qt__Key_At)) {
return true
}

return false
}

func (e *Editor) convertKey(event *gui.QKeyEvent) string {
text := event.Text()
key := event.Key()
mod := event.Modifiers()

if e.opts.Debug != "" {
e.putLog("key input(raw)::", fmt.Sprintf("text: %s, key: %d, mod: %v", text, key, mod))
}

// this is macmeta alternatively
if e.config.Editor.Macmeta {
if mod&core.Qt__AltModifier > 0 && mod&core.Qt__ShiftModifier > 0 {
text = string(rune(key))
} else if mod&core.Qt__AltModifier > 0 && !(mod&core.Qt__ShiftModifier > 0) {
text = strings.ToLower(string(rune(key)))
}
}

if mod&core.Qt__KeypadModifier > 0 {
keypadKeys := map[core.Qt__Key]string{
core.Qt__Key_Home: "kHome",
core.Qt__Key_End: "kEnd",
core.Qt__Key_PageUp: "kPageUp",
core.Qt__Key_PageDown: "kPageDown",
core.Qt__Key_Plus: "kPlus",
core.Qt__Key_Minus: "kMinus",
core.Qt__Key_multiply: "kMultiply",
core.Qt__Key_division: "kDivide",
core.Qt__Key_Enter: "kEnter",
core.Qt__Key_Period: "kPoint",
core.Qt__Key_0: "k0",
core.Qt__Key_1: "k1",
core.Qt__Key_2: "k2",
core.Qt__Key_3: "k3",
core.Qt__Key_4: "k4",
core.Qt__Key_5: "k5",
core.Qt__Key_6: "k6",
core.Qt__Key_7: "k7",
core.Qt__Key_8: "k8",
core.Qt__Key_9: "k9",
}

if value, ok := keypadKeys[core.Qt__Key(key)]; ok {
return fmt.Sprintf("<%s%s>", e.modPrefix(mod), value)
}
}

specialKey, ok := e.specialKeys[core.Qt__Key(key)]
if ok {
if key == int(core.Qt__Key_Space) || key == int(core.Qt__Key_Backspace) {
mod &= ^core.Qt__ShiftModifier
}
return fmt.Sprintf("<%s%s>", e.modPrefix(mod), specialKey)
}

if text == "<" {
modNoShift := mod & ^core.Qt__ShiftModifier
return fmt.Sprintf("<%s%s>", e.modPrefix(modNoShift), "lt")
}

isCaretKey := key == int(core.Qt__Key_6) || key == int(core.Qt__Key_AsciiCircum)

// Normalize modifiers, CTRL+^ always sends as <C-^>
if isCaretKey && (mod&controlModifier() > 0) {
modNoShiftMeta := mod & ^core.Qt__ShiftModifier & ^cmdModifier()
return fmt.Sprintf("<%s%s>", e.modPrefix(modNoShiftMeta), "^")
}

if text == "\\" {
return fmt.Sprintf("<%s%s>", e.modPrefix(mod), "Bslash")
}

rtext := []rune(text)
isGraphic := false
if len(rtext) > 0 {
isGraphic = unicode.IsGraphic(rtext[0])
}
if text == "" || !isGraphic {
if key == int(core.Qt__Key_Alt) ||
key == int(core.Qt__Key_AltGr) ||
key == int(core.Qt__Key_CapsLock) ||
key == int(core.Qt__Key_Control) ||
key == int(core.Qt__Key_Meta) ||
key == int(core.Qt__Key_Shift) ||
key == int(core.Qt__Key_Super_L) ||
key == int(core.Qt__Key_Super_R) {
return ""
}

// Ignore special keys
if key == int(core.Qt__Key_VolumeDown) ||
key == int(core.Qt__Key_VolumeMute) ||
key == int(core.Qt__Key_VolumeUp) {
return ""
}

text = keyToText(key, mod)
}
c := text
if c == "" {
return ""
}

char := []rune(c)[0]
// char := core.NewQChar11(c)

// Remove SHIFT
if (int(char) >= 0x80 || unicode.IsPrint(char)) && !(mod&controlModifier() > 0) && !(mod&cmdModifier() > 0) {
mod &= ^core.Qt__ShiftModifier
}
// if (char.Unicode() >= 0x80 || char.IsPrint()) && !(mod&controlModifier() > 0) && !(mod&cmdModifier() > 0) {
// mod &= ^core.Qt__ShiftModifier
// }

// Remove CTRL
if int(char) < 0x20 {
text = keyToText(key, mod)
}
// if char.Unicode() < 0x20 {
// text = keyToText(key, mod)
// }

if runtime.GOOS == "darwin" {
// Remove ALT/OPTION
if int(char) >= 0x80 && unicode.IsPrint(char) {
mod &= ^core.Qt__AltModifier
}
// if char.Unicode() >= 0x80 && char.IsPrint() {
// mod &= ^core.Qt__AltModifier
// }

// Some locales require Alt for basic low-ascii characters,
// remove AltModifer. Ex) German layouts use Alt for "{".
if isAsciiCharRequiringAlt(key, mod, []rune(c)[0]) {
mod &= ^core.Qt__AltModifier
}

}

prefix := e.modPrefix(mod)
if prefix != "" {
return fmt.Sprintf("<%s%s>", prefix, c)
}

return c
}

func (e *Editor) modPrefix(mod core.Qt__KeyboardModifier) string {
prefix := ""
if runtime.GOOS == "windows" {
if mod&controlModifier() > 0 && !(mod&core.Qt__AltModifier > 0) {
prefix += "C-"
}
if mod&core.Qt__ShiftModifier > 0 {
prefix += "S-"
}
if mod&core.Qt__AltModifier > 0 && !(mod&controlModifier() > 0) {
prefix += e.prefixToMapMetaKey
}
} else {
if mod&cmdModifier() > 0 {
prefix += "D-"
}
if mod&controlModifier() > 0 {
prefix += "C-"
}
if mod&core.Qt__ShiftModifier > 0 {
prefix += "S-"
}
if mod&core.Qt__AltModifier > 0 {
prefix += e.prefixToMapMetaKey
}
}

return prefix
}

func (e *Editor) initSpecialKeys() {
e.specialKeys = map[core.Qt__Key]string{}
e.specialKeys[core.Qt__Key_Up] = "Up"
e.specialKeys[core.Qt__Key_Down] = "Down"
e.specialKeys[core.Qt__Key_Left] = "Left"
e.specialKeys[core.Qt__Key_Right] = "Right"

e.specialKeys[core.Qt__Key_F1] = "F1"
e.specialKeys[core.Qt__Key_F2] = "F2"
e.specialKeys[core.Qt__Key_F3] = "F3"
e.specialKeys[core.Qt__Key_F4] = "F4"
e.specialKeys[core.Qt__Key_F5] = "F5"
e.specialKeys[core.Qt__Key_F6] = "F6"
e.specialKeys[core.Qt__Key_F7] = "F7"
e.specialKeys[core.Qt__Key_F8] = "F8"
e.specialKeys[core.Qt__Key_F9] = "F9"
e.specialKeys[core.Qt__Key_F10] = "F10"
e.specialKeys[core.Qt__Key_F11] = "F11"
e.specialKeys[core.Qt__Key_F12] = "F12"
e.specialKeys[core.Qt__Key_F13] = "F13"
e.specialKeys[core.Qt__Key_F14] = "F14"
e.specialKeys[core.Qt__Key_F15] = "F15"
e.specialKeys[core.Qt__Key_F16] = "F16"
e.specialKeys[core.Qt__Key_F17] = "F17"
e.specialKeys[core.Qt__Key_F18] = "F18"
e.specialKeys[core.Qt__Key_F19] = "F19"
e.specialKeys[core.Qt__Key_F20] = "F20"
e.specialKeys[core.Qt__Key_F21] = "F21"
e.specialKeys[core.Qt__Key_F22] = "F22"
e.specialKeys[core.Qt__Key_F23] = "F23"
e.specialKeys[core.Qt__Key_F24] = "F24"
e.specialKeys[core.Qt__Key_Backspace] = "BS"
e.specialKeys[core.Qt__Key_Delete] = "Del"
e.specialKeys[core.Qt__Key_Insert] = "Insert"
e.specialKeys[core.Qt__Key_Home] = "Home"
e.specialKeys[core.Qt__Key_End] = "End"
e.specialKeys[core.Qt__Key_PageUp] = "PageUp"
e.specialKeys[core.Qt__Key_PageDown] = "PageDown"
e.specialKeys[core.Qt__Key_Return] = "Enter"
e.specialKeys[core.Qt__Key_Enter] = "Enter"
e.specialKeys[core.Qt__Key_Tab] = "Tab"
e.specialKeys[core.Qt__Key_Backtab] = "Tab"
e.specialKeys[core.Qt__Key_Escape] = "Esc"
e.specialKeys[core.Qt__Key_Backslash] = "Bslash"
e.specialKeys[core.Qt__Key_Space] = "Space"

if runtime.GOOS == "darwin" {
e.keyControl = core.Qt__Key_Meta
e.keyCmd = core.Qt__Key_Control
} else if runtime.GOOS == "windows" {
e.keyControl = core.Qt__Key_Control
e.keyCmd = (core.Qt__Key)(0)
} else {
e.keyControl = core.Qt__Key_Control
e.keyCmd = core.Qt__Key_Meta
}

e.prefixToMapMetaKey = "A-"
}

func (e *Editor) close(exitcode int) {
e.stopOnce.Do(func() {
e.stop <- exitcode
Expand Down
Loading

0 comments on commit 5f7ed25

Please sign in to comment.