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 13, 2023
1 parent e5e322a commit 414fad0
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 @@ -81,7 +81,8 @@ And please only add new entries to the top of this list, right below the `# Unre
- On Web, use `Window.requestIdleCallback()` for `ControlFlow::Poll` when available.
- 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,6 +1,8 @@
use super::super::DeviceId;
use super::{super::ScaleChangeArgs, backend, state::State};
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 @@ -15,7 +17,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 Down Expand Up @@ -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 @@ -126,8 +130,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 @@ -259,7 +265,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 @@ -282,7 +288,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 @@ -304,6 +310,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,
}),
});
}),
));
}

pub(crate) fn set_on_scale_change<F>(&self, handler: F)
Expand Down Expand Up @@ -645,8 +687,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::{
};
use crate::dpi::Size;
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 @@ -141,24 +141,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 @@ -176,24 +188,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 414fad0

Please sign in to comment.