fix(windows): resolve numlock and French keyboard input issues (#1165)

This commit is contained in:
b0tmtl 2025-07-20 06:28:15 -04:00 committed by GitHub
parent 6232e0fc58
commit 8bf2eeccd0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -463,28 +463,41 @@ func (p *Parser) parseWin32InputKeyEvent(state *win32InputState, vkc uint16, _ u
baseCode = KeyMediaStop baseCode = KeyMediaStop
case vkc == xwindows.VK_MEDIA_PLAY_PAUSE: case vkc == xwindows.VK_MEDIA_PLAY_PAUSE:
baseCode = KeyMediaPlayPause baseCode = KeyMediaPlayPause
case vkc == xwindows.VK_OEM_1: case vkc == xwindows.VK_OEM_1, vkc == xwindows.VK_OEM_PLUS, vkc == xwindows.VK_OEM_COMMA,
baseCode = ';' vkc == xwindows.VK_OEM_MINUS, vkc == xwindows.VK_OEM_PERIOD, vkc == xwindows.VK_OEM_2,
case vkc == xwindows.VK_OEM_PLUS: vkc == xwindows.VK_OEM_3, vkc == xwindows.VK_OEM_4, vkc == xwindows.VK_OEM_5,
baseCode = '+' vkc == xwindows.VK_OEM_6, vkc == xwindows.VK_OEM_7:
case vkc == xwindows.VK_OEM_COMMA: // Use the actual character provided by Windows for current keyboard layout
baseCode = ',' // instead of hardcoded US layout mappings
case vkc == xwindows.VK_OEM_MINUS: if !unicode.IsControl(r) && unicode.IsPrint(r) {
baseCode = '-' baseCode = r
case vkc == xwindows.VK_OEM_PERIOD: } else {
baseCode = '.' // Fallback to original hardcoded mappings for non-printable cases
case vkc == xwindows.VK_OEM_2: switch vkc {
baseCode = '/' case xwindows.VK_OEM_1:
case vkc == xwindows.VK_OEM_3: baseCode = ';'
baseCode = '`' case xwindows.VK_OEM_PLUS:
case vkc == xwindows.VK_OEM_4: baseCode = '+'
baseCode = '[' case xwindows.VK_OEM_COMMA:
case vkc == xwindows.VK_OEM_5: baseCode = ','
baseCode = '\\' case xwindows.VK_OEM_MINUS:
case vkc == xwindows.VK_OEM_6: baseCode = '-'
baseCode = ']' case xwindows.VK_OEM_PERIOD:
case vkc == xwindows.VK_OEM_7: baseCode = '.'
baseCode = '\'' case xwindows.VK_OEM_2:
baseCode = '/'
case xwindows.VK_OEM_3:
baseCode = '`'
case xwindows.VK_OEM_4:
baseCode = '['
case xwindows.VK_OEM_5:
baseCode = '\\'
case xwindows.VK_OEM_6:
baseCode = ']'
case xwindows.VK_OEM_7:
baseCode = '\''
}
}
} }
if utf16.IsSurrogate(r) { if utf16.IsSurrogate(r) {
@ -500,20 +513,29 @@ func (p *Parser) parseWin32InputKeyEvent(state *win32InputState, vkc uint16, _ u
// XXX: Should this be a KeyMod? // XXX: Should this be a KeyMod?
altGr := cks&(xwindows.LEFT_CTRL_PRESSED|xwindows.RIGHT_ALT_PRESSED) == xwindows.LEFT_CTRL_PRESSED|xwindows.RIGHT_ALT_PRESSED altGr := cks&(xwindows.LEFT_CTRL_PRESSED|xwindows.RIGHT_ALT_PRESSED) == xwindows.LEFT_CTRL_PRESSED|xwindows.RIGHT_ALT_PRESSED
// FIXED: Remove numlock and scroll lock states when checking for printable text
// These lock states shouldn't affect normal typing
cksForTextCheck := cks &^ (xwindows.NUMLOCK_ON | xwindows.SCROLLLOCK_ON)
var text string var text string
keyCode := baseCode keyCode := baseCode
if !unicode.IsControl(r) { if !unicode.IsControl(r) {
rw := utf8.EncodeRune(utf8Buf[:], r) rw := utf8.EncodeRune(utf8Buf[:], r)
keyCode, _ = utf8.DecodeRune(utf8Buf[:rw]) keyCode, _ = utf8.DecodeRune(utf8Buf[:rw])
if unicode.IsPrint(keyCode) && (cks == 0 || if unicode.IsPrint(keyCode) && (cksForTextCheck == 0 ||
cks == xwindows.SHIFT_PRESSED || cksForTextCheck == xwindows.SHIFT_PRESSED ||
cks == xwindows.CAPSLOCK_ON || cksForTextCheck == xwindows.CAPSLOCK_ON ||
altGr) { altGr) {
// If the control key state is 0, shift is pressed, or caps lock // If the control key state is 0, shift is pressed, or caps lock
// then the key event is a printable event i.e. [text] is not empty. // then the key event is a printable event i.e. [text] is not empty.
text = string(keyCode) text = string(keyCode)
} }
} }
// Special case: numeric keypad divide should produce "/" text on all layouts (fix french keyboard layout)
if baseCode == KeyKpDivide {
text = "/"
}
key.Code = keyCode key.Code = keyCode
key.Text = text key.Text = text