diff --git a/app/internal/xkb/xkb_unix.go b/app/internal/xkb/xkb_unix.go index eda120d8a..05959b59e 100644 --- a/app/internal/xkb/xkb_unix.go +++ b/app/internal/xkb/xkb_unix.go @@ -160,19 +160,18 @@ func (x *Context) DispatchKey(keyCode uint32, state key.State) (events []event.E x.utf8Buf = make([]byte, 1) } sym := C.xkb_state_key_get_one_sym(x.state, kc) - if name, ok := convertKeysym(sym); ok { - cmd := key.Event{ - Name: name, - Modifiers: x.Modifiers(), - State: state, - } - // Ensure that a physical backtab key is translated to - // Shift-Tab. - if sym == C.XKB_KEY_ISO_Left_Tab { - cmd.Modifiers |= key.ModShift - } - events = append(events, cmd) + cmd := key.Event{ + Code: int(keyCode), + Name: convertKeysym(sym), + Modifiers: x.Modifiers(), + State: state, + } + // Ensure that a physical backtab key is translated to + // Shift-Tab. + if sym == C.XKB_KEY_ISO_Left_Tab { + cmd.Modifiers |= key.ModShift } + events = append(events, cmd) C.xkb_compose_state_feed(x.compState, sym) var str []byte switch C.xkb_compose_state_get_status(x.compState) { @@ -231,12 +230,12 @@ func (x *Context) UpdateMask(depressed, latched, locked, depressedGroup, latched C.xkb_layout_index_t(depressedGroup), C.xkb_layout_index_t(latchedGroup), C.xkb_layout_index_t(lockedGroup)) } -func convertKeysym(s C.xkb_keysym_t) (string, bool) { +func convertKeysym(s C.xkb_keysym_t) string { if 'a' <= s && s <= 'z' { - return string(rune(s - 'a' + 'A')), true + return string(rune(s - 'a' + 'A')) } if ' ' < s && s <= '~' { - return string(rune(s)), true + return string(rune(s)) } var n string switch s { @@ -302,8 +301,6 @@ func convertKeysym(s C.xkb_keysym_t) (string, bool) { n = key.NameAlt case C.XKB_KEY_Super_L, C.XKB_KEY_Super_R: n = key.NameSuper - default: - return "", false } - return n, true + return n } diff --git a/app/os_android.go b/app/os_android.go index c850e41dd..36fc10425 100644 --- a/app/os_android.go +++ b/app/os_android.go @@ -896,7 +896,7 @@ func runInJVM(jvm *C.JavaVM, f func(env *C.JNIEnv)) { f(env) } -func convertKeyCode(code C.jint) (string, bool) { +func convertKeyCode(code C.jint) string { var n string switch code { case C.AKEYCODE_FORWARD_DEL: @@ -923,10 +923,8 @@ func convertKeyCode(code C.jint) (string, bool) { n = key.NameLeftArrow case C.AKEYCODE_DPAD_RIGHT: n = key.NameRightArrow - default: - return "", false } - return n, true + return n } //export Java_org_gioui_GioView_onKeyEvent @@ -936,13 +934,15 @@ func Java_org_gioui_GioView_onKeyEvent(env *C.JNIEnv, class C.jclass, handle C.j w.callbacks.ClickFocus() return } - if n, ok := convertKeyCode(keyCode); ok { - state := key.Release - if pressed == C.JNI_TRUE { - state = key.Press - } - w.callbacks.Event(key.Event{Name: n, State: state}) + state := key.Release + if pressed == C.JNI_TRUE { + state = key.Press } + w.callbacks.Event(key.Event{ + Code: int(keyCode), + Name: convertKeyCode(keyCode), + State: state, + }) if pressed == C.JNI_TRUE && r != 0 && r != '\n' { // Checking for "\n" to prevent duplication with key.NameEnter (gio#224). w.callbacks.EditorInsert(string(rune(r))) } diff --git a/app/os_js.go b/app/os_js.go index 6f0df82cc..c1f086f32 100644 --- a/app/os_js.go +++ b/app/os_js.go @@ -358,15 +358,14 @@ func (w *window) keyboard(hint key.InputHint) { } func (w *window) keyEvent(e js.Value, ks key.State) { + c := e.Get("keyCode").Int() k := e.Get("key").String() - if n, ok := translateKey(k); ok { - cmd := key.Event{ - Name: n, - Modifiers: modifiersFor(e), - State: ks, - } - w.w.Event(cmd) - } + w.w.Event(key.Event{ + Code: c, + Name: translateKey(k), + Modifiers: modifiersFor(e), + State: ks, + }) } // modifiersFor returns the modifier set for a DOM MouseEvent or @@ -737,9 +736,8 @@ func osMain() { select {} } -func translateKey(k string) (string, bool) { - var n string - +func translateKey(k string) string { + n := k switch k { case "ArrowUp": n = key.NameUpArrow @@ -805,11 +803,10 @@ func translateKey(k string) (string, bool) { r, s := utf8.DecodeRuneInString(k) // If there is exactly one printable character, return that. if s == len(k) && unicode.IsPrint(r) { - return strings.ToUpper(k), true + n = strings.ToUpper(k) } - return "", false } - return n, true + return n } func (_ ViewEvent) ImplementsEvent() {} diff --git a/app/os_macos.go b/app/os_macos.go index 0d50ea47a..98c85ba06 100644 --- a/app/os_macos.go +++ b/app/os_macos.go @@ -486,13 +486,12 @@ func gio_onKeys(view, cstr C.CFTypeRef, ti C.double, mods C.NSUInteger, keyDown } w := mustView(view) for _, k := range str { - if n, ok := convertKey(k); ok { - w.w.Event(key.Event{ - Name: n, - Modifiers: kmods, - State: ks, - }) - } + w.w.Event(key.Event{ + Code: int(k), + Name: convertKey(k), + Modifiers: kmods, + State: ks, + }) } } @@ -892,8 +891,8 @@ func osMain() { C.gio_main() } -func convertKey(k rune) (string, bool) { - var n string +func convertKey(k rune) string { + n := string(k) switch k { case 0x1b: n = key.NameEscape @@ -951,12 +950,11 @@ func convertKey(k rune) (string, bool) { n = key.NameSpace default: k = unicode.ToUpper(k) - if !unicode.IsPrint(k) { - return "", false + if unicode.IsPrint(k) { + n = string(k) } - n = string(k) } - return n, true + return n } func convertMods(mods C.NSUInteger) key.Modifiers { diff --git a/app/os_windows.go b/app/os_windows.go index 0a49f94ef..87d215904 100644 --- a/app/os_windows.go +++ b/app/os_windows.go @@ -17,9 +17,10 @@ import ( syscall "golang.org/x/sys/windows" + gowindows "golang.org/x/sys/windows" + "gioui.org/app/internal/windows" "gioui.org/unit" - gowindows "golang.org/x/sys/windows" "gioui.org/f32" "gioui.org/io/clipboard" @@ -243,23 +244,21 @@ func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr // Avoid flickering between GPU content and background color. return windows.TRUE case windows.WM_KEYDOWN, windows.WM_KEYUP, windows.WM_SYSKEYDOWN, windows.WM_SYSKEYUP: - if n, ok := convertKeyCode(wParam); ok { - e := key.Event{ - Name: n, - Modifiers: getModifiers(), - State: key.Press, - } - if msg == windows.WM_KEYUP || msg == windows.WM_SYSKEYUP { - e.State = key.Release - } - - w.w.Event(e) + state := key.Press + if msg == windows.WM_KEYUP || msg == windows.WM_SYSKEYUP { + state = key.Release + } + w.w.Event(key.Event{ + Code: int(wParam), + Name: convertKeyCode(wParam), + Modifiers: getModifiers(), + State: state, + }) - if (wParam == windows.VK_F10) && (msg == windows.WM_SYSKEYDOWN || msg == windows.WM_SYSKEYUP) { - // Reserve F10 for ourselves, and don't let it open the system menu. Other Windows programs - // such as cmd.exe and graphical debuggers also reserve F10. - return 0 - } + if (wParam == windows.VK_F10) && (msg == windows.WM_SYSKEYDOWN || msg == windows.WM_SYSKEYUP) { + // Reserve F10 for ourselves, and don't let it open the system menu. Other Windows programs + // such as cmd.exe and graphical debuggers also reserve F10. + return 0 } case windows.WM_LBUTTONDOWN: w.pointerButton(pointer.ButtonPrimary, true, lParam, getModifiers()) @@ -834,9 +833,9 @@ func (w *window) raise() { windows.SWP_NOMOVE|windows.SWP_NOSIZE|windows.SWP_SHOWWINDOW) } -func convertKeyCode(code uintptr) (string, bool) { +func convertKeyCode(code uintptr) string { if '0' <= code && code <= '9' || 'A' <= code && code <= 'Z' { - return string(rune(code)), true + return string(rune(code)) } var r string @@ -923,10 +922,8 @@ func convertKeyCode(code uintptr) (string, bool) { r = key.NameAlt case windows.VK_LWIN, windows.VK_RWIN: r = key.NameSuper - default: - return "", false } - return r, true + return r } func configForDPI(dpi int) unit.Metric { diff --git a/io/key/key.go b/io/key/key.go index af31e3e6a..f3efe19bc 100644 --- a/io/key/key.go +++ b/io/key/key.go @@ -116,6 +116,8 @@ type FocusEvent struct { // An Event is generated when a key is pressed. For text input // use EditEvent. type Event struct { + // Code of the key. It is platform-specific, thus non-portable. + Code int // Name of the key. For letters, the upper case form is used, via // unicode.ToUpper. The shift modifier is taken into account, all other // modifiers are ignored. For example, the "shift-1" and "ctrl-shift-1"