io/key: switch Event.Name to be a string and add function keys

Function keys don't have a natural rune representation so switch
Event.Name to be a string to fit "F1"-"F12".

Fixes gio#59

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-11-08 19:00:43 +01:00
parent c833c98fd7
commit cc43588aba
8 changed files with 169 additions and 59 deletions
+3 -3
View File
@@ -353,8 +353,8 @@ func runInJVM(f func(env *C.JNIEnv)) {
f(env) f(env)
} }
func convertKeyCode(code C.jint) (rune, bool) { func convertKeyCode(code C.jint) (string, bool) {
var n rune var n string
switch code { switch code {
case C.AKEYCODE_DPAD_UP: case C.AKEYCODE_DPAD_UP:
n = key.NameUpArrow n = key.NameUpArrow
@@ -369,7 +369,7 @@ func convertKeyCode(code C.jint) (rune, bool) {
case C.AKEYCODE_DEL: case C.AKEYCODE_DEL:
n = key.NameDeleteBackward n = key.NameDeleteBackward
default: default:
return 0, false return "", false
} }
return n, true return n, true
} }
+1 -1
View File
@@ -205,7 +205,7 @@ func (w *window) SetAnimating(anim bool) {
C.gio_setAnimating(w.view, animi) C.gio_setAnimating(w.view, animi)
} }
func (w *window) onKeyCommand(name rune) { func (w *window) onKeyCommand(name string) {
w.w.Event(key.Event{ w.w.Event(key.Event{
Name: name, Name: name,
}) })
+7 -5
View File
@@ -383,17 +383,17 @@ func Main() {
<-mainDone <-mainDone
} }
func translateKey(k string) (rune, bool) { func translateKey(k string) (string, bool) {
if len(k) == 1 { if len(k) == 1 {
c := k[0] c := k[0]
if '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' { if '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' {
return rune(c), true return string(c), true
} }
if 'a' <= c && c <= 'z' { if 'a' <= c && c <= 'z' {
return rune(c - 0x20), true return string(c - 0x20), true
} }
} }
var n rune var n string
switch k { switch k {
case "ArrowUp": case "ArrowUp":
n = key.NameUpArrow n = key.NameUpArrow
@@ -419,8 +419,10 @@ func translateKey(k string) (rune, bool) {
n = key.NamePageUp n = key.NamePageUp
case "PageDown": case "PageDown":
n = key.NamePageDown n = key.NamePageDown
case "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12":
n = k
default: default:
return 0, false return "", false
} }
return n, true return n, true
} }
+29 -5
View File
@@ -289,14 +289,14 @@ func Main() {
C.gio_main(view, title, C.CGFloat(w), C.CGFloat(h)) 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' { if '0' <= k && k <= '9' || 'A' <= k && k <= 'Z' {
return k, true return string(k), true
} }
if 'a' <= k && k <= 'z' { if 'a' <= k && k <= 'z' {
return k - 0x20, true return string(k - 0x20), true
} }
var n rune var n string
switch k { switch k {
case 0x1b: case 0x1b:
n = key.NameEscape n = key.NameEscape
@@ -322,8 +322,32 @@ func convertKey(k rune) (rune, bool) {
n = key.NamePageUp n = key.NamePageUp
case C.NSPageDownFunctionKey: case C.NSPageDownFunctionKey:
n = key.NamePageDown 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: default:
return 0, false return "", false
} }
return n, true return n, true
} }
+41 -4
View File
@@ -112,6 +112,19 @@ const (
_VK_RETURN = 0x0d _VK_RETURN = 0x0d
_VK_UP = 0x26 _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 _UNICODE_NOCHAR = 65535
_WM_CANCELMODE = 0x001F _WM_CANCELMODE = 0x001F
@@ -457,11 +470,11 @@ func (w *window) HWND() (syscall.Handle, int, int) {
return w.hwnd, w.width, w.height 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' { 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 { switch code {
case _VK_ESCAPE: case _VK_ESCAPE:
r = key.NameEscape r = key.NameEscape
@@ -487,8 +500,32 @@ func convertKeyCode(code uintptr) (rune, bool) {
r = key.NamePageUp r = key.NamePageUp
case _VK_NEXT: case _VK_NEXT:
r = key.NamePageDown 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: default:
return 0, false return "", false
} }
return r, true return r, true
} }
+29 -5
View File
@@ -257,8 +257,8 @@ func (h *x11EventHandler) handleEvents() bool {
if r, ok := x11SpecialKeySymToRune(h.keysym); ok { if r, ok := x11SpecialKeySymToRune(h.keysym); ok {
w.w.Event(key.Event{Name: r, Modifiers: mods}) w.w.Event(key.Event{Name: r, Modifiers: mods})
} else { } else {
if r, _ = utf8.DecodeRune(h.text[:l]); r != utf8.RuneError { if r, _ := utf8.DecodeRune(h.text[:l]); r != utf8.RuneError {
w.w.Event(key.Event{Name: unicode.ToUpper(r), Modifiers: mods}) w.w.Event(key.Event{Name: string(unicode.ToUpper(r)), Modifiers: mods})
} }
// Send EditEvent only when not a CTRL key combination. // Send EditEvent only when not a CTRL key combination.
if !mods.Contain(key.ModCtrl) { if !mods.Contain(key.ModCtrl) {
@@ -349,8 +349,8 @@ func x11KeyStateToModifiers(s C.uint) key.Modifiers {
return m return m
} }
func x11SpecialKeySymToRune(s C.KeySym) (rune, bool) { func x11SpecialKeySymToRune(s C.KeySym) (string, bool) {
var n rune var n string
switch s { switch s {
case C.XK_Escape: case C.XK_Escape:
n = key.NameEscape n = key.NameEscape
@@ -378,8 +378,32 @@ func x11SpecialKeySymToRune(s C.KeySym) (rune, bool) {
n = key.NamePageUp n = key.NamePageUp
case C.XK_Page_Down, C.XK_KP_Next: case C.XK_Page_Down, C.XK_KP_Next:
n = key.NamePageDown 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: default:
return 0, false return "", false
} }
return n, true return n, true
} }
+41 -18
View File
@@ -5,7 +5,18 @@
// Package xkb implements a Go interface for the X Keyboard Extension library. // Package xkb implements a Go interface for the X Keyboard Extension library.
package xkb 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 #cgo LDFLAGS: -lxkbcommon
@@ -18,18 +29,6 @@ import "gioui.org/io/event"
*/ */
import "C" import "C"
import (
"errors"
"fmt"
"os"
"syscall"
"unicode"
"unicode/utf8"
"unsafe"
"gioui.org/io/key"
)
type Context struct { type Context struct {
ctx *C.struct_xkb_context ctx *C.struct_xkb_context
keyMap *C.struct_xkb_keymap keyMap *C.struct_xkb_keymap
@@ -191,14 +190,14 @@ func mapXKBKeyCode(keyCode uint32) uint32 {
return keyCode + 8 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' { if '0' <= s && s <= '9' || 'A' <= s && s <= 'Z' {
return rune(s), true return string(s), true
} }
if 'a' <= s && s <= 'z' { if 'a' <= s && s <= 'z' {
return rune(s - 0x20), true return string(s - 0x20), true
} }
var n rune var n string
switch s { switch s {
case C.XKB_KEY_Escape: case C.XKB_KEY_Escape:
n = key.NameEscape n = key.NameEscape
@@ -226,8 +225,32 @@ func convertKeysym(s C.xkb_keysym_t) (rune, bool) {
n = key.NamePageUp n = key.NamePageUp
case C.XKB_KEY_Page_Down: case C.XKB_KEY_Page_Down:
n = key.NamePageDown 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: default:
return 0, false return "", false
} }
return n, true return n, true
} }
+18 -18
View File
@@ -39,10 +39,10 @@ type FocusEvent struct {
// An Event is generated when a key is pressed. For text input // An Event is generated when a key is pressed. For text input
// use EditEvent. // use EditEvent.
type Event struct { type Event struct {
// Name is the rune character that most closely // Name of the key. For letters, the upper case form is used.
// match the key. For letters, the upper case form // Use the Name* constants for special keys suchs as the arrow
// is used. // keys.
Name rune Name string
// Modifiers is the set of active modifiers when // Modifiers is the set of active modifiers when
// the key was pressed. // the key was pressed.
Modifiers Modifiers Modifiers Modifiers
@@ -73,20 +73,20 @@ const (
) )
const ( const (
// Runes for special keys. // Names for special keys.
NameLeftArrow = '←' NameLeftArrow = "←"
NameRightArrow = '→' NameRightArrow = "→"
NameUpArrow = '↑' NameUpArrow = "↑"
NameDownArrow = '↓' NameDownArrow = "↓"
NameReturn = '⏎' NameReturn = "⏎"
NameEnter = '⌤' NameEnter = "⌤"
NameEscape = '⎋' NameEscape = "⎋"
NameHome = '⇱' NameHome = "⇱"
NameEnd = '⇲' NameEnd = "⇲"
NameDeleteBackward = '⌫' NameDeleteBackward = "⌫"
NameDeleteForward = '⌦' NameDeleteForward = "⌦"
NamePageUp = '⇞' NamePageUp = "⇞"
NamePageDown = '⇟' NamePageDown = "⇟"
) )
// Contain reports whether m contains all modifiers // Contain reports whether m contains all modifiers