diff --git a/app/internal/window/os_android.go b/app/internal/window/os_android.go index 34303d8c..b2062dae 100644 --- a/app/internal/window/os_android.go +++ b/app/internal/window/os_android.go @@ -353,8 +353,8 @@ func runInJVM(f func(env *C.JNIEnv)) { f(env) } -func convertKeyCode(code C.jint) (rune, bool) { - var n rune +func convertKeyCode(code C.jint) (string, bool) { + var n string switch code { case C.AKEYCODE_DPAD_UP: n = key.NameUpArrow @@ -369,7 +369,7 @@ func convertKeyCode(code C.jint) (rune, bool) { case C.AKEYCODE_DEL: n = key.NameDeleteBackward default: - return 0, false + return "", false } return n, true } diff --git a/app/internal/window/os_ios.go b/app/internal/window/os_ios.go index 8e2b933c..2a4f5650 100644 --- a/app/internal/window/os_ios.go +++ b/app/internal/window/os_ios.go @@ -205,7 +205,7 @@ func (w *window) SetAnimating(anim bool) { C.gio_setAnimating(w.view, animi) } -func (w *window) onKeyCommand(name rune) { +func (w *window) onKeyCommand(name string) { w.w.Event(key.Event{ Name: name, }) diff --git a/app/internal/window/os_js.go b/app/internal/window/os_js.go index 5aef3350..d3b122a0 100644 --- a/app/internal/window/os_js.go +++ b/app/internal/window/os_js.go @@ -383,17 +383,17 @@ func Main() { <-mainDone } -func translateKey(k string) (rune, bool) { +func translateKey(k string) (string, bool) { if len(k) == 1 { c := k[0] if '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' { - return rune(c), true + return string(c), true } if 'a' <= c && c <= 'z' { - return rune(c - 0x20), true + return string(c - 0x20), true } } - var n rune + var n string switch k { case "ArrowUp": n = key.NameUpArrow @@ -419,8 +419,10 @@ func translateKey(k string) (rune, bool) { n = key.NamePageUp case "PageDown": n = key.NamePageDown + case "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12": + n = k default: - return 0, false + return "", false } return n, true } diff --git a/app/internal/window/os_macos.go b/app/internal/window/os_macos.go index 152d8e8c..bcdffc33 100644 --- a/app/internal/window/os_macos.go +++ b/app/internal/window/os_macos.go @@ -289,14 +289,14 @@ func Main() { C.gio_main(view, title, C.CGFloat(w), C.CGFloat(h)) } -func convertKey(k rune) (rune, bool) { +func convertKey(k rune) (string, bool) { if '0' <= k && k <= '9' || 'A' <= k && k <= 'Z' { - return k, true + return string(k), true } if 'a' <= k && k <= 'z' { - return k - 0x20, true + return string(k - 0x20), true } - var n rune + var n string switch k { case 0x1b: n = key.NameEscape @@ -322,8 +322,32 @@ func convertKey(k rune) (rune, bool) { n = key.NamePageUp case C.NSPageDownFunctionKey: n = key.NamePageDown + case C.NSF1FunctionKey: + n = "F1" + case C.NSF2FunctionKey: + n = "F2" + case C.NSF3FunctionKey: + n = "F3" + case C.NSF4FunctionKey: + n = "F4" + case C.NSF5FunctionKey: + n = "F5" + case C.NSF6FunctionKey: + n = "F6" + case C.NSF7FunctionKey: + n = "F7" + case C.NSF8FunctionKey: + n = "F8" + case C.NSF9FunctionKey: + n = "F9" + case C.NSF10FunctionKey: + n = "F10" + case C.NSF11FunctionKey: + n = "F11" + case C.NSF12FunctionKey: + n = "F12" default: - return 0, false + return "", false } return n, true } diff --git a/app/internal/window/os_windows.go b/app/internal/window/os_windows.go index 41fc92f4..bac8114c 100644 --- a/app/internal/window/os_windows.go +++ b/app/internal/window/os_windows.go @@ -112,6 +112,19 @@ const ( _VK_RETURN = 0x0d _VK_UP = 0x26 + _VK_F1 = 0x70 + _VK_F2 = 0x71 + _VK_F3 = 0x72 + _VK_F4 = 0x73 + _VK_F5 = 0x74 + _VK_F6 = 0x75 + _VK_F7 = 0x76 + _VK_F8 = 0x77 + _VK_F9 = 0x78 + _VK_F10 = 0x79 + _VK_F11 = 0x7A + _VK_F12 = 0x7B + _UNICODE_NOCHAR = 65535 _WM_CANCELMODE = 0x001F @@ -457,11 +470,11 @@ func (w *window) HWND() (syscall.Handle, int, int) { return w.hwnd, w.width, w.height } -func convertKeyCode(code uintptr) (rune, bool) { +func convertKeyCode(code uintptr) (string, bool) { if '0' <= code && code <= '9' || 'A' <= code && code <= 'Z' { - return rune(code), true + return string(code), true } - var r rune + var r string switch code { case _VK_ESCAPE: r = key.NameEscape @@ -487,8 +500,32 @@ func convertKeyCode(code uintptr) (rune, bool) { r = key.NamePageUp case _VK_NEXT: r = key.NamePageDown + case _VK_F1: + r = "F1" + case _VK_F2: + r = "F2" + case _VK_F3: + r = "F3" + case _VK_F4: + r = "F4" + case _VK_F5: + r = "F5" + case _VK_F6: + r = "F6" + case _VK_F7: + r = "F7" + case _VK_F8: + r = "F8" + case _VK_F9: + r = "F9" + case _VK_F10: + r = "F10" + case _VK_F11: + r = "F11" + case _VK_F12: + r = "F12" default: - return 0, false + return "", false } return r, true } diff --git a/app/internal/window/os_x11.go b/app/internal/window/os_x11.go index 81edf1c9..ab80afeb 100644 --- a/app/internal/window/os_x11.go +++ b/app/internal/window/os_x11.go @@ -257,8 +257,8 @@ func (h *x11EventHandler) handleEvents() bool { if r, ok := x11SpecialKeySymToRune(h.keysym); ok { w.w.Event(key.Event{Name: r, Modifiers: mods}) } else { - if r, _ = utf8.DecodeRune(h.text[:l]); r != utf8.RuneError { - w.w.Event(key.Event{Name: unicode.ToUpper(r), Modifiers: mods}) + if r, _ := utf8.DecodeRune(h.text[:l]); r != utf8.RuneError { + w.w.Event(key.Event{Name: string(unicode.ToUpper(r)), Modifiers: mods}) } // Send EditEvent only when not a CTRL key combination. if !mods.Contain(key.ModCtrl) { @@ -349,8 +349,8 @@ func x11KeyStateToModifiers(s C.uint) key.Modifiers { return m } -func x11SpecialKeySymToRune(s C.KeySym) (rune, bool) { - var n rune +func x11SpecialKeySymToRune(s C.KeySym) (string, bool) { + var n string switch s { case C.XK_Escape: n = key.NameEscape @@ -378,8 +378,32 @@ func x11SpecialKeySymToRune(s C.KeySym) (rune, bool) { n = key.NamePageUp case C.XK_Page_Down, C.XK_KP_Next: n = key.NamePageDown + case C.XK_F1: + n = "F1" + case C.XK_F2: + n = "F2" + case C.XK_F3: + n = "F3" + case C.XK_F4: + n = "F4" + case C.XK_F5: + n = "F5" + case C.XK_F6: + n = "F6" + case C.XK_F7: + n = "F7" + case C.XK_F8: + n = "F8" + case C.XK_F9: + n = "F9" + case C.XK_F10: + n = "F10" + case C.XK_F11: + n = "F11" + case C.XK_F12: + n = "F12" default: - return 0, false + return "", false } return n, true } diff --git a/app/internal/xkb/xkb_unix.go b/app/internal/xkb/xkb_unix.go index 1d024e7f..470de075 100644 --- a/app/internal/xkb/xkb_unix.go +++ b/app/internal/xkb/xkb_unix.go @@ -5,7 +5,18 @@ // Package xkb implements a Go interface for the X Keyboard Extension library. package xkb -import "gioui.org/io/event" +import ( + "errors" + "fmt" + "os" + "syscall" + "unicode" + "unicode/utf8" + "unsafe" + + "gioui.org/io/event" + "gioui.org/io/key" +) /* #cgo LDFLAGS: -lxkbcommon @@ -18,18 +29,6 @@ import "gioui.org/io/event" */ import "C" -import ( - "errors" - "fmt" - "os" - "syscall" - "unicode" - "unicode/utf8" - "unsafe" - - "gioui.org/io/key" -) - type Context struct { ctx *C.struct_xkb_context keyMap *C.struct_xkb_keymap @@ -191,14 +190,14 @@ func mapXKBKeyCode(keyCode uint32) uint32 { return keyCode + 8 } -func convertKeysym(s C.xkb_keysym_t) (rune, bool) { +func convertKeysym(s C.xkb_keysym_t) (string, bool) { if '0' <= s && s <= '9' || 'A' <= s && s <= 'Z' { - return rune(s), true + return string(s), true } if 'a' <= s && s <= 'z' { - return rune(s - 0x20), true + return string(s - 0x20), true } - var n rune + var n string switch s { case C.XKB_KEY_Escape: n = key.NameEscape @@ -226,8 +225,32 @@ func convertKeysym(s C.xkb_keysym_t) (rune, bool) { n = key.NamePageUp case C.XKB_KEY_Page_Down: n = key.NamePageDown + case C.XKB_KEY_F1: + n = "F1" + case C.XKB_KEY_F2: + n = "F2" + case C.XKB_KEY_F3: + n = "F3" + case C.XKB_KEY_F4: + n = "F4" + case C.XKB_KEY_F5: + n = "F5" + case C.XKB_KEY_F6: + n = "F6" + case C.XKB_KEY_F7: + n = "F7" + case C.XKB_KEY_F8: + n = "F8" + case C.XKB_KEY_F9: + n = "F9" + case C.XKB_KEY_F10: + n = "F10" + case C.XKB_KEY_F11: + n = "F11" + case C.XKB_KEY_F12: + n = "F12" default: - return 0, false + return "", false } return n, true } diff --git a/io/key/key.go b/io/key/key.go index f33bfde5..275cb6d9 100644 --- a/io/key/key.go +++ b/io/key/key.go @@ -39,10 +39,10 @@ type FocusEvent struct { // An Event is generated when a key is pressed. For text input // use EditEvent. type Event struct { - // Name is the rune character that most closely - // match the key. For letters, the upper case form - // is used. - Name rune + // Name of the key. For letters, the upper case form is used. + // Use the Name* constants for special keys suchs as the arrow + // keys. + Name string // Modifiers is the set of active modifiers when // the key was pressed. Modifiers Modifiers @@ -73,20 +73,20 @@ const ( ) const ( - // Runes for special keys. - NameLeftArrow = '←' - NameRightArrow = '→' - NameUpArrow = '↑' - NameDownArrow = '↓' - NameReturn = '⏎' - NameEnter = '⌤' - NameEscape = '⎋' - NameHome = '⇱' - NameEnd = '⇲' - NameDeleteBackward = '⌫' - NameDeleteForward = '⌦' - NamePageUp = '⇞' - NamePageDown = '⇟' + // Names for special keys. + NameLeftArrow = "←" + NameRightArrow = "→" + NameUpArrow = "↑" + NameDownArrow = "↓" + NameReturn = "⏎" + NameEnter = "⌤" + NameEscape = "⎋" + NameHome = "⇱" + NameEnd = "⇲" + NameDeleteBackward = "⌫" + NameDeleteForward = "⌦" + NamePageUp = "⇞" + NamePageDown = "⇟" ) // Contain reports whether m contains all modifiers