mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +11:00
Web: Use mouse events instead of pointer events if the latter isn't supported (#1630)
* Fixed Safari not getting mouse events * Edited changelog * Addressed compiler warnings Co-authored-by: Ryan G <ryanisaacg@users.noreply.github.com>
This commit is contained in:
parent
7a49c88200
commit
05fdcb5b27
|
@ -10,6 +10,7 @@
|
||||||
- On android added support for `run_return`.
|
- On android added support for `run_return`.
|
||||||
- On MacOS, Fixed fullscreen and dialog support for `run_return`.
|
- On MacOS, Fixed fullscreen and dialog support for `run_return`.
|
||||||
- On Windows, fix bug where we'd try to emit `MainEventsCleared` events during nested win32 event loops.
|
- On Windows, fix bug where we'd try to emit `MainEventsCleared` events during nested win32 event loops.
|
||||||
|
- On Web, use mouse events if pointer events aren't supported. This affects Safari.
|
||||||
- On Windows, `set_ime_position` is now a no-op instead of a runtime crash.
|
- On Windows, `set_ime_position` is now a no-op instead of a runtime crash.
|
||||||
- On Android, `set_fullscreen` is now a no-op instead of a runtime crash.
|
- On Android, `set_fullscreen` is now a no-op instead of a runtime crash.
|
||||||
- On iOS and Android, `set_inner_size` is now a no-op instead of a runtime crash.
|
- On iOS and Android, `set_inner_size` is now a no-op instead of a runtime crash.
|
||||||
|
|
|
@ -9,8 +9,8 @@ use std::rc::Rc;
|
||||||
|
|
||||||
use wasm_bindgen::{closure::Closure, JsCast};
|
use wasm_bindgen::{closure::Closure, JsCast};
|
||||||
use web_sys::{
|
use web_sys::{
|
||||||
Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, MediaQueryListEvent, PointerEvent,
|
Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, MediaQueryListEvent, MouseEvent,
|
||||||
WheelEvent,
|
PointerEvent, WheelEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Canvas {
|
pub struct Canvas {
|
||||||
|
@ -24,8 +24,14 @@ pub struct Canvas {
|
||||||
on_cursor_leave: Option<Closure<dyn FnMut(PointerEvent)>>,
|
on_cursor_leave: Option<Closure<dyn FnMut(PointerEvent)>>,
|
||||||
on_cursor_enter: Option<Closure<dyn FnMut(PointerEvent)>>,
|
on_cursor_enter: Option<Closure<dyn FnMut(PointerEvent)>>,
|
||||||
on_cursor_move: Option<Closure<dyn FnMut(PointerEvent)>>,
|
on_cursor_move: Option<Closure<dyn FnMut(PointerEvent)>>,
|
||||||
on_mouse_press: Option<Closure<dyn FnMut(PointerEvent)>>,
|
on_pointer_press: Option<Closure<dyn FnMut(PointerEvent)>>,
|
||||||
on_mouse_release: Option<Closure<dyn FnMut(PointerEvent)>>,
|
on_pointer_release: Option<Closure<dyn FnMut(PointerEvent)>>,
|
||||||
|
// Fallback events when pointer event support is missing
|
||||||
|
on_mouse_leave: Option<Closure<dyn FnMut(MouseEvent)>>,
|
||||||
|
on_mouse_enter: Option<Closure<dyn FnMut(MouseEvent)>>,
|
||||||
|
on_mouse_move: Option<Closure<dyn FnMut(MouseEvent)>>,
|
||||||
|
on_mouse_press: Option<Closure<dyn FnMut(MouseEvent)>>,
|
||||||
|
on_mouse_release: Option<Closure<dyn FnMut(MouseEvent)>>,
|
||||||
on_mouse_wheel: Option<Closure<dyn FnMut(WheelEvent)>>,
|
on_mouse_wheel: Option<Closure<dyn FnMut(WheelEvent)>>,
|
||||||
on_fullscreen_change: Option<Closure<dyn FnMut(Event)>>,
|
on_fullscreen_change: Option<Closure<dyn FnMut(Event)>>,
|
||||||
wants_fullscreen: Rc<RefCell<bool>>,
|
wants_fullscreen: Rc<RefCell<bool>>,
|
||||||
|
@ -76,8 +82,13 @@ impl Canvas {
|
||||||
on_cursor_leave: None,
|
on_cursor_leave: None,
|
||||||
on_cursor_enter: None,
|
on_cursor_enter: None,
|
||||||
on_cursor_move: None,
|
on_cursor_move: None,
|
||||||
on_mouse_release: None,
|
on_pointer_release: None,
|
||||||
|
on_pointer_press: None,
|
||||||
|
on_mouse_leave: None,
|
||||||
|
on_mouse_enter: None,
|
||||||
|
on_mouse_move: None,
|
||||||
on_mouse_press: None,
|
on_mouse_press: None,
|
||||||
|
on_mouse_release: None,
|
||||||
on_mouse_wheel: None,
|
on_mouse_wheel: None,
|
||||||
on_fullscreen_change: None,
|
on_fullscreen_change: None,
|
||||||
wants_fullscreen: Rc::new(RefCell::new(false)),
|
wants_fullscreen: Rc::new(RefCell::new(false)),
|
||||||
|
@ -180,63 +191,110 @@ impl Canvas {
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(i32),
|
F: 'static + FnMut(i32),
|
||||||
{
|
{
|
||||||
self.on_cursor_leave = Some(self.add_event("pointerout", move |event: PointerEvent| {
|
if has_pointer_event() {
|
||||||
handler(event.pointer_id());
|
self.on_cursor_leave =
|
||||||
}));
|
Some(self.add_event("pointerout", move |event: PointerEvent| {
|
||||||
|
handler(event.pointer_id());
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
self.on_mouse_leave = Some(self.add_event("mouseout", move |_: MouseEvent| {
|
||||||
|
handler(0);
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_cursor_enter<F>(&mut self, mut handler: F)
|
pub fn on_cursor_enter<F>(&mut self, mut handler: F)
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(i32),
|
F: 'static + FnMut(i32),
|
||||||
{
|
{
|
||||||
self.on_cursor_enter = Some(self.add_event("pointerover", move |event: PointerEvent| {
|
if has_pointer_event() {
|
||||||
handler(event.pointer_id());
|
self.on_cursor_enter =
|
||||||
}));
|
Some(self.add_event("pointerover", move |event: PointerEvent| {
|
||||||
|
handler(event.pointer_id());
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
self.on_mouse_enter = Some(self.add_event("mouseover", move |_: MouseEvent| {
|
||||||
|
handler(0);
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_mouse_release<F>(&mut self, mut handler: F)
|
pub fn on_mouse_release<F>(&mut self, mut handler: F)
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(i32, MouseButton, ModifiersState),
|
F: 'static + FnMut(i32, MouseButton, ModifiersState),
|
||||||
{
|
{
|
||||||
self.on_mouse_release = Some(self.add_user_event(
|
if has_pointer_event() {
|
||||||
"pointerup",
|
self.on_pointer_release = Some(self.add_user_event(
|
||||||
move |event: PointerEvent| {
|
"pointerup",
|
||||||
handler(
|
move |event: PointerEvent| {
|
||||||
event.pointer_id(),
|
handler(
|
||||||
event::mouse_button(&event),
|
event.pointer_id(),
|
||||||
event::mouse_modifiers(&event),
|
event::mouse_button(&event),
|
||||||
);
|
event::mouse_modifiers(&event),
|
||||||
},
|
);
|
||||||
));
|
},
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
self.on_mouse_release =
|
||||||
|
Some(self.add_user_event("mouseup", move |event: MouseEvent| {
|
||||||
|
handler(
|
||||||
|
0,
|
||||||
|
event::mouse_button(&event),
|
||||||
|
event::mouse_modifiers(&event),
|
||||||
|
);
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_mouse_press<F>(&mut self, mut handler: F)
|
pub fn on_mouse_press<F>(&mut self, mut handler: F)
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(i32, MouseButton, ModifiersState),
|
F: 'static + FnMut(i32, MouseButton, ModifiersState),
|
||||||
{
|
{
|
||||||
self.on_mouse_press = Some(self.add_user_event(
|
if has_pointer_event() {
|
||||||
"pointerdown",
|
self.on_pointer_press = Some(self.add_user_event(
|
||||||
move |event: PointerEvent| {
|
"pointerdown",
|
||||||
handler(
|
move |event: PointerEvent| {
|
||||||
event.pointer_id(),
|
handler(
|
||||||
event::mouse_button(&event),
|
event.pointer_id(),
|
||||||
event::mouse_modifiers(&event),
|
event::mouse_button(&event),
|
||||||
);
|
event::mouse_modifiers(&event),
|
||||||
},
|
);
|
||||||
));
|
},
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
self.on_mouse_press =
|
||||||
|
Some(self.add_user_event("mousedown", move |event: MouseEvent| {
|
||||||
|
handler(
|
||||||
|
0,
|
||||||
|
event::mouse_button(&event),
|
||||||
|
event::mouse_modifiers(&event),
|
||||||
|
);
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_cursor_move<F>(&mut self, mut handler: F)
|
pub fn on_cursor_move<F>(&mut self, mut handler: F)
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(i32, PhysicalPosition<f64>, ModifiersState),
|
F: 'static + FnMut(i32, PhysicalPosition<f64>, ModifiersState),
|
||||||
{
|
{
|
||||||
self.on_cursor_move = Some(self.add_event("pointermove", move |event: PointerEvent| {
|
if has_pointer_event() {
|
||||||
handler(
|
self.on_cursor_move =
|
||||||
event.pointer_id(),
|
Some(self.add_event("pointermove", move |event: PointerEvent| {
|
||||||
event::mouse_position(&event).to_physical(super::scale_factor()),
|
handler(
|
||||||
event::mouse_modifiers(&event),
|
event.pointer_id(),
|
||||||
);
|
event::mouse_position(&event).to_physical(super::scale_factor()),
|
||||||
}));
|
event::mouse_modifiers(&event),
|
||||||
|
);
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
self.on_mouse_move = Some(self.add_event("mousemove", move |event: MouseEvent| {
|
||||||
|
handler(
|
||||||
|
0,
|
||||||
|
event::mouse_position(&event).to_physical(super::scale_factor()),
|
||||||
|
event::mouse_modifiers(&event),
|
||||||
|
);
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_mouse_wheel<F>(&mut self, mut handler: F)
|
pub fn on_mouse_wheel<F>(&mut self, mut handler: F)
|
||||||
|
@ -334,3 +392,15 @@ impl Canvas {
|
||||||
super::is_fullscreen(&self.raw)
|
super::is_fullscreen(&self.raw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether pointer events are supported.
|
||||||
|
/// Used to decide whether to use pointer events
|
||||||
|
/// or plain mouse events. Note that Safari
|
||||||
|
/// doesn't support pointer events now.
|
||||||
|
fn has_pointer_event() -> bool {
|
||||||
|
if let Some(window) = web_sys::window() {
|
||||||
|
window.get("PointerEvent").is_some()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue