Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(input): un-expose Key.BaseRune + Key GoDocs #83

Merged
merged 4 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 7 additions & 13 deletions input/driver_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,11 @@ func parseConInputEvent(event coninput.InputRecord, ps *coninput.ButtonState) Ev
return event
}

// Get active keyboard layout
fgWin := windows.GetForegroundWindow()
fgThread, err := windows.GetWindowThreadProcessId(fgWin, nil)
if err != nil {
return event
}

layout := termwindows.GetKeyboardLayout(fgThread)
if layout == windows.InvalidHandle {
return event
}
// Always use US layout for translation
// This is to follow the behavior of the Kitty Keyboard base layout
// feature :eye_roll:
// https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-language-pack-default-values?view=windows-11
const usLayout = 0x409

// Translate key to rune
var keyState [256]byte
Expand All @@ -154,7 +148,7 @@ func parseConInputEvent(event coninput.InputRecord, ps *coninput.ButtonState) Ev
&utf16Buf[0],
int32(len(utf16Buf)),
dontChangeKernelKeyboardLayout,
layout,
usLayout,
)

// -1 indicates a dead key
Expand All @@ -169,7 +163,7 @@ func parseConInputEvent(event coninput.InputRecord, ps *coninput.ButtonState) Ev
return event
}

key.BaseRune = runes[0]
key.baseRune = runes[0]
if e.KeyDown {
return KeyDownEvent(key)
}
Expand Down
73 changes: 61 additions & 12 deletions input/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,31 +179,79 @@ const (

// Key represents a key event.
type Key struct {
Sym KeySym
Rune rune
AltRune rune
BaseRune rune
// Sym is a special key, like enter, tab, backspace, and so on.
Sym KeySym

// Mod is a modifier key, like ctrl, alt, and so on.
Mod KeyMod

// Rune is the actual character received. If the user presses shift+a, the
// Rune will be 'A'.
Rune rune

// AltRune is the actual, unshifted key pressed by the user. For example,
// if the user presses shift+a, or caps lock is on, the AltRune will be
// 'a'.
//
// In the case of non-latin keyboards, like Arabic, AltRune is the
// unshifted key on the keyboard.
//
// This is only available with the Kitty Keyboard Protocol or the Windows
// Console API.
AltRune rune

// baseRune is the key pressed according to the standard PC-101 key layout.
// On internaltional keyboards, this is the key that would be pressed if
// the keyboard was set to US layout.
//
// For example, if the user presses 'q' on a French AZERTY keyboard, the
// baseRune will be 'q'.
//
// This is only available with the Kitty Keyboard Protocol or the Windows
// Console API.
baseRune rune

// IsRepeat indicates whether the key is being held down and sending events
// repeatedly.
//
// This is only available with the Kitty Keyboard Protocol or the Windows
// Console API.
IsRepeat bool
Mod KeyMod
}

// KeyDownEvent represents a key down event.
type KeyDownEvent Key

// String implements fmt.Stringer.
// String implements fmt.Stringer and is quite useful for matching key
// events. For details, on what this returns see [Key.String].
func (k KeyDownEvent) String() string {
return Key(k).String()
}

// KeyUpEvent represents a key up event.
type KeyUpEvent Key

// String implements fmt.Stringer.
// String implements fmt.Stringer and is quite useful for matching complex key
// events. For details, on what this returns see [Key.String].
func (k KeyUpEvent) String() string {
return Key(k).String()
}

// String implements fmt.Stringer.
// String implements fmt.Stringer and is used to convert a key to a string.
// While less type safe than looking at the individual fields, it will usually
// be more convenient and readable to use this method when matching against
// keys.
//
// Note that modifier keys are always printed in the following order:
// - ctrl
// - alt
// - shift
// - meta
// - hyper
// - super
//
// For example, you'll always see "ctrl+shift+alt+a" and never
// "shift+ctrl+alt+a".
func (k Key) String() string {
var s string
if k.Mod.IsCtrl() && k.Sym != KeyLeftCtrl && k.Sym != KeyRightCtrl {
Expand Down Expand Up @@ -232,10 +280,10 @@ func (k Key) String() string {
}
return string(r)
}
if k.BaseRune != 0 {
// If a BaseRune is present, use it to represent a key using the standard
if k.baseRune != 0 {
// If a baseRune is present, use it to represent a key using the standard
// PC-101 key layout.
s += runeStr(k.BaseRune)
s += runeStr(k.baseRune)
} else if k.AltRune != 0 {
// Otherwise, use the AltRune aka the non-shifted one if present.
s += runeStr(k.AltRune)
Expand All @@ -248,7 +296,8 @@ func (k Key) String() string {
return s
}

// String implements fmt.Stringer.
// String implements fmt.Stringer and prints the string representation of a of
// a Symbol key.
func (k KeySym) String() string {
s, ok := keySymString[k]
if !ok {
Expand Down
2 changes: 1 addition & 1 deletion input/kitty.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func parseKittyKeyboard(csi *ansi.CsiSequence) Event {
// PC-101 key layout codepoint.
// This is useful to create an unambiguous mapping of keys
// when using a different language layout.
key.BaseRune = b
key.baseRune = b
}
fallthrough
case 2:
Expand Down
Loading