Skip to content

Commit

Permalink
Fix WindowEvent::ReceivedCharacter on web (#1747)
Browse files Browse the repository at this point in the history
* Fix WindowEvent::ReceivedCharacter on web

The event was never sent to the application because of the unconditional
preventDefault() call on keydown.

Fixes #1741

* Don't scroll when pressing space on a focused canvas

After reaching keypress, we should prevent further propagation.

Relates to #1741
  • Loading branch information
tronical authored Oct 29, 2020
1 parent 66c117e commit 33fb62b
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- On Wayland, fix window not being resizeable when using `with_min_inner_size` in `WindowBuilder`.
- On Unix, fix cross-compiling to wasm32 without enabling X11 or Wayland.
- On Windows, fix use after free crash during window destruction.
- On Web, fix `WindowEvent::ReceivedCharacter` never being sent on key input.

# 0.23.0 (2020-10-02)

Expand Down
20 changes: 16 additions & 4 deletions src/platform_impl/web/stdweb/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use stdweb::js;
use stdweb::traits::IPointerEvent;
use stdweb::unstable::TryInto;
use stdweb::web::event::{
BlurEvent, ConcreteEvent, FocusEvent, FullscreenChangeEvent, IEvent, KeyDownEvent,
KeyPressEvent, KeyUpEvent, MouseWheelEvent, PointerDownEvent, PointerMoveEvent,
PointerOutEvent, PointerOverEvent, PointerUpEvent,
BlurEvent, ConcreteEvent, FocusEvent, FullscreenChangeEvent, IEvent, IKeyboardEvent,
KeyDownEvent, KeyPressEvent, KeyUpEvent, ModifierKey, MouseWheelEvent, PointerDownEvent,
PointerMoveEvent, PointerOutEvent, PointerOverEvent, PointerUpEvent,
};
use stdweb::web::html_element::CanvasElement;
use stdweb::web::{document, EventListenerHandle, IElement, IEventTarget, IHtmlElement};
Expand Down Expand Up @@ -136,7 +136,17 @@ impl Canvas {
F: 'static + FnMut(ScanCode, Option<VirtualKeyCode>, ModifiersState),
{
self.on_keyboard_press = Some(self.add_user_event(move |event: KeyDownEvent| {
event.prevent_default();
// event.prevent_default() would suppress subsequent on_received_character() calls. That
// supression is correct for key sequences like Tab/Shift-Tab, Ctrl+R, PgUp/Down to
// scroll, etc. We should not do it for key sequences that result in meaningful character
// input though.
let event_key = &event.key();
let is_key_string = event_key.len() == 1 || !event_key.is_ascii();
let is_shortcut_modifiers = (event.ctrl_key() || event.alt_key())
&& !event.get_modifier_state(ModifierKey::AltGr);
if !is_key_string || is_shortcut_modifiers {
event.prevent_default();
}
handler(
event::scan_code(&event),
event::virtual_key_code(&event),
Expand All @@ -155,6 +165,8 @@ impl Canvas {
// viable/compatible alternative as of now. `beforeinput` is still widely
// unsupported.
self.on_received_character = Some(self.add_user_event(move |event: KeyPressEvent| {
// Supress further handling to stop keys like the space key from scrolling the page.
event.prevent_default();
handler(event::codepoint(&event));
}));
}
Expand Down
14 changes: 13 additions & 1 deletion src/platform_impl/web/web_sys/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,17 @@ impl Canvas {
self.on_keyboard_press = Some(self.common.add_user_event(
"keydown",
move |event: KeyboardEvent| {
event.prevent_default();
// event.prevent_default() would suppress subsequent on_received_character() calls. That
// supression is correct for key sequences like Tab/Shift-Tab, Ctrl+R, PgUp/Down to
// scroll, etc. We should not do it for key sequences that result in meaningful character
// input though.
let event_key = &event.key();
let is_key_string = event_key.len() == 1 || !event_key.is_ascii();
let is_shortcut_modifiers =
(event.ctrl_key() || event.alt_key()) && !event.get_modifier_state("AltGr");
if !is_key_string || is_shortcut_modifiers {
event.prevent_default();
}
handler(
event::scan_code(&event),
event::virtual_key_code(&event),
Expand All @@ -179,6 +189,8 @@ impl Canvas {
self.on_received_character = Some(self.common.add_user_event(
"keypress",
move |event: KeyboardEvent| {
// Supress further handling to stop keys like the space key from scrolling the page.
event.prevent_default();
handler(event::codepoint(&event));
},
));
Expand Down

0 comments on commit 33fb62b

Please sign in to comment.