events.rs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. //! An event system that's less confusing than Traits + RC;
  2. //! This should hopefully make it easier to port to other platforms.
  3. //!
  4. //! Unfortunately, it is less efficient than the original, but hopefully it's negligible.
  5. use crate::{
  6. innerlude::Listener,
  7. innerlude::{ElementId, NodeFactory, ScopeId},
  8. };
  9. use bumpalo::boxed::Box as BumpBox;
  10. use std::{
  11. any::Any,
  12. cell::{Cell, RefCell},
  13. fmt::Debug,
  14. };
  15. pub use on::*;
  16. #[derive(Debug)]
  17. pub struct UserEvent {
  18. /// The originator of the event trigger
  19. pub scope: ScopeId,
  20. /// The optional real node associated with the trigger
  21. pub mounted_dom_id: Option<ElementId>,
  22. /// The event type IE "onclick" or "onmouseover"
  23. ///
  24. /// The name that the renderer will use to mount the listener.
  25. pub name: &'static str,
  26. /// The type of event
  27. pub event: Box<dyn Any + Send>,
  28. }
  29. /// Priority of Event Triggers.
  30. ///
  31. /// Internally, Dioxus will abort work that's taking too long if new, more important work arrives. Unlike React, Dioxus
  32. /// won't be afraid to pause work or flush changes to the RealDOM. This is called "cooperative scheduling". Some Renderers
  33. /// implement this form of scheduling internally, however Dioxus will perform its own scheduling as well.
  34. ///
  35. /// The ultimate goal of the scheduler is to manage latency of changes, prioritizing "flashier" changes over "subtler" changes.
  36. ///
  37. /// React has a 5-tier priority system. However, they break things into "Continuous" and "Discrete" priority. For now,
  38. /// we keep it simple, and just use a 3-tier priority system.
  39. ///
  40. /// - NoPriority = 0
  41. /// - LowPriority = 1
  42. /// - NormalPriority = 2
  43. /// - UserBlocking = 3
  44. /// - HighPriority = 4
  45. /// - ImmediatePriority = 5
  46. ///
  47. /// We still have a concept of discrete vs continuous though - discrete events won't be batched, but continuous events will.
  48. /// This means that multiple "scroll" events will be processed in a single frame, but multiple "click" events will be
  49. /// flushed before proceeding. Multiple discrete events is highly unlikely, though.
  50. #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
  51. pub enum EventPriority {
  52. /// Work that must be completed during the EventHandler phase.
  53. ///
  54. /// Currently this is reserved for controlled inputs.
  55. Immediate = 3,
  56. /// "High Priority" work will not interrupt other high priority work, but will interrupt medium and low priority work.
  57. ///
  58. /// This is typically reserved for things like user interaction.
  59. ///
  60. /// React calls these "discrete" events, but with an extra category of "user-blocking" (Immediate).
  61. High = 2,
  62. /// "Medium priority" work is generated by page events not triggered by the user. These types of events are less important
  63. /// than "High Priority" events and will take precedence over low priority events.
  64. ///
  65. /// This is typically reserved for VirtualEvents that are not related to keyboard or mouse input.
  66. ///
  67. /// React calls these "continuous" events (e.g. mouse move, mouse wheel, touch move, etc).
  68. Medium = 1,
  69. /// "Low Priority" work will always be preempted unless the work is significantly delayed, in which case it will be
  70. /// advanced to the front of the work queue until completed.
  71. ///
  72. /// The primary user of Low Priority work is the asynchronous work system (Suspense).
  73. ///
  74. /// This is considered "idle" work or "background" work.
  75. Low = 0,
  76. }
  77. pub mod on {
  78. use super::*;
  79. macro_rules! event_directory {
  80. ( $(
  81. $( #[$attr:meta] )*
  82. $wrapper:ident: [
  83. // $eventdata:ident($wrapper:ident): [
  84. $(
  85. $( #[$method_attr:meta] )*
  86. $name:ident
  87. )*
  88. ];
  89. )* ) => {
  90. $(
  91. $(
  92. $(#[$method_attr])*
  93. pub fn $name<'a, F>(
  94. c: NodeFactory<'a>,
  95. mut callback: F,
  96. ) -> Listener<'a>
  97. where F: FnMut($wrapper) + 'a
  98. {
  99. let bump = &c.bump();
  100. // we can't allocate unsized in bumpalo's box, so we need to craft the box manually
  101. // safety: this is essentially the same as calling Box::new() but manually
  102. // The box is attached to the lifetime of the bumpalo allocator
  103. let cb: &mut dyn FnMut(Box<dyn Any + Send>) = bump.alloc(move |evt: Box<dyn Any + Send>| {
  104. let event = evt.downcast::<$wrapper>().unwrap();
  105. callback(*event)
  106. });
  107. let callback: BumpBox<dyn FnMut(Box<dyn Any + Send>) + 'a> = unsafe { BumpBox::from_raw(cb) };
  108. // ie oncopy
  109. let event_name = stringify!($name);
  110. // ie copy
  111. let shortname: &'static str = &event_name[2..];
  112. Listener {
  113. event: shortname,
  114. mounted_node: Cell::new(None),
  115. callback: RefCell::new(Some(callback)),
  116. }
  117. }
  118. )*
  119. )*
  120. };
  121. }
  122. // The Dioxus Synthetic event system
  123. // todo: move these into the html event system. dioxus accepts *any* event, so having these here doesn't make sense.
  124. event_directory! {
  125. ClipboardEvent: [
  126. /// Called when "copy"
  127. oncopy
  128. /// oncut
  129. oncut
  130. /// onpaste
  131. onpaste
  132. ];
  133. CompositionEvent: [
  134. /// oncompositionend
  135. oncompositionend
  136. /// oncompositionstart
  137. oncompositionstart
  138. /// oncompositionupdate
  139. oncompositionupdate
  140. ];
  141. KeyboardEvent: [
  142. /// onkeydown
  143. onkeydown
  144. /// onkeypress
  145. onkeypress
  146. /// onkeyup
  147. onkeyup
  148. ];
  149. FocusEvent: [
  150. /// onfocus
  151. onfocus
  152. /// onblur
  153. onblur
  154. ];
  155. FormEvent: [
  156. /// onchange
  157. onchange
  158. /// oninput handler
  159. oninput
  160. /// oninvalid
  161. oninvalid
  162. /// onreset
  163. onreset
  164. /// onsubmit
  165. onsubmit
  166. ];
  167. /// A synthetic event that wraps a web-style [`MouseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)
  168. ///
  169. ///
  170. /// The MouseEvent interface represents events that occur due to the user interacting with a pointing device (such as a mouse).
  171. ///
  172. /// ## Trait implementation:
  173. /// ```rust
  174. /// fn alt_key(&self) -> bool;
  175. /// fn button(&self) -> i16;
  176. /// fn buttons(&self) -> u16;
  177. /// fn client_x(&self) -> i32;
  178. /// fn client_y(&self) -> i32;
  179. /// fn ctrl_key(&self) -> bool;
  180. /// fn meta_key(&self) -> bool;
  181. /// fn page_x(&self) -> i32;
  182. /// fn page_y(&self) -> i32;
  183. /// fn screen_x(&self) -> i32;
  184. /// fn screen_y(&self) -> i32;
  185. /// fn shift_key(&self) -> bool;
  186. /// fn get_modifier_state(&self, key_code: &str) -> bool;
  187. /// ```
  188. ///
  189. /// ## Event Handlers
  190. /// - [`onclick`]
  191. /// - [`oncontextmenu`]
  192. /// - [`ondoubleclick`]
  193. /// - [`ondrag`]
  194. /// - [`ondragend`]
  195. /// - [`ondragenter`]
  196. /// - [`ondragexit`]
  197. /// - [`ondragleave`]
  198. /// - [`ondragover`]
  199. /// - [`ondragstart`]
  200. /// - [`ondrop`]
  201. /// - [`onmousedown`]
  202. /// - [`onmouseenter`]
  203. /// - [`onmouseleave`]
  204. /// - [`onmousemove`]
  205. /// - [`onmouseout`]
  206. /// - [`onmouseover`]
  207. /// - [`onmouseup`]
  208. MouseEvent: [
  209. /// Execute a callback when a button is clicked.
  210. ///
  211. /// ## Description
  212. ///
  213. /// An element receives a click event when a pointing device button (such as a mouse's primary mouse button)
  214. /// is both pressed and released while the pointer is located inside the element.
  215. ///
  216. /// - Bubbles: Yes
  217. /// - Cancelable: Yes
  218. /// - Interface: [`MouseEvent`]
  219. ///
  220. /// If the button is pressed on one element and the pointer is moved outside the element before the button
  221. /// is released, the event is fired on the most specific ancestor element that contained both elements.
  222. /// `click` fires after both the `mousedown` and `mouseup` events have fired, in that order.
  223. ///
  224. /// ## Example
  225. /// ```
  226. /// rsx!( button { "click me", onclick: move |_| log::info!("Clicked!`") } )
  227. /// ```
  228. ///
  229. /// ## Reference
  230. /// - https://www.w3schools.com/tags/ev_onclick.asp
  231. /// - https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event
  232. onclick
  233. /// oncontextmenu
  234. oncontextmenu
  235. /// ondoubleclick
  236. ondoubleclick
  237. /// ondrag
  238. ondrag
  239. /// ondragend
  240. ondragend
  241. /// ondragenter
  242. ondragenter
  243. /// ondragexit
  244. ondragexit
  245. /// ondragleave
  246. ondragleave
  247. /// ondragover
  248. ondragover
  249. /// ondragstart
  250. ondragstart
  251. /// ondrop
  252. ondrop
  253. /// onmousedown
  254. onmousedown
  255. /// onmouseenter
  256. onmouseenter
  257. /// onmouseleave
  258. onmouseleave
  259. /// onmousemove
  260. onmousemove
  261. /// onmouseout
  262. onmouseout
  263. ///
  264. onscroll
  265. /// onmouseover
  266. ///
  267. /// Triggered when the users's mouse hovers over an element.
  268. onmouseover
  269. /// onmouseup
  270. onmouseup
  271. ];
  272. PointerEvent: [
  273. /// pointerdown
  274. onpointerdown
  275. /// pointermove
  276. onpointermove
  277. /// pointerup
  278. onpointerup
  279. /// pointercancel
  280. onpointercancel
  281. /// gotpointercapture
  282. ongotpointercapture
  283. /// lostpointercapture
  284. onlostpointercapture
  285. /// pointerenter
  286. onpointerenter
  287. /// pointerleave
  288. onpointerleave
  289. /// pointerover
  290. onpointerover
  291. /// pointerout
  292. onpointerout
  293. ];
  294. SelectionEvent: [
  295. /// onselect
  296. onselect
  297. ];
  298. TouchEvent: [
  299. /// ontouchcancel
  300. ontouchcancel
  301. /// ontouchend
  302. ontouchend
  303. /// ontouchmove
  304. ontouchmove
  305. /// ontouchstart
  306. ontouchstart
  307. ];
  308. WheelEvent: [
  309. ///
  310. onwheel
  311. ];
  312. MediaEvent: [
  313. ///abort
  314. onabort
  315. ///canplay
  316. oncanplay
  317. ///canplaythrough
  318. oncanplaythrough
  319. ///durationchange
  320. ondurationchange
  321. ///emptied
  322. onemptied
  323. ///encrypted
  324. onencrypted
  325. ///ended
  326. onended
  327. ///error
  328. onerror
  329. ///loadeddata
  330. onloadeddata
  331. ///loadedmetadata
  332. onloadedmetadata
  333. ///loadstart
  334. onloadstart
  335. ///pause
  336. onpause
  337. ///play
  338. onplay
  339. ///playing
  340. onplaying
  341. ///progress
  342. onprogress
  343. ///ratechange
  344. onratechange
  345. ///seeked
  346. onseeked
  347. ///seeking
  348. onseeking
  349. ///stalled
  350. onstalled
  351. ///suspend
  352. onsuspend
  353. ///timeupdate
  354. ontimeupdate
  355. ///volumechange
  356. onvolumechange
  357. ///waiting
  358. onwaiting
  359. ];
  360. AnimationEvent: [
  361. /// onanimationstart
  362. onanimationstart
  363. /// onanimationend
  364. onanimationend
  365. /// onanimationiteration
  366. onanimationiteration
  367. ];
  368. TransitionEvent: [
  369. ///
  370. ontransitionend
  371. ];
  372. ToggleEvent: [
  373. ///
  374. ontoggle
  375. ];
  376. }
  377. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  378. #[derive(Debug)]
  379. pub struct ClipboardEvent(
  380. // DOMDataTransfer clipboardData
  381. );
  382. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  383. #[derive(Debug)]
  384. pub struct CompositionEvent {
  385. pub data: String,
  386. }
  387. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  388. #[derive(Debug)]
  389. pub struct KeyboardEvent {
  390. pub char_code: u32,
  391. /// Identify which "key" was entered.
  392. ///
  393. /// This is the best method to use for all languages. They key gets mapped to a String sequence which you can match on.
  394. /// The key isn't an enum because there are just so many context-dependent keys.
  395. ///
  396. /// A full list on which keys to use is available at:
  397. /// <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values>
  398. ///
  399. /// # Example
  400. ///
  401. /// ```rust
  402. /// match event.key().as_str() {
  403. /// "Esc" | "Escape" => {}
  404. /// "ArrowDown" => {}
  405. /// "ArrowLeft" => {}
  406. /// _ => {}
  407. /// }
  408. /// ```
  409. ///
  410. pub key: String,
  411. /// Get the key code as an enum Variant.
  412. ///
  413. /// This is intended for things like arrow keys, escape keys, function keys, and other non-international keys.
  414. /// To match on unicode sequences, use the [`key`] method - this will return a string identifier instead of a limited enum.
  415. ///
  416. ///
  417. /// ## Example
  418. ///
  419. /// ```rust
  420. /// use dioxus::KeyCode;
  421. /// match event.key_code() {
  422. /// KeyCode::Escape => {}
  423. /// KeyCode::LeftArrow => {}
  424. /// KeyCode::RightArrow => {}
  425. /// _ => {}
  426. /// }
  427. /// ```
  428. ///
  429. pub key_code: KeyCode,
  430. /// Indicate if the `alt` modifier key was pressed during this keyboard event
  431. pub alt_key: bool,
  432. /// Indicate if the `ctrl` modifier key was pressed during this keyboard event
  433. pub ctrl_key: bool,
  434. /// Indicate if the `meta` modifier key was pressed during this keyboard event
  435. pub meta_key: bool,
  436. /// Indicate if the `shift` modifier key was pressed during this keyboard event
  437. pub shift_key: bool,
  438. pub locale: String,
  439. pub location: usize,
  440. pub repeat: bool,
  441. pub which: usize,
  442. // get_modifier_state: bool,
  443. }
  444. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  445. #[derive(Debug)]
  446. pub struct FocusEvent {/* DOMEventInner: Send + SyncTarget relatedTarget */}
  447. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  448. #[derive(Debug)]
  449. pub struct FormEvent {
  450. pub value: String,
  451. /* DOMEvent: Send + SyncTarget relatedTarget */
  452. }
  453. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  454. #[derive(Debug)]
  455. pub struct MouseEvent {
  456. pub alt_key: bool,
  457. pub button: i16,
  458. pub buttons: u16,
  459. pub client_x: i32,
  460. pub client_y: i32,
  461. pub ctrl_key: bool,
  462. pub meta_key: bool,
  463. pub page_x: i32,
  464. pub page_y: i32,
  465. pub screen_x: i32,
  466. pub screen_y: i32,
  467. pub shift_key: bool,
  468. // fn get_modifier_state(&self, key_code: &str) -> bool;
  469. }
  470. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  471. #[derive(Debug)]
  472. pub struct PointerEvent {
  473. // Mouse only
  474. pub alt_key: bool,
  475. pub button: i16,
  476. pub buttons: u16,
  477. pub client_x: i32,
  478. pub client_y: i32,
  479. pub ctrl_key: bool,
  480. pub meta_key: bool,
  481. pub page_x: i32,
  482. pub page_y: i32,
  483. pub screen_x: i32,
  484. pub screen_y: i32,
  485. pub shift_key: bool,
  486. pub pointer_id: i32,
  487. pub width: i32,
  488. pub height: i32,
  489. pub pressure: f32,
  490. pub tangential_pressure: f32,
  491. pub tilt_x: i32,
  492. pub tilt_y: i32,
  493. pub twist: i32,
  494. pub pointer_type: String,
  495. pub is_primary: bool,
  496. // pub get_modifier_state: bool,
  497. }
  498. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  499. #[derive(Debug)]
  500. pub struct SelectionEvent {}
  501. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  502. #[derive(Debug)]
  503. pub struct TouchEvent {
  504. pub alt_key: bool,
  505. pub ctrl_key: bool,
  506. pub meta_key: bool,
  507. pub shift_key: bool,
  508. // get_modifier_state: bool,
  509. // changedTouches: DOMTouchList,
  510. // targetTouches: DOMTouchList,
  511. // touches: DOMTouchList,
  512. }
  513. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  514. #[derive(Debug)]
  515. pub struct WheelEvent {
  516. pub delta_mode: u32,
  517. pub delta_x: f64,
  518. pub delta_y: f64,
  519. pub delta_z: f64,
  520. }
  521. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  522. #[derive(Debug)]
  523. pub struct MediaEvent {}
  524. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  525. #[derive(Debug)]
  526. pub struct ImageEvent {
  527. pub load_error: bool,
  528. }
  529. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  530. #[derive(Debug)]
  531. pub struct AnimationEvent {
  532. pub animation_name: String,
  533. pub pseudo_element: String,
  534. pub elapsed_time: f32,
  535. }
  536. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  537. #[derive(Debug)]
  538. pub struct TransitionEvent {
  539. pub property_name: String,
  540. pub pseudo_element: String,
  541. pub elapsed_time: f32,
  542. }
  543. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  544. #[derive(Debug)]
  545. pub struct ToggleEvent {}
  546. }
  547. #[cfg_attr(
  548. feature = "serialize",
  549. derive(serde_repr::Serialize_repr, serde_repr::Deserialize_repr)
  550. )]
  551. #[derive(Clone, Copy, Debug)]
  552. #[repr(u8)]
  553. pub enum KeyCode {
  554. // That key has no keycode, = 0
  555. // break, = 3
  556. // backspace / delete, = 8
  557. // tab, = 9
  558. // clear, = 12
  559. // enter, = 13
  560. // shift, = 16
  561. // ctrl, = 17
  562. // alt, = 18
  563. // pause/break, = 19
  564. // caps lock, = 20
  565. // hangul, = 21
  566. // hanja, = 25
  567. // escape, = 27
  568. // conversion, = 28
  569. // non-conversion, = 29
  570. // spacebar, = 32
  571. // page up, = 33
  572. // page down, = 34
  573. // end, = 35
  574. // home, = 36
  575. // left arrow, = 37
  576. // up arrow, = 38
  577. // right arrow, = 39
  578. // down arrow, = 40
  579. // select, = 41
  580. // print, = 42
  581. // execute, = 43
  582. // Print Screen, = 44
  583. // insert, = 45
  584. // delete, = 46
  585. // help, = 47
  586. // 0, = 48
  587. // 1, = 49
  588. // 2, = 50
  589. // 3, = 51
  590. // 4, = 52
  591. // 5, = 53
  592. // 6, = 54
  593. // 7, = 55
  594. // 8, = 56
  595. // 9, = 57
  596. // :, = 58
  597. // semicolon (firefox), equals, = 59
  598. // <, = 60
  599. // equals (firefox), = 61
  600. // ß, = 63
  601. // @ (firefox), = 64
  602. // a, = 65
  603. // b, = 66
  604. // c, = 67
  605. // d, = 68
  606. // e, = 69
  607. // f, = 70
  608. // g, = 71
  609. // h, = 72
  610. // i, = 73
  611. // j, = 74
  612. // k, = 75
  613. // l, = 76
  614. // m, = 77
  615. // n, = 78
  616. // o, = 79
  617. // p, = 80
  618. // q, = 81
  619. // r, = 82
  620. // s, = 83
  621. // t, = 84
  622. // u, = 85
  623. // v, = 86
  624. // w, = 87
  625. // x, = 88
  626. // y, = 89
  627. // z, = 90
  628. // Windows Key / Left ⌘ / Chromebook Search key, = 91
  629. // right window key, = 92
  630. // Windows Menu / Right ⌘, = 93
  631. // sleep, = 95
  632. // numpad 0, = 96
  633. // numpad 1, = 97
  634. // numpad 2, = 98
  635. // numpad 3, = 99
  636. // numpad 4, = 100
  637. // numpad 5, = 101
  638. // numpad 6, = 102
  639. // numpad 7, = 103
  640. // numpad 8, = 104
  641. // numpad 9, = 105
  642. // multiply, = 106
  643. // add, = 107
  644. // numpad period (firefox), = 108
  645. // subtract, = 109
  646. // decimal point, = 110
  647. // divide, = 111
  648. // f1, = 112
  649. // f2, = 113
  650. // f3, = 114
  651. // f4, = 115
  652. // f5, = 116
  653. // f6, = 117
  654. // f7, = 118
  655. // f8, = 119
  656. // f9, = 120
  657. // f10, = 121
  658. // f11, = 122
  659. // f12, = 123
  660. // f13, = 124
  661. // f14, = 125
  662. // f15, = 126
  663. // f16, = 127
  664. // f17, = 128
  665. // f18, = 129
  666. // f19, = 130
  667. // f20, = 131
  668. // f21, = 132
  669. // f22, = 133
  670. // f23, = 134
  671. // f24, = 135
  672. // f25, = 136
  673. // f26, = 137
  674. // f27, = 138
  675. // f28, = 139
  676. // f29, = 140
  677. // f30, = 141
  678. // f31, = 142
  679. // f32, = 143
  680. // num lock, = 144
  681. // scroll lock, = 145
  682. // airplane mode, = 151
  683. // ^, = 160
  684. // !, = 161
  685. // ؛ (arabic semicolon), = 162
  686. // #, = 163
  687. // $, = 164
  688. // ù, = 165
  689. // page backward, = 166
  690. // page forward, = 167
  691. // refresh, = 168
  692. // closing paren (AZERTY), = 169
  693. // *, = 170
  694. // ~ + * key, = 171
  695. // home key, = 172
  696. // minus (firefox), mute/unmute, = 173
  697. // decrease volume level, = 174
  698. // increase volume level, = 175
  699. // next, = 176
  700. // previous, = 177
  701. // stop, = 178
  702. // play/pause, = 179
  703. // e-mail, = 180
  704. // mute/unmute (firefox), = 181
  705. // decrease volume level (firefox), = 182
  706. // increase volume level (firefox), = 183
  707. // semi-colon / ñ, = 186
  708. // equal sign, = 187
  709. // comma, = 188
  710. // dash, = 189
  711. // period, = 190
  712. // forward slash / ç, = 191
  713. // grave accent / ñ / æ / ö, = 192
  714. // ?, / or °, = 193
  715. // numpad period (chrome), = 194
  716. // open bracket, = 219
  717. // back slash, = 220
  718. // close bracket / å, = 221
  719. // single quote / ø / ä, = 222
  720. // `, = 223
  721. // left or right ⌘ key (firefox), = 224
  722. // altgr, = 225
  723. // < /git >, left back slash, = 226
  724. // GNOME Compose Key, = 230
  725. // ç, = 231
  726. // XF86Forward, = 233
  727. // XF86Back, = 234
  728. // non-conversion, = 235
  729. // alphanumeric, = 240
  730. // hiragana/katakana, = 242
  731. // half-width/full-width, = 243
  732. // kanji, = 244
  733. // unlock trackpad (Chrome/Edge), = 251
  734. // toggle touchpad, = 255
  735. NA = 0,
  736. Break = 3,
  737. Backspace = 8,
  738. Tab = 9,
  739. Clear = 12,
  740. Enter = 13,
  741. Shift = 16,
  742. Ctrl = 17,
  743. Alt = 18,
  744. Pause = 19,
  745. CapsLock = 20,
  746. // hangul, = 21
  747. // hanja, = 25
  748. Escape = 27,
  749. // conversion, = 28
  750. // non-conversion, = 29
  751. Space = 32,
  752. PageUp = 33,
  753. PageDown = 34,
  754. End = 35,
  755. Home = 36,
  756. LeftArrow = 37,
  757. UpArrow = 38,
  758. RightArrow = 39,
  759. DownArrow = 40,
  760. // select, = 41
  761. // print, = 42
  762. // execute, = 43
  763. // Print Screen, = 44
  764. Insert = 45,
  765. Delete = 46,
  766. // help, = 47
  767. Num0 = 48,
  768. Num1 = 49,
  769. Num2 = 50,
  770. Num3 = 51,
  771. Num4 = 52,
  772. Num5 = 53,
  773. Num6 = 54,
  774. Num7 = 55,
  775. Num8 = 56,
  776. Num9 = 57,
  777. // :, = 58
  778. // semicolon (firefox), equals, = 59
  779. // <, = 60
  780. // equals (firefox), = 61
  781. // ß, = 63
  782. // @ (firefox), = 64
  783. A = 65,
  784. B = 66,
  785. C = 67,
  786. D = 68,
  787. E = 69,
  788. F = 70,
  789. G = 71,
  790. H = 72,
  791. I = 73,
  792. J = 74,
  793. K = 75,
  794. L = 76,
  795. M = 77,
  796. N = 78,
  797. O = 79,
  798. P = 80,
  799. Q = 81,
  800. R = 82,
  801. S = 83,
  802. T = 84,
  803. U = 85,
  804. V = 86,
  805. W = 87,
  806. X = 88,
  807. Y = 89,
  808. Z = 90,
  809. LeftWindow = 91,
  810. RightWindow = 92,
  811. SelectKey = 93,
  812. Numpad0 = 96,
  813. Numpad1 = 97,
  814. Numpad2 = 98,
  815. Numpad3 = 99,
  816. Numpad4 = 100,
  817. Numpad5 = 101,
  818. Numpad6 = 102,
  819. Numpad7 = 103,
  820. Numpad8 = 104,
  821. Numpad9 = 105,
  822. Multiply = 106,
  823. Add = 107,
  824. Subtract = 109,
  825. DecimalPoint = 110,
  826. Divide = 111,
  827. F1 = 112,
  828. F2 = 113,
  829. F3 = 114,
  830. F4 = 115,
  831. F5 = 116,
  832. F6 = 117,
  833. F7 = 118,
  834. F8 = 119,
  835. F9 = 120,
  836. F10 = 121,
  837. F11 = 122,
  838. F12 = 123,
  839. // f13, = 124
  840. // f14, = 125
  841. // f15, = 126
  842. // f16, = 127
  843. // f17, = 128
  844. // f18, = 129
  845. // f19, = 130
  846. // f20, = 131
  847. // f21, = 132
  848. // f22, = 133
  849. // f23, = 134
  850. // f24, = 135
  851. // f25, = 136
  852. // f26, = 137
  853. // f27, = 138
  854. // f28, = 139
  855. // f29, = 140
  856. // f30, = 141
  857. // f31, = 142
  858. // f32, = 143
  859. NumLock = 144,
  860. ScrollLock = 145,
  861. // airplane mode, = 151
  862. // ^, = 160
  863. // !, = 161
  864. // ؛ (arabic semicolon), = 162
  865. // #, = 163
  866. // $, = 164
  867. // ù, = 165
  868. // page backward, = 166
  869. // page forward, = 167
  870. // refresh, = 168
  871. // closing paren (AZERTY), = 169
  872. // *, = 170
  873. // ~ + * key, = 171
  874. // home key, = 172
  875. // minus (firefox), mute/unmute, = 173
  876. // decrease volume level, = 174
  877. // increase volume level, = 175
  878. // next, = 176
  879. // previous, = 177
  880. // stop, = 178
  881. // play/pause, = 179
  882. // e-mail, = 180
  883. // mute/unmute (firefox), = 181
  884. // decrease volume level (firefox), = 182
  885. // increase volume level (firefox), = 183
  886. Semicolon = 186,
  887. EqualSign = 187,
  888. Comma = 188,
  889. Dash = 189,
  890. Period = 190,
  891. ForwardSlash = 191,
  892. GraveAccent = 192,
  893. // ?, / or °, = 193
  894. // numpad period (chrome), = 194
  895. OpenBracket = 219,
  896. BackSlash = 220,
  897. CloseBraket = 221,
  898. SingleQuote = 222,
  899. // `, = 223
  900. // left or right ⌘ key (firefox), = 224
  901. // altgr, = 225
  902. // < /git >, left back slash, = 226
  903. // GNOME Compose Key, = 230
  904. // ç, = 231
  905. // XF86Forward, = 233
  906. // XF86Back, = 234
  907. // non-conversion, = 235
  908. // alphanumeric, = 240
  909. // hiragana/katakana, = 242
  910. // half-width/full-width, = 243
  911. // kanji, = 244
  912. // unlock trackpad (Chrome/Edge), = 251
  913. // toggle touchpad, = 255
  914. #[cfg_attr(feature = "serialize", serde(other))]
  915. Unknown,
  916. }
  917. impl KeyCode {
  918. pub fn from_raw_code(i: u8) -> Self {
  919. use KeyCode::*;
  920. match i {
  921. 8 => Backspace,
  922. 9 => Tab,
  923. 13 => Enter,
  924. 16 => Shift,
  925. 17 => Ctrl,
  926. 18 => Alt,
  927. 19 => Pause,
  928. 20 => CapsLock,
  929. 27 => Escape,
  930. 33 => PageUp,
  931. 34 => PageDown,
  932. 35 => End,
  933. 36 => Home,
  934. 37 => LeftArrow,
  935. 38 => UpArrow,
  936. 39 => RightArrow,
  937. 40 => DownArrow,
  938. 45 => Insert,
  939. 46 => Delete,
  940. 48 => Num0,
  941. 49 => Num1,
  942. 50 => Num2,
  943. 51 => Num3,
  944. 52 => Num4,
  945. 53 => Num5,
  946. 54 => Num6,
  947. 55 => Num7,
  948. 56 => Num8,
  949. 57 => Num9,
  950. 65 => A,
  951. 66 => B,
  952. 67 => C,
  953. 68 => D,
  954. 69 => E,
  955. 70 => F,
  956. 71 => G,
  957. 72 => H,
  958. 73 => I,
  959. 74 => J,
  960. 75 => K,
  961. 76 => L,
  962. 77 => M,
  963. 78 => N,
  964. 79 => O,
  965. 80 => P,
  966. 81 => Q,
  967. 82 => R,
  968. 83 => S,
  969. 84 => T,
  970. 85 => U,
  971. 86 => V,
  972. 87 => W,
  973. 88 => X,
  974. 89 => Y,
  975. 90 => Z,
  976. 91 => LeftWindow,
  977. 92 => RightWindow,
  978. 93 => SelectKey,
  979. 96 => Numpad0,
  980. 97 => Numpad1,
  981. 98 => Numpad2,
  982. 99 => Numpad3,
  983. 100 => Numpad4,
  984. 101 => Numpad5,
  985. 102 => Numpad6,
  986. 103 => Numpad7,
  987. 104 => Numpad8,
  988. 105 => Numpad9,
  989. 106 => Multiply,
  990. 107 => Add,
  991. 109 => Subtract,
  992. 110 => DecimalPoint,
  993. 111 => Divide,
  994. 112 => F1,
  995. 113 => F2,
  996. 114 => F3,
  997. 115 => F4,
  998. 116 => F5,
  999. 117 => F6,
  1000. 118 => F7,
  1001. 119 => F8,
  1002. 120 => F9,
  1003. 121 => F10,
  1004. 122 => F11,
  1005. 123 => F12,
  1006. 144 => NumLock,
  1007. 145 => ScrollLock,
  1008. 186 => Semicolon,
  1009. 187 => EqualSign,
  1010. 188 => Comma,
  1011. 189 => Dash,
  1012. 190 => Period,
  1013. 191 => ForwardSlash,
  1014. 192 => GraveAccent,
  1015. 219 => OpenBracket,
  1016. 220 => BackSlash,
  1017. 221 => CloseBraket,
  1018. 222 => SingleQuote,
  1019. _ => Unknown,
  1020. }
  1021. }
  1022. // get the raw code
  1023. pub fn raw_code(&self) -> u32 {
  1024. *self as u32
  1025. }
  1026. }
  1027. pub(crate) fn event_meta(event: &UserEvent) -> (bool, EventPriority) {
  1028. use EventPriority::*;
  1029. match event.name {
  1030. // clipboard
  1031. "copy" | "cut" | "paste" => (true, Medium),
  1032. // Composition
  1033. "compositionend" | "compositionstart" | "compositionupdate" => (true, Low),
  1034. // Keyboard
  1035. "keydown" | "keypress" | "keyup" => (true, High),
  1036. // Focus
  1037. "focus" | "blur" => (true, Low),
  1038. // Form
  1039. "change" | "input" | "invalid" | "reset" | "submit" => (true, Medium),
  1040. // Mouse
  1041. "click" | "contextmenu" | "doubleclick" | "drag" | "dragend" | "dragenter" | "dragexit"
  1042. | "dragleave" | "dragover" | "dragstart" | "drop" | "mousedown" | "mouseenter"
  1043. | "mouseleave" | "mouseout" | "mouseover" | "mouseup" => (true, High),
  1044. "mousemove" => (false, Medium),
  1045. // Pointer
  1046. "pointerdown" | "pointermove" | "pointerup" | "pointercancel" | "gotpointercapture"
  1047. | "lostpointercapture" | "pointerenter" | "pointerleave" | "pointerover" | "pointerout" => {
  1048. (true, Medium)
  1049. }
  1050. // Selection
  1051. "select" | "touchcancel" | "touchend" => (true, Medium),
  1052. // Touch
  1053. "touchmove" | "touchstart" => (true, Medium),
  1054. // Wheel
  1055. "scroll" | "wheel" => (false, Medium),
  1056. // Media
  1057. "abort" | "canplay" | "canplaythrough" | "durationchange" | "emptied" | "encrypted"
  1058. | "ended" | "error" | "loadeddata" | "loadedmetadata" | "loadstart" | "pause" | "play"
  1059. | "playing" | "progress" | "ratechange" | "seeked" | "seeking" | "stalled" | "suspend"
  1060. | "timeupdate" | "volumechange" | "waiting" => (true, Medium),
  1061. // Animation
  1062. "animationstart" | "animationend" | "animationiteration" => (true, Medium),
  1063. // Transition
  1064. "transitionend" => (true, Medium),
  1065. // Toggle
  1066. "toggle" => (true, Medium),
  1067. _ => (true, Low),
  1068. }
  1069. }