Skip to content

Commit

Permalink
Implement DeviceEvent::Key
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Jun 14, 2023
1 parent c8add62 commit d083e4e
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 45 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ And please only add new entries to the top of this list, right below the `# Unre
the canvas size will be reported through `WindowEvent::Resized`.
- On Web, respect `EventLoopWindowTarget::listen_device_events()` settings.
- On Web, fix `DeviceEvent::MouseMotion` only being emitted for each canvas instead of the whole window.
- On Web, add `DeviceEvent::Motion`, `DeviceEvent::MouseWheel` and `DeviceEvent::Button` support.
- On Web, add `DeviceEvent::Motion`, `DeviceEvent::MouseWheel`, `DeviceEvent::Button` and
`DeviceEvent::Key` support.

# 0.28.6

Expand Down
64 changes: 54 additions & 10 deletions src/platform_impl/web/event_loop/runner.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use super::super::DeviceId;
use super::{backend, state::State};
use crate::dpi::PhysicalSize;
use crate::event::{DeviceEvent, DeviceId as RootDeviceId, ElementState, Event, StartCause};
use crate::event::{
DeviceEvent, DeviceId as RootDeviceId, ElementState, Event, RawKeyEvent, StartCause,
};
use crate::event_loop::{ControlFlow, DeviceEvents};
use crate::platform_impl::platform::backend::EventListenerHandle;
use crate::window::WindowId;
Expand All @@ -16,7 +18,7 @@ use std::{
rc::{Rc, Weak},
};
use wasm_bindgen::prelude::Closure;
use web_sys::{PointerEvent, WheelEvent};
use web_sys::{KeyboardEvent, PointerEvent, WheelEvent};
use web_time::{Duration, Instant};

pub struct Shared<T: 'static>(Rc<Execution<T>>);
Expand All @@ -43,8 +45,10 @@ pub struct Execution<T: 'static> {
device_events: Cell<DeviceEvents>,
on_mouse_move: OnEventHandle<PointerEvent>,
on_wheel: OnEventHandle<WheelEvent>,
on_press: OnEventHandle<PointerEvent>,
on_release: OnEventHandle<PointerEvent>,
on_mouse_press: OnEventHandle<PointerEvent>,
on_mouse_release: OnEventHandle<PointerEvent>,
on_key_press: OnEventHandle<KeyboardEvent>,
on_key_release: OnEventHandle<KeyboardEvent>,
}

enum RunnerEnum<T: 'static> {
Expand Down Expand Up @@ -146,8 +150,10 @@ impl<T: 'static> Shared<T> {
device_events: Cell::default(),
on_mouse_move: RefCell::new(None),
on_wheel: RefCell::new(None),
on_press: RefCell::new(None),
on_release: RefCell::new(None),
on_mouse_press: RefCell::new(None),
on_mouse_release: RefCell::new(None),
on_key_press: RefCell::new(None),
on_key_release: RefCell::new(None),
}))
}

Expand Down Expand Up @@ -279,7 +285,7 @@ impl<T: 'static> Shared<T> {
}),
));
let runner = self.clone();
*self.0.on_press.borrow_mut() = Some(EventListenerHandle::new(
*self.0.on_mouse_press.borrow_mut() = Some(EventListenerHandle::new(
self.window(),
"pointerdown",
Closure::new(move |event: PointerEvent| {
Expand All @@ -302,7 +308,7 @@ impl<T: 'static> Shared<T> {
}),
));
let runner = self.clone();
*self.0.on_release.borrow_mut() = Some(EventListenerHandle::new(
*self.0.on_mouse_release.borrow_mut() = Some(EventListenerHandle::new(
self.window(),
"pointerup",
Closure::new(move |event: PointerEvent| {
Expand All @@ -324,6 +330,42 @@ impl<T: 'static> Shared<T> {
});
}),
));
let runner = self.clone();
*self.0.on_key_press.borrow_mut() = Some(EventListenerHandle::new(
self.window(),
"keydown",
Closure::new(move |event: KeyboardEvent| {
if !runner.device_events() {
return;
}

runner.send_event(Event::DeviceEvent {
device_id: RootDeviceId(unsafe { DeviceId::dummy() }),
event: DeviceEvent::Key(RawKeyEvent {
physical_key: backend::event::key_code(&event),
state: ElementState::Pressed,
}),
});
}),
));
let runner = self.clone();
*self.0.on_key_release.borrow_mut() = Some(EventListenerHandle::new(
self.window(),
"keyup",
Closure::new(move |event: KeyboardEvent| {
if !runner.device_events() {
return;
}

runner.send_event(Event::DeviceEvent {
device_id: RootDeviceId(unsafe { DeviceId::dummy() }),
event: DeviceEvent::Key(RawKeyEvent {
physical_key: backend::event::key_code(&event),
state: ElementState::Released,
}),
});
}),
));
}

// Generate a strictly increasing ID
Expand Down Expand Up @@ -566,8 +608,10 @@ impl<T: 'static> Shared<T> {
*self.0.unload_event_handle.borrow_mut() = None;
*self.0.on_mouse_move.borrow_mut() = None;
*self.0.on_wheel.borrow_mut() = None;
*self.0.on_press.borrow_mut() = None;
*self.0.on_release.borrow_mut() = None;
*self.0.on_mouse_press.borrow_mut() = None;
*self.0.on_mouse_release.borrow_mut() = None;
*self.0.on_key_press.borrow_mut() = None;
*self.0.on_key_release.borrow_mut() = None;
// Dropping the `Runner` drops the event handler closure, which will in
// turn drop all `Window`s moved into the closure.
*self.0.runner.borrow_mut() = RunnerEnum::Destroyed;
Expand Down
92 changes: 58 additions & 34 deletions src/platform_impl/web/event_loop/window_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use super::{
window::WindowId,
};
use crate::event::{
DeviceEvent, DeviceId as RootDeviceId, ElementState, Event, KeyEvent, Touch, TouchPhase,
WindowEvent,
DeviceEvent, DeviceId as RootDeviceId, ElementState, Event, KeyEvent, RawKeyEvent, Touch,
TouchPhase, WindowEvent,
};
use crate::event_loop::DeviceEvents;
use crate::keyboard::ModifiersState;
Expand Down Expand Up @@ -137,24 +137,36 @@ impl<T> EventLoopWindowTarget<T> {
}
});

let device_id = RootDeviceId(unsafe { DeviceId::dummy() });

let device_event = runner.device_events().then_some(Event::DeviceEvent {
device_id,
event: DeviceEvent::Key(RawKeyEvent {
physical_key,
state: ElementState::Pressed,
}),
});

runner.send_events(
iter::once(Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::KeyboardInput {
device_id: RootDeviceId(unsafe { DeviceId::dummy() }),
event: KeyEvent {
physical_key,
logical_key,
text,
location,
state: ElementState::Pressed,
repeat,
platform_specific: KeyEventExtra,
device_event
.into_iter()
.chain(iter::once(Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::KeyboardInput {
device_id,
event: KeyEvent {
physical_key,
logical_key,
text,
location,
state: ElementState::Pressed,
repeat,
platform_specific: KeyEventExtra,
},
is_synthetic: false,
},
is_synthetic: false,
},
})
.chain(modifiers_changed),
}))
.chain(modifiers_changed),
);
},
prevent_default,
Expand All @@ -172,24 +184,36 @@ impl<T> EventLoopWindowTarget<T> {
}
});

let device_id = RootDeviceId(unsafe { DeviceId::dummy() });

let device_event = runner.device_events().then_some(Event::DeviceEvent {
device_id,
event: DeviceEvent::Key(RawKeyEvent {
physical_key,
state: ElementState::Pressed,
}),
});

runner.send_events(
iter::once(Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::KeyboardInput {
device_id: RootDeviceId(unsafe { DeviceId::dummy() }),
event: KeyEvent {
physical_key,
logical_key,
text,
location,
state: ElementState::Released,
repeat,
platform_specific: KeyEventExtra,
device_event
.into_iter()
.chain(iter::once(Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::KeyboardInput {
device_id,
event: KeyEvent {
physical_key,
logical_key,
text,
location,
state: ElementState::Released,
repeat,
platform_specific: KeyEventExtra,
},
is_synthetic: false,
},
is_synthetic: false,
},
})
.chain(modifiers_changed),
}))
.chain(modifiers_changed),
)
},
prevent_default,
Expand Down

0 comments on commit d083e4e

Please sign in to comment.