key.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:generate stringer -type=Code
  5. // Package key defines an event for physical keyboard keys.
  6. //
  7. // On-screen software keyboards do not send key events.
  8. //
  9. // See the golang.org/x/mobile/app package for details on the event model.
  10. package key
  11. import (
  12. "fmt"
  13. "strings"
  14. )
  15. // Event is a key event.
  16. type Event struct {
  17. // Rune is the meaning of the key event as determined by the
  18. // operating system. The mapping is determined by system-dependent
  19. // current layout, modifiers, lock-states, etc.
  20. //
  21. // If non-negative, it is a Unicode codepoint: pressing the 'a' key
  22. // generates different Runes 'a' or 'A' (but the same Code) depending on
  23. // the state of the shift key.
  24. //
  25. // If -1, the key does not generate a Unicode codepoint. To distinguish
  26. // them, look at Code.
  27. Rune rune
  28. // Code is the identity of the physical key relative to a notional
  29. // "standard" keyboard, independent of current layout, modifiers,
  30. // lock-states, etc
  31. //
  32. // For standard key codes, its value matches USB HID key codes.
  33. // Compare its value to uint32-typed constants in this package, such
  34. // as CodeLeftShift and CodeEscape.
  35. //
  36. // Pressing the regular '2' key and number-pad '2' key (with Num-Lock)
  37. // generate different Codes (but the same Rune).
  38. Code Code
  39. // Modifiers is a bitmask representing a set of modifier keys: ModShift,
  40. // ModAlt, etc.
  41. Modifiers Modifiers
  42. // Direction is the direction of the key event: DirPress, DirRelease,
  43. // or DirNone (for key repeats).
  44. Direction Direction
  45. // TODO: add a Device ID, for multiple input devices?
  46. // TODO: add a time.Time?
  47. }
  48. func (e Event) String() string {
  49. if e.Rune >= 0 {
  50. return fmt.Sprintf("key.Event{%q (%v), %v, %v}", e.Rune, e.Code, e.Modifiers, e.Direction)
  51. }
  52. return fmt.Sprintf("key.Event{(%v), %v, %v}", e.Code, e.Modifiers, e.Direction)
  53. }
  54. // Direction is the direction of the key event.
  55. type Direction uint8
  56. const (
  57. DirNone Direction = 0
  58. DirPress Direction = 1
  59. DirRelease Direction = 2
  60. )
  61. // Modifiers is a bitmask representing a set of modifier keys.
  62. type Modifiers uint32
  63. const (
  64. ModShift Modifiers = 1 << 0
  65. ModControl Modifiers = 1 << 1
  66. ModAlt Modifiers = 1 << 2
  67. ModMeta Modifiers = 1 << 3 // called "Command" on OS X
  68. )
  69. // Code is the identity of a key relative to a notional "standard" keyboard.
  70. type Code uint32
  71. // Physical key codes.
  72. //
  73. // For standard key codes, its value matches USB HID key codes.
  74. // TODO: add missing codes.
  75. const (
  76. CodeUnknown Code = 0
  77. CodeA Code = 4
  78. CodeB Code = 5
  79. CodeC Code = 6
  80. CodeD Code = 7
  81. CodeE Code = 8
  82. CodeF Code = 9
  83. CodeG Code = 10
  84. CodeH Code = 11
  85. CodeI Code = 12
  86. CodeJ Code = 13
  87. CodeK Code = 14
  88. CodeL Code = 15
  89. CodeM Code = 16
  90. CodeN Code = 17
  91. CodeO Code = 18
  92. CodeP Code = 19
  93. CodeQ Code = 20
  94. CodeR Code = 21
  95. CodeS Code = 22
  96. CodeT Code = 23
  97. CodeU Code = 24
  98. CodeV Code = 25
  99. CodeW Code = 26
  100. CodeX Code = 27
  101. CodeY Code = 28
  102. CodeZ Code = 29
  103. Code1 Code = 30
  104. Code2 Code = 31
  105. Code3 Code = 32
  106. Code4 Code = 33
  107. Code5 Code = 34
  108. Code6 Code = 35
  109. Code7 Code = 36
  110. Code8 Code = 37
  111. Code9 Code = 38
  112. Code0 Code = 39
  113. CodeReturnEnter Code = 40
  114. CodeEscape Code = 41
  115. CodeDeleteBackspace Code = 42
  116. CodeTab Code = 43
  117. CodeSpacebar Code = 44
  118. CodeHyphenMinus Code = 45 // -
  119. CodeEqualSign Code = 46 // =
  120. CodeLeftSquareBracket Code = 47 // [
  121. CodeRightSquareBracket Code = 48 // ]
  122. CodeBackslash Code = 49 // \
  123. CodeSemicolon Code = 51 // ;
  124. CodeApostrophe Code = 52 // '
  125. CodeGraveAccent Code = 53 // `
  126. CodeComma Code = 54 // ,
  127. CodeFullStop Code = 55 // .
  128. CodeSlash Code = 56 // /
  129. CodeCapsLock Code = 57
  130. CodeF1 Code = 58
  131. CodeF2 Code = 59
  132. CodeF3 Code = 60
  133. CodeF4 Code = 61
  134. CodeF5 Code = 62
  135. CodeF6 Code = 63
  136. CodeF7 Code = 64
  137. CodeF8 Code = 65
  138. CodeF9 Code = 66
  139. CodeF10 Code = 67
  140. CodeF11 Code = 68
  141. CodeF12 Code = 69
  142. CodePause Code = 72
  143. CodeInsert Code = 73
  144. CodeHome Code = 74
  145. CodePageUp Code = 75
  146. CodeDeleteForward Code = 76
  147. CodeEnd Code = 77
  148. CodePageDown Code = 78
  149. CodeRightArrow Code = 79
  150. CodeLeftArrow Code = 80
  151. CodeDownArrow Code = 81
  152. CodeUpArrow Code = 82
  153. CodeKeypadNumLock Code = 83
  154. CodeKeypadSlash Code = 84 // /
  155. CodeKeypadAsterisk Code = 85 // *
  156. CodeKeypadHyphenMinus Code = 86 // -
  157. CodeKeypadPlusSign Code = 87 // +
  158. CodeKeypadEnter Code = 88
  159. CodeKeypad1 Code = 89
  160. CodeKeypad2 Code = 90
  161. CodeKeypad3 Code = 91
  162. CodeKeypad4 Code = 92
  163. CodeKeypad5 Code = 93
  164. CodeKeypad6 Code = 94
  165. CodeKeypad7 Code = 95
  166. CodeKeypad8 Code = 96
  167. CodeKeypad9 Code = 97
  168. CodeKeypad0 Code = 98
  169. CodeKeypadFullStop Code = 99 // .
  170. CodeKeypadEqualSign Code = 103 // =
  171. CodeF13 Code = 104
  172. CodeF14 Code = 105
  173. CodeF15 Code = 106
  174. CodeF16 Code = 107
  175. CodeF17 Code = 108
  176. CodeF18 Code = 109
  177. CodeF19 Code = 110
  178. CodeF20 Code = 111
  179. CodeF21 Code = 112
  180. CodeF22 Code = 113
  181. CodeF23 Code = 114
  182. CodeF24 Code = 115
  183. CodeHelp Code = 117
  184. CodeMute Code = 127
  185. CodeVolumeUp Code = 128
  186. CodeVolumeDown Code = 129
  187. CodeLeftControl Code = 224
  188. CodeLeftShift Code = 225
  189. CodeLeftAlt Code = 226
  190. CodeLeftGUI Code = 227
  191. CodeRightControl Code = 228
  192. CodeRightShift Code = 229
  193. CodeRightAlt Code = 230
  194. CodeRightGUI Code = 231
  195. // The following codes are not part of the standard USB HID Usage IDs for
  196. // keyboards. See http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
  197. //
  198. // Usage IDs are uint16s, so these non-standard values start at 0x10000.
  199. // CodeCompose is the Code for a compose key, sometimes called a multi key,
  200. // used to input non-ASCII characters such as ñ being composed of n and ~.
  201. //
  202. // See https://en.wikipedia.org/wiki/Compose_key
  203. CodeCompose Code = 0x10000
  204. )
  205. // TODO: Given we use runes outside the unicode space, should we provide a
  206. // printing function? Related: it's a little unfortunate that printing a
  207. // key.Event with %v gives not very readable output like:
  208. // {100 7 key.Modifiers() Press}
  209. var mods = [...]struct {
  210. m Modifiers
  211. s string
  212. }{
  213. {ModShift, "Shift"},
  214. {ModControl, "Control"},
  215. {ModAlt, "Alt"},
  216. {ModMeta, "Meta"},
  217. }
  218. func (m Modifiers) String() string {
  219. var match []string
  220. for _, mod := range mods {
  221. if mod.m&m != 0 {
  222. match = append(match, mod.s)
  223. }
  224. }
  225. return "key.Modifiers(" + strings.Join(match, "|") + ")"
  226. }
  227. func (d Direction) String() string {
  228. switch d {
  229. case DirNone:
  230. return "None"
  231. case DirPress:
  232. return "Press"
  233. case DirRelease:
  234. return "Release"
  235. default:
  236. return fmt.Sprintf("key.Direction(%d)", d)
  237. }
  238. }