mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
On Web, handle coalesced events
This commit is contained in:
parent
31ebc5caf4
commit
4f3eacf01e
|
@ -59,6 +59,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
||||||
a transient activation.
|
a transient activation.
|
||||||
- On Web, fix pointer button events not being processed when a buttons is already pressed.
|
- On Web, fix pointer button events not being processed when a buttons is already pressed.
|
||||||
- **Breaking:** Updated `bitflags` crate version to `2`, which changes the API on exposed types.
|
- **Breaking:** Updated `bitflags` crate version to `2`, which changes the API on exposed types.
|
||||||
|
- On Web, handle coalesced pointer events, which increases the resolution of pointer inputs.
|
||||||
|
|
||||||
# 0.28.6
|
# 0.28.6
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ use crate::event::{Force, MouseButton};
|
||||||
use crate::keyboard::ModifiersState;
|
use crate::keyboard::ModifiersState;
|
||||||
|
|
||||||
use event::ButtonsState;
|
use event::ButtonsState;
|
||||||
|
use wasm_bindgen::prelude::wasm_bindgen;
|
||||||
|
use wasm_bindgen::{JsCast, JsValue};
|
||||||
use web_sys::PointerEvent;
|
use web_sys::PointerEvent;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -157,26 +159,76 @@ impl PointerHandler {
|
||||||
self.on_cursor_move = Some(canvas_common.add_event(
|
self.on_cursor_move = Some(canvas_common.add_event(
|
||||||
"pointermove",
|
"pointermove",
|
||||||
move |event: PointerEvent| {
|
move |event: PointerEvent| {
|
||||||
if event.pointer_type() == "touch" {
|
// coalesced events are not available on Safari
|
||||||
if prevent_default {
|
#[wasm_bindgen]
|
||||||
// prevent scroll on mobile web
|
extern "C" {
|
||||||
event.prevent_default();
|
#[wasm_bindgen(extends = PointerEvent)]
|
||||||
}
|
type PointerEventExt;
|
||||||
touch_handler(
|
|
||||||
event.pointer_id(),
|
#[wasm_bindgen(method, getter, js_name = getCoalescedEvents)]
|
||||||
event::touch_position(&event, &canvas)
|
fn has_get_coalesced_events(this: &PointerEventExt) -> JsValue;
|
||||||
.to_physical(super::super::scale_factor()),
|
}
|
||||||
Force::Normalized(event.pressure() as f64),
|
|
||||||
);
|
if event.pointer_type() == "touch" && prevent_default {
|
||||||
} else {
|
// prevent scroll on mobile web
|
||||||
mouse_handler(
|
event.prevent_default();
|
||||||
event.pointer_id(),
|
}
|
||||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
|
||||||
event::mouse_delta(&event).to_physical(super::super::scale_factor()),
|
let event: PointerEventExt = event.unchecked_into();
|
||||||
|
|
||||||
|
let id = event.pointer_id();
|
||||||
|
// cache buttons if the pointer is a mouse
|
||||||
|
let mouse = (event.pointer_type() != "touch").then(|| {
|
||||||
|
(
|
||||||
event::mouse_modifiers(&event),
|
event::mouse_modifiers(&event),
|
||||||
event::mouse_buttons(&event),
|
event::mouse_buttons(&event),
|
||||||
event::mouse_button(&event),
|
event::mouse_button(&event),
|
||||||
);
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// store coalesced events to extend it's lifetime
|
||||||
|
let events = (!event.has_get_coalesced_events().is_undefined())
|
||||||
|
.then(|| event.get_coalesced_events())
|
||||||
|
// if coalesced events is empty, it's a chorded button event
|
||||||
|
.filter(|events| events.length() != 0);
|
||||||
|
|
||||||
|
// make a single iterator depending on the availability of coalesced events
|
||||||
|
let events = if let Some(events) = &events {
|
||||||
|
None.into_iter().chain(
|
||||||
|
Some(events.iter().map(PointerEventExt::unchecked_from_js))
|
||||||
|
.into_iter()
|
||||||
|
.flatten(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Some(event).into_iter().chain(None.into_iter().flatten())
|
||||||
|
};
|
||||||
|
|
||||||
|
for event in events {
|
||||||
|
// coalesced events should always have the same source as the root event
|
||||||
|
debug_assert_eq!(id, event.pointer_id());
|
||||||
|
debug_assert_eq!(mouse.is_none(), event.pointer_type() == "touch");
|
||||||
|
|
||||||
|
if let Some((modifiers, buttons, button)) = mouse {
|
||||||
|
// coalesced events should have the same buttons
|
||||||
|
debug_assert_eq!(modifiers, event::mouse_modifiers(&event));
|
||||||
|
debug_assert_eq!(buttons, event::mouse_buttons(&event));
|
||||||
|
|
||||||
|
mouse_handler(
|
||||||
|
id,
|
||||||
|
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||||
|
event::mouse_delta(&event).to_physical(super::super::scale_factor()),
|
||||||
|
modifiers,
|
||||||
|
buttons,
|
||||||
|
button,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
touch_handler(
|
||||||
|
id,
|
||||||
|
event::touch_position(&event, &canvas)
|
||||||
|
.to_physical(super::super::scale_factor()),
|
||||||
|
Force::Normalized(event.pressure() as f64),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::convert::TryInto;
|
||||||
use web_sys::{HtmlCanvasElement, KeyboardEvent, MouseEvent, PointerEvent, WheelEvent};
|
use web_sys::{HtmlCanvasElement, KeyboardEvent, MouseEvent, PointerEvent, WheelEvent};
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct ButtonsState: u16 {
|
pub struct ButtonsState: u16 {
|
||||||
const LEFT = 0b001;
|
const LEFT = 0b001;
|
||||||
const RIGHT = 0b010;
|
const RIGHT = 0b010;
|
||||||
|
|
Loading…
Reference in a new issue