mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 13:51:30 +11:00
Process pointer button events
This commit is contained in:
parent
2ade772ab0
commit
d273518ce9
|
@ -57,6 +57,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
|||
- On Web: fix position of touch events to be relative to the canvas.
|
||||
- On Web, fix `Window:::set_fullscreen` doing nothing when called outside the event loop but during
|
||||
a transient activation.
|
||||
- On Web, fix pointer button events not being processed when a buttons is already pressed.
|
||||
|
||||
# 0.28.6
|
||||
|
||||
|
|
|
@ -249,7 +249,7 @@ impl<T> EventLoopWindowTarget<T> {
|
|||
let modifiers = self.modifiers.clone();
|
||||
let has_focus_clone = has_focus.clone();
|
||||
canvas.on_cursor_move(
|
||||
move |pointer_id, position, delta, active_modifiers| {
|
||||
move |pointer_id, position, delta, active_modifiers, buttons, button| {
|
||||
let modifiers_changed =
|
||||
(has_focus_clone.get() && modifiers.get() != active_modifiers).then(|| {
|
||||
modifiers.set(active_modifiers);
|
||||
|
@ -259,21 +259,48 @@ impl<T> EventLoopWindowTarget<T> {
|
|||
}
|
||||
});
|
||||
|
||||
runner.send_events(modifiers_changed.into_iter().chain([
|
||||
Event::WindowEvent {
|
||||
window_id: RootWindowId(id),
|
||||
event: WindowEvent::CursorMoved {
|
||||
device_id: RootDeviceId(DeviceId(pointer_id)),
|
||||
position,
|
||||
},
|
||||
},
|
||||
Event::DeviceEvent {
|
||||
device_id: RootDeviceId(DeviceId(pointer_id)),
|
||||
event: DeviceEvent::MouseMotion {
|
||||
delta: (delta.x, delta.y),
|
||||
},
|
||||
},
|
||||
]));
|
||||
let button_event = button.map(|button| {
|
||||
if buttons.contains(button.into()) {
|
||||
Event::WindowEvent {
|
||||
window_id: RootWindowId(id),
|
||||
event: WindowEvent::MouseInput {
|
||||
device_id: RootDeviceId(DeviceId(pointer_id)),
|
||||
state: ElementState::Pressed,
|
||||
button,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
Event::WindowEvent {
|
||||
window_id: RootWindowId(id),
|
||||
event: WindowEvent::MouseInput {
|
||||
device_id: RootDeviceId(DeviceId(pointer_id)),
|
||||
state: ElementState::Released,
|
||||
button,
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
runner.send_events(
|
||||
modifiers_changed
|
||||
.into_iter()
|
||||
.chain([
|
||||
Event::WindowEvent {
|
||||
window_id: RootWindowId(id),
|
||||
event: WindowEvent::CursorMoved {
|
||||
device_id: RootDeviceId(DeviceId(pointer_id)),
|
||||
position,
|
||||
},
|
||||
},
|
||||
Event::DeviceEvent {
|
||||
device_id: RootDeviceId(DeviceId(pointer_id)),
|
||||
event: DeviceEvent::MouseMotion {
|
||||
delta: (delta.x, delta.y),
|
||||
},
|
||||
},
|
||||
])
|
||||
.chain(button_event),
|
||||
);
|
||||
},
|
||||
move |device_id, location, force| {
|
||||
runner_touch.send_event(Event::WindowEvent {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::event;
|
||||
use super::event_handle::EventListenerHandle;
|
||||
use super::media_query_handle::MediaQueryListHandle;
|
||||
use super::{event, ButtonsState};
|
||||
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
||||
use crate::error::OsError as RootOE;
|
||||
use crate::event::{Force, MouseButton, MouseScrollDelta};
|
||||
|
@ -273,7 +273,15 @@ impl Canvas {
|
|||
touch_handler: T,
|
||||
prevent_default: bool,
|
||||
) where
|
||||
M: 'static + FnMut(i32, PhysicalPosition<f64>, PhysicalPosition<f64>, ModifiersState),
|
||||
M: 'static
|
||||
+ FnMut(
|
||||
i32,
|
||||
PhysicalPosition<f64>,
|
||||
PhysicalPosition<f64>,
|
||||
ModifiersState,
|
||||
ButtonsState,
|
||||
Option<MouseButton>,
|
||||
),
|
||||
T: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
|
||||
{
|
||||
match &mut self.mouse_state {
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::keyboard::ModifiersState;
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use event::ButtonsState;
|
||||
use web_sys::{EventTarget, MouseEvent};
|
||||
|
||||
type MouseLeaveHandler = Rc<RefCell<Option<Box<dyn FnMut(i32, ModifiersState)>>>>;
|
||||
|
@ -108,8 +109,11 @@ impl MouseHandler {
|
|||
MouseCaptureState::Captured => {}
|
||||
}
|
||||
event.stop_propagation();
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
handler(0, event::mouse_button(&event), modifiers);
|
||||
handler(
|
||||
0,
|
||||
event::mouse_button(&event).expect("no mouse button released"),
|
||||
event::mouse_modifiers(&event),
|
||||
);
|
||||
if event
|
||||
.target()
|
||||
.map_or(false, |target| target != EventTarget::from(canvas))
|
||||
|
@ -158,12 +162,11 @@ impl MouseHandler {
|
|||
}
|
||||
*mouse_capture_state = MouseCaptureState::Captured;
|
||||
event.stop_propagation();
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
handler(
|
||||
0,
|
||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||
event::mouse_button(&event),
|
||||
modifiers,
|
||||
event::mouse_button(&event).expect("no mouse button pressed"),
|
||||
event::mouse_modifiers(&event),
|
||||
);
|
||||
},
|
||||
));
|
||||
|
@ -171,7 +174,15 @@ impl MouseHandler {
|
|||
|
||||
pub fn on_cursor_move<F>(&mut self, canvas_common: &super::Common, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(i32, PhysicalPosition<f64>, PhysicalPosition<f64>, ModifiersState),
|
||||
F: 'static
|
||||
+ FnMut(
|
||||
i32,
|
||||
PhysicalPosition<f64>,
|
||||
PhysicalPosition<f64>,
|
||||
ModifiersState,
|
||||
ButtonsState,
|
||||
Option<MouseButton>,
|
||||
),
|
||||
{
|
||||
let mouse_capture_state = self.mouse_capture_state.clone();
|
||||
let canvas = canvas_common.raw.clone();
|
||||
|
@ -202,12 +213,13 @@ impl MouseHandler {
|
|||
event::mouse_position_by_client(&event, &canvas)
|
||||
};
|
||||
let mouse_delta = event::mouse_delta(&event);
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
handler(
|
||||
0,
|
||||
mouse_pos.to_physical(super::super::scale_factor()),
|
||||
mouse_delta.to_physical(super::super::scale_factor()),
|
||||
modifiers,
|
||||
event::mouse_modifiers(&event),
|
||||
event::mouse_buttons(&event),
|
||||
event::mouse_button(&event),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::dpi::PhysicalPosition;
|
|||
use crate::event::{Force, MouseButton};
|
||||
use crate::keyboard::ModifiersState;
|
||||
|
||||
use event::ButtonsState;
|
||||
use web_sys::PointerEvent;
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -42,8 +43,7 @@ impl PointerHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
handler(event.pointer_id(), modifiers);
|
||||
handler(event.pointer_id(), event::mouse_modifiers(&event));
|
||||
},
|
||||
));
|
||||
}
|
||||
|
@ -62,8 +62,7 @@ impl PointerHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
handler(event.pointer_id(), modifiers);
|
||||
handler(event.pointer_id(), event::mouse_modifiers(&event));
|
||||
},
|
||||
));
|
||||
}
|
||||
|
@ -89,8 +88,11 @@ impl PointerHandler {
|
|||
Force::Normalized(event.pressure() as f64),
|
||||
);
|
||||
} else {
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
mouse_handler(event.pointer_id(), event::mouse_button(&event), modifiers);
|
||||
mouse_handler(
|
||||
event.pointer_id(),
|
||||
event::mouse_button(&event).expect("no mouse button released"),
|
||||
event::mouse_modifiers(&event),
|
||||
);
|
||||
}
|
||||
},
|
||||
));
|
||||
|
@ -117,12 +119,11 @@ impl PointerHandler {
|
|||
Force::Normalized(event.pressure() as f64),
|
||||
);
|
||||
} else {
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
mouse_handler(
|
||||
event.pointer_id(),
|
||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||
event::mouse_button(&event),
|
||||
modifiers,
|
||||
event::mouse_button(&event).expect("no mouse button pressed"),
|
||||
event::mouse_modifiers(&event),
|
||||
);
|
||||
|
||||
// Error is swallowed here since the error would occur every time the mouse is
|
||||
|
@ -141,7 +142,15 @@ impl PointerHandler {
|
|||
mut touch_handler: T,
|
||||
prevent_default: bool,
|
||||
) where
|
||||
M: 'static + FnMut(i32, PhysicalPosition<f64>, PhysicalPosition<f64>, ModifiersState),
|
||||
M: 'static
|
||||
+ FnMut(
|
||||
i32,
|
||||
PhysicalPosition<f64>,
|
||||
PhysicalPosition<f64>,
|
||||
ModifiersState,
|
||||
ButtonsState,
|
||||
Option<MouseButton>,
|
||||
),
|
||||
T: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
|
||||
{
|
||||
let canvas = canvas_common.raw.clone();
|
||||
|
@ -160,12 +169,13 @@ impl PointerHandler {
|
|||
Force::Normalized(event.pressure() as f64),
|
||||
);
|
||||
} else {
|
||||
let modifiers = event::mouse_modifiers(&event);
|
||||
mouse_handler(
|
||||
event.pointer_id(),
|
||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||
event::mouse_delta(&event).to_physical(super::super::scale_factor()),
|
||||
modifiers,
|
||||
event::mouse_modifiers(&event),
|
||||
event::mouse_buttons(&event),
|
||||
event::mouse_button(&event),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -6,12 +6,50 @@ use smol_str::SmolStr;
|
|||
use std::convert::TryInto;
|
||||
use web_sys::{HtmlCanvasElement, KeyboardEvent, MouseEvent, PointerEvent, WheelEvent};
|
||||
|
||||
pub fn mouse_button(event: &MouseEvent) -> MouseButton {
|
||||
bitflags! {
|
||||
pub struct ButtonsState: u16 {
|
||||
const LEFT = 0b001;
|
||||
const RIGHT = 0b010;
|
||||
const MIDDLE = 0b100;
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ButtonsState> for MouseButton {
|
||||
fn from(value: ButtonsState) -> Self {
|
||||
match value {
|
||||
ButtonsState::LEFT => MouseButton::Left,
|
||||
ButtonsState::RIGHT => MouseButton::Right,
|
||||
ButtonsState::MIDDLE => MouseButton::Middle,
|
||||
_ => MouseButton::Other(value.bits()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MouseButton> for ButtonsState {
|
||||
fn from(value: MouseButton) -> Self {
|
||||
match value {
|
||||
MouseButton::Left => ButtonsState::LEFT,
|
||||
MouseButton::Right => ButtonsState::RIGHT,
|
||||
MouseButton::Middle => ButtonsState::MIDDLE,
|
||||
MouseButton::Other(value) => unsafe { ButtonsState::from_bits_unchecked(value) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mouse_buttons(event: &MouseEvent) -> ButtonsState {
|
||||
unsafe { ButtonsState::from_bits_unchecked(event.buttons()) }
|
||||
}
|
||||
|
||||
pub fn mouse_button(event: &MouseEvent) -> Option<MouseButton> {
|
||||
match event.button() {
|
||||
0 => MouseButton::Left,
|
||||
1 => MouseButton::Middle,
|
||||
2 => MouseButton::Right,
|
||||
i => MouseButton::Other((i - 3).try_into().expect("very large mouse button value")),
|
||||
-1 => None,
|
||||
0 => Some(MouseButton::Left),
|
||||
1 => Some(MouseButton::Middle),
|
||||
2 => Some(MouseButton::Right),
|
||||
i => Some(MouseButton::Other(
|
||||
i.try_into()
|
||||
.expect("unexpected negative mouse button value"),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ mod scaling;
|
|||
mod timeout;
|
||||
|
||||
pub use self::canvas::Canvas;
|
||||
pub use self::event::ButtonsState;
|
||||
pub use self::scaling::ScaleChangeDetector;
|
||||
pub use self::timeout::{AnimationFrameRequest, Timeout};
|
||||
|
||||
|
|
Loading…
Reference in a new issue