From 65b038d64ac68f790b8553a54fc872d480f6995a Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Thu, 19 Sep 2024 12:37:07 -0400 Subject: [PATCH] fix: kitty: support faulty c0 mappings Some terminals such as WezTerm report incorrect press and release sequences when "report event types" enhancement is enabled. This patch adds support for these faulty mappings. Related: https://github.com/wez/wezterm/issues/6160 --- kitty.go | 258 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 137 insertions(+), 121 deletions(-) diff --git a/kitty.go b/kitty.go index 3023e636b7..48e5314ee9 100644 --- a/kitty.go +++ b/kitty.go @@ -8,124 +8,140 @@ import ( ) // Kitty Clipboard Control Sequences -var kittyKeyMap = map[int]rune{ - ansi.BS: KeyBackspace, - ansi.HT: KeyTab, - ansi.CR: KeyEnter, - ansi.ESC: KeyEscape, - ansi.DEL: KeyBackspace, +var kittyKeyMap = map[int]Key{ + ansi.BS: {Code: KeyBackspace}, + ansi.HT: {Code: KeyTab}, + ansi.CR: {Code: KeyEnter}, + ansi.ESC: {Code: KeyEscape}, + ansi.DEL: {Code: KeyBackspace}, - 57344: KeyEscape, - 57345: KeyEnter, - 57346: KeyTab, - 57347: KeyBackspace, - 57348: KeyInsert, - 57349: KeyDelete, - 57350: KeyLeft, - 57351: KeyRight, - 57352: KeyUp, - 57353: KeyDown, - 57354: KeyPgUp, - 57355: KeyPgDown, - 57356: KeyHome, - 57357: KeyEnd, - 57358: KeyCapsLock, - 57359: KeyScrollLock, - 57360: KeyNumLock, - 57361: KeyPrintScreen, - 57362: KeyPause, - 57363: KeyMenu, - 57364: KeyF1, - 57365: KeyF2, - 57366: KeyF3, - 57367: KeyF4, - 57368: KeyF5, - 57369: KeyF6, - 57370: KeyF7, - 57371: KeyF8, - 57372: KeyF9, - 57373: KeyF10, - 57374: KeyF11, - 57375: KeyF12, - 57376: KeyF13, - 57377: KeyF14, - 57378: KeyF15, - 57379: KeyF16, - 57380: KeyF17, - 57381: KeyF18, - 57382: KeyF19, - 57383: KeyF20, - 57384: KeyF21, - 57385: KeyF22, - 57386: KeyF23, - 57387: KeyF24, - 57388: KeyF25, - 57389: KeyF26, - 57390: KeyF27, - 57391: KeyF28, - 57392: KeyF29, - 57393: KeyF30, - 57394: KeyF31, - 57395: KeyF32, - 57396: KeyF33, - 57397: KeyF34, - 57398: KeyF35, - 57399: KeyKp0, - 57400: KeyKp1, - 57401: KeyKp2, - 57402: KeyKp3, - 57403: KeyKp4, - 57404: KeyKp5, - 57405: KeyKp6, - 57406: KeyKp7, - 57407: KeyKp8, - 57408: KeyKp9, - 57409: KeyKpDecimal, - 57410: KeyKpDivide, - 57411: KeyKpMultiply, - 57412: KeyKpMinus, - 57413: KeyKpPlus, - 57414: KeyKpEnter, - 57415: KeyKpEqual, - 57416: KeyKpSep, - 57417: KeyKpLeft, - 57418: KeyKpRight, - 57419: KeyKpUp, - 57420: KeyKpDown, - 57421: KeyKpPgUp, - 57422: KeyKpPgDown, - 57423: KeyKpHome, - 57424: KeyKpEnd, - 57425: KeyKpInsert, - 57426: KeyKpDelete, - 57427: KeyKpBegin, - 57428: KeyMediaPlay, - 57429: KeyMediaPause, - 57430: KeyMediaPlayPause, - 57431: KeyMediaReverse, - 57432: KeyMediaStop, - 57433: KeyMediaFastForward, - 57434: KeyMediaRewind, - 57435: KeyMediaNext, - 57436: KeyMediaPrev, - 57437: KeyMediaRecord, - 57438: KeyLowerVol, - 57439: KeyRaiseVol, - 57440: KeyMute, - 57441: KeyLeftShift, - 57442: KeyLeftCtrl, - 57443: KeyLeftAlt, - 57444: KeyLeftSuper, - 57445: KeyLeftHyper, - 57446: KeyLeftMeta, - 57447: KeyRightShift, - 57448: KeyRightCtrl, - 57449: KeyRightAlt, - 57450: KeyRightSuper, - 57451: KeyRightHyper, - 57452: KeyRightMeta, - 57453: KeyIsoLevel3Shift, - 57454: KeyIsoLevel5Shift, + 57344: {Code: KeyEscape}, + 57345: {Code: KeyEnter}, + 57346: {Code: KeyTab}, + 57347: {Code: KeyBackspace}, + 57348: {Code: KeyInsert}, + 57349: {Code: KeyDelete}, + 57350: {Code: KeyLeft}, + 57351: {Code: KeyRight}, + 57352: {Code: KeyUp}, + 57353: {Code: KeyDown}, + 57354: {Code: KeyPgUp}, + 57355: {Code: KeyPgDown}, + 57356: {Code: KeyHome}, + 57357: {Code: KeyEnd}, + 57358: {Code: KeyCapsLock}, + 57359: {Code: KeyScrollLock}, + 57360: {Code: KeyNumLock}, + 57361: {Code: KeyPrintScreen}, + 57362: {Code: KeyPause}, + 57363: {Code: KeyMenu}, + 57364: {Code: KeyF1}, + 57365: {Code: KeyF2}, + 57366: {Code: KeyF3}, + 57367: {Code: KeyF4}, + 57368: {Code: KeyF5}, + 57369: {Code: KeyF6}, + 57370: {Code: KeyF7}, + 57371: {Code: KeyF8}, + 57372: {Code: KeyF9}, + 57373: {Code: KeyF10}, + 57374: {Code: KeyF11}, + 57375: {Code: KeyF12}, + 57376: {Code: KeyF13}, + 57377: {Code: KeyF14}, + 57378: {Code: KeyF15}, + 57379: {Code: KeyF16}, + 57380: {Code: KeyF17}, + 57381: {Code: KeyF18}, + 57382: {Code: KeyF19}, + 57383: {Code: KeyF20}, + 57384: {Code: KeyF21}, + 57385: {Code: KeyF22}, + 57386: {Code: KeyF23}, + 57387: {Code: KeyF24}, + 57388: {Code: KeyF25}, + 57389: {Code: KeyF26}, + 57390: {Code: KeyF27}, + 57391: {Code: KeyF28}, + 57392: {Code: KeyF29}, + 57393: {Code: KeyF30}, + 57394: {Code: KeyF31}, + 57395: {Code: KeyF32}, + 57396: {Code: KeyF33}, + 57397: {Code: KeyF34}, + 57398: {Code: KeyF35}, + 57399: {Code: KeyKp0}, + 57400: {Code: KeyKp1}, + 57401: {Code: KeyKp2}, + 57402: {Code: KeyKp3}, + 57403: {Code: KeyKp4}, + 57404: {Code: KeyKp5}, + 57405: {Code: KeyKp6}, + 57406: {Code: KeyKp7}, + 57407: {Code: KeyKp8}, + 57408: {Code: KeyKp9}, + 57409: {Code: KeyKpDecimal}, + 57410: {Code: KeyKpDivide}, + 57411: {Code: KeyKpMultiply}, + 57412: {Code: KeyKpMinus}, + 57413: {Code: KeyKpPlus}, + 57414: {Code: KeyKpEnter}, + 57415: {Code: KeyKpEqual}, + 57416: {Code: KeyKpSep}, + 57417: {Code: KeyKpLeft}, + 57418: {Code: KeyKpRight}, + 57419: {Code: KeyKpUp}, + 57420: {Code: KeyKpDown}, + 57421: {Code: KeyKpPgUp}, + 57422: {Code: KeyKpPgDown}, + 57423: {Code: KeyKpHome}, + 57424: {Code: KeyKpEnd}, + 57425: {Code: KeyKpInsert}, + 57426: {Code: KeyKpDelete}, + 57427: {Code: KeyKpBegin}, + 57428: {Code: KeyMediaPlay}, + 57429: {Code: KeyMediaPause}, + 57430: {Code: KeyMediaPlayPause}, + 57431: {Code: KeyMediaReverse}, + 57432: {Code: KeyMediaStop}, + 57433: {Code: KeyMediaFastForward}, + 57434: {Code: KeyMediaRewind}, + 57435: {Code: KeyMediaNext}, + 57436: {Code: KeyMediaPrev}, + 57437: {Code: KeyMediaRecord}, + 57438: {Code: KeyLowerVol}, + 57439: {Code: KeyRaiseVol}, + 57440: {Code: KeyMute}, + 57441: {Code: KeyLeftShift}, + 57442: {Code: KeyLeftCtrl}, + 57443: {Code: KeyLeftAlt}, + 57444: {Code: KeyLeftSuper}, + 57445: {Code: KeyLeftHyper}, + 57446: {Code: KeyLeftMeta}, + 57447: {Code: KeyRightShift}, + 57448: {Code: KeyRightCtrl}, + 57449: {Code: KeyRightAlt}, + 57450: {Code: KeyRightSuper}, + 57451: {Code: KeyRightHyper}, + 57452: {Code: KeyRightMeta}, + 57453: {Code: KeyIsoLevel3Shift}, + 57454: {Code: KeyIsoLevel5Shift}, +} + +func init() { + // These are some faulty C0 mappings some terminals such as WezTerm have + // and doesn't follow the specs. + kittyKeyMap[ansi.NUL] = Key{Code: KeySpace, Mod: ModCtrl} + for i := ansi.SOH; i <= ansi.SUB; i++ { + if _, ok := kittyKeyMap[i]; !ok { + kittyKeyMap[i] = Key{Code: rune(i + 0x60), Mod: ModCtrl} + } + } + for i := ansi.FS; i <= ansi.US; i++ { + if _, ok := kittyKeyMap[i]; !ok { + kittyKeyMap[i] = Key{Code: rune(i + 0x40), Mod: ModCtrl} + } + } } const ( @@ -183,13 +199,13 @@ func fromKittyMod(mod int) KeyMod { // See https://sw.kovidgoyal.net/kitty/keyboard-protocol/ func parseKittyKeyboard(csi *ansi.CsiSequence) Msg { var isRelease bool - key := Key{} + var key Key if params := csi.Subparams(0); len(params) > 0 { + var foundKey bool code := params[0] - if sym, ok := kittyKeyMap[code]; ok { - key.Code = sym - } else { + key, foundKey = kittyKeyMap[code] + if !foundKey { r := rune(code) if !utf8.ValidRune(r) { r = utf8.RuneError