mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-26 03:36:32 +11:00
Process pointer button events
This commit is contained in:
parent
2ade772ab0
commit
d273518ce9
7 changed files with 140 additions and 43 deletions
|
@ -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 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
|
- On Web, fix `Window:::set_fullscreen` doing nothing when called outside the event loop but during
|
||||||
a transient activation.
|
a transient activation.
|
||||||
|
- On Web, fix pointer button events not being processed when a buttons is already pressed.
|
||||||
|
|
||||||
# 0.28.6
|
# 0.28.6
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ impl<T> EventLoopWindowTarget<T> {
|
||||||
let modifiers = self.modifiers.clone();
|
let modifiers = self.modifiers.clone();
|
||||||
let has_focus_clone = has_focus.clone();
|
let has_focus_clone = has_focus.clone();
|
||||||
canvas.on_cursor_move(
|
canvas.on_cursor_move(
|
||||||
move |pointer_id, position, delta, active_modifiers| {
|
move |pointer_id, position, delta, active_modifiers, buttons, button| {
|
||||||
let modifiers_changed =
|
let modifiers_changed =
|
||||||
(has_focus_clone.get() && modifiers.get() != active_modifiers).then(|| {
|
(has_focus_clone.get() && modifiers.get() != active_modifiers).then(|| {
|
||||||
modifiers.set(active_modifiers);
|
modifiers.set(active_modifiers);
|
||||||
|
@ -259,7 +259,32 @@ impl<T> EventLoopWindowTarget<T> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
runner.send_events(modifiers_changed.into_iter().chain([
|
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 {
|
Event::WindowEvent {
|
||||||
window_id: RootWindowId(id),
|
window_id: RootWindowId(id),
|
||||||
event: WindowEvent::CursorMoved {
|
event: WindowEvent::CursorMoved {
|
||||||
|
@ -273,7 +298,9 @@ impl<T> EventLoopWindowTarget<T> {
|
||||||
delta: (delta.x, delta.y),
|
delta: (delta.x, delta.y),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]));
|
])
|
||||||
|
.chain(button_event),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
move |device_id, location, force| {
|
move |device_id, location, force| {
|
||||||
runner_touch.send_event(Event::WindowEvent {
|
runner_touch.send_event(Event::WindowEvent {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::event;
|
|
||||||
use super::event_handle::EventListenerHandle;
|
use super::event_handle::EventListenerHandle;
|
||||||
use super::media_query_handle::MediaQueryListHandle;
|
use super::media_query_handle::MediaQueryListHandle;
|
||||||
|
use super::{event, ButtonsState};
|
||||||
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
||||||
use crate::error::OsError as RootOE;
|
use crate::error::OsError as RootOE;
|
||||||
use crate::event::{Force, MouseButton, MouseScrollDelta};
|
use crate::event::{Force, MouseButton, MouseScrollDelta};
|
||||||
|
@ -273,7 +273,15 @@ impl Canvas {
|
||||||
touch_handler: T,
|
touch_handler: T,
|
||||||
prevent_default: bool,
|
prevent_default: bool,
|
||||||
) where
|
) 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),
|
T: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
|
||||||
{
|
{
|
||||||
match &mut self.mouse_state {
|
match &mut self.mouse_state {
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::keyboard::ModifiersState;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use event::ButtonsState;
|
||||||
use web_sys::{EventTarget, MouseEvent};
|
use web_sys::{EventTarget, MouseEvent};
|
||||||
|
|
||||||
type MouseLeaveHandler = Rc<RefCell<Option<Box<dyn FnMut(i32, ModifiersState)>>>>;
|
type MouseLeaveHandler = Rc<RefCell<Option<Box<dyn FnMut(i32, ModifiersState)>>>>;
|
||||||
|
@ -108,8 +109,11 @@ impl MouseHandler {
|
||||||
MouseCaptureState::Captured => {}
|
MouseCaptureState::Captured => {}
|
||||||
}
|
}
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
let modifiers = event::mouse_modifiers(&event);
|
handler(
|
||||||
handler(0, event::mouse_button(&event), modifiers);
|
0,
|
||||||
|
event::mouse_button(&event).expect("no mouse button released"),
|
||||||
|
event::mouse_modifiers(&event),
|
||||||
|
);
|
||||||
if event
|
if event
|
||||||
.target()
|
.target()
|
||||||
.map_or(false, |target| target != EventTarget::from(canvas))
|
.map_or(false, |target| target != EventTarget::from(canvas))
|
||||||
|
@ -158,12 +162,11 @@ impl MouseHandler {
|
||||||
}
|
}
|
||||||
*mouse_capture_state = MouseCaptureState::Captured;
|
*mouse_capture_state = MouseCaptureState::Captured;
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
let modifiers = event::mouse_modifiers(&event);
|
|
||||||
handler(
|
handler(
|
||||||
0,
|
0,
|
||||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||||
event::mouse_button(&event),
|
event::mouse_button(&event).expect("no mouse button pressed"),
|
||||||
modifiers,
|
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)
|
pub fn on_cursor_move<F>(&mut self, canvas_common: &super::Common, mut handler: F)
|
||||||
where
|
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 mouse_capture_state = self.mouse_capture_state.clone();
|
||||||
let canvas = canvas_common.raw.clone();
|
let canvas = canvas_common.raw.clone();
|
||||||
|
@ -202,12 +213,13 @@ impl MouseHandler {
|
||||||
event::mouse_position_by_client(&event, &canvas)
|
event::mouse_position_by_client(&event, &canvas)
|
||||||
};
|
};
|
||||||
let mouse_delta = event::mouse_delta(&event);
|
let mouse_delta = event::mouse_delta(&event);
|
||||||
let modifiers = event::mouse_modifiers(&event);
|
|
||||||
handler(
|
handler(
|
||||||
0,
|
0,
|
||||||
mouse_pos.to_physical(super::super::scale_factor()),
|
mouse_pos.to_physical(super::super::scale_factor()),
|
||||||
mouse_delta.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::event::{Force, MouseButton};
|
||||||
use crate::keyboard::ModifiersState;
|
use crate::keyboard::ModifiersState;
|
||||||
|
|
||||||
|
use event::ButtonsState;
|
||||||
use web_sys::PointerEvent;
|
use web_sys::PointerEvent;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -42,8 +43,7 @@ impl PointerHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let modifiers = event::mouse_modifiers(&event);
|
handler(event.pointer_id(), event::mouse_modifiers(&event));
|
||||||
handler(event.pointer_id(), modifiers);
|
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,7 @@ impl PointerHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let modifiers = event::mouse_modifiers(&event);
|
handler(event.pointer_id(), event::mouse_modifiers(&event));
|
||||||
handler(event.pointer_id(), modifiers);
|
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -89,8 +88,11 @@ impl PointerHandler {
|
||||||
Force::Normalized(event.pressure() as f64),
|
Force::Normalized(event.pressure() as f64),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let modifiers = event::mouse_modifiers(&event);
|
mouse_handler(
|
||||||
mouse_handler(event.pointer_id(), event::mouse_button(&event), modifiers);
|
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),
|
Force::Normalized(event.pressure() as f64),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let modifiers = event::mouse_modifiers(&event);
|
|
||||||
mouse_handler(
|
mouse_handler(
|
||||||
event.pointer_id(),
|
event.pointer_id(),
|
||||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||||
event::mouse_button(&event),
|
event::mouse_button(&event).expect("no mouse button pressed"),
|
||||||
modifiers,
|
event::mouse_modifiers(&event),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Error is swallowed here since the error would occur every time the mouse is
|
// Error is swallowed here since the error would occur every time the mouse is
|
||||||
|
@ -141,7 +142,15 @@ impl PointerHandler {
|
||||||
mut touch_handler: T,
|
mut touch_handler: T,
|
||||||
prevent_default: bool,
|
prevent_default: bool,
|
||||||
) where
|
) 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),
|
T: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
|
||||||
{
|
{
|
||||||
let canvas = canvas_common.raw.clone();
|
let canvas = canvas_common.raw.clone();
|
||||||
|
@ -160,12 +169,13 @@ impl PointerHandler {
|
||||||
Force::Normalized(event.pressure() as f64),
|
Force::Normalized(event.pressure() as f64),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let modifiers = event::mouse_modifiers(&event);
|
|
||||||
mouse_handler(
|
mouse_handler(
|
||||||
event.pointer_id(),
|
event.pointer_id(),
|
||||||
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
event::mouse_position(&event).to_physical(super::super::scale_factor()),
|
||||||
event::mouse_delta(&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 std::convert::TryInto;
|
||||||
use web_sys::{HtmlCanvasElement, KeyboardEvent, MouseEvent, PointerEvent, WheelEvent};
|
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() {
|
match event.button() {
|
||||||
0 => MouseButton::Left,
|
-1 => None,
|
||||||
1 => MouseButton::Middle,
|
0 => Some(MouseButton::Left),
|
||||||
2 => MouseButton::Right,
|
1 => Some(MouseButton::Middle),
|
||||||
i => MouseButton::Other((i - 3).try_into().expect("very large mouse button value")),
|
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;
|
mod timeout;
|
||||||
|
|
||||||
pub use self::canvas::Canvas;
|
pub use self::canvas::Canvas;
|
||||||
|
pub use self::event::ButtonsState;
|
||||||
pub use self::scaling::ScaleChangeDetector;
|
pub use self::scaling::ScaleChangeDetector;
|
||||||
pub use self::timeout::{AnimationFrameRequest, Timeout};
|
pub use self::timeout::{AnimationFrameRequest, Timeout};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue