Skip to content

Commit

Permalink
Split modifier handling in all pointer events
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Jun 4, 2023
1 parent 3b25b2b commit 967abbb
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 119 deletions.
191 changes: 111 additions & 80 deletions src/platform_impl/web/event_loop/window_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,51 +198,65 @@ impl<T> EventLoopWindowTarget<T> {
prevent_default,
);

let runner = self.runner.clone();
let modifiers = self.modifiers.clone();
let has_focus_clone = has_focus.clone();
canvas.on_cursor_leave(move |pointer_id, active_modifiers| {
let modifiers_changed = (has_focus_clone.get() && modifiers.get() != active_modifiers)
.then(|| {
modifiers.set(active_modifiers);
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::ModifiersChanged(active_modifiers.into()),
}
});
canvas.on_cursor_leave(
{
let runner = self.runner.clone();
let has_focus = has_focus.clone();
let modifiers = self.modifiers.clone();

runner.send_events(modifiers_changed.into_iter().chain(iter::once(
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::CursorLeft {
device_id: RootDeviceId(DeviceId(pointer_id)),
},
},
)));
});
move |active_modifiers| {
if has_focus.get() && modifiers.get() != active_modifiers {
modifiers.set(active_modifiers);
runner.send_event(Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::ModifiersChanged(active_modifiers.into()),
});
}
}
},
{
let runner = self.runner.clone();

let runner = self.runner.clone();
let modifiers = self.modifiers.clone();
let has_focus_clone = has_focus.clone();
canvas.on_cursor_enter(move |pointer_id, active_modifiers| {
let modifiers_changed = (has_focus_clone.get() && modifiers.get() != active_modifiers)
.then(|| {
modifiers.set(active_modifiers);
Event::WindowEvent {
move |pointer_id| {
runner.send_event(Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::ModifiersChanged(active_modifiers.into()),
event: WindowEvent::CursorLeft {
device_id: RootDeviceId(DeviceId(pointer_id)),
},
});
}
},
);

canvas.on_cursor_enter(
{
let runner = self.runner.clone();
let has_focus = has_focus.clone();
let modifiers = self.modifiers.clone();

move |active_modifiers| {
if has_focus.get() && modifiers.get() != active_modifiers {
modifiers.set(active_modifiers);
runner.send_event(Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::ModifiersChanged(active_modifiers.into()),
});
}
});
}
},
{
let runner = self.runner.clone();

runner.send_events(modifiers_changed.into_iter().chain(iter::once(
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::CursorEntered {
device_id: RootDeviceId(DeviceId(pointer_id)),
},
},
)));
});
move |pointer_id| {
runner.send_event(Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::CursorEntered {
device_id: RootDeviceId(DeviceId(pointer_id)),
},
});
}
},
);

canvas.on_cursor_move(
{
Expand Down Expand Up @@ -351,7 +365,7 @@ impl<T> EventLoopWindowTarget<T> {
let modifiers = self.modifiers.clone();
let has_focus = has_focus.clone();

move |pointer_id, position, button, active_modifiers| {
move |active_modifiers| {
let focus_changed = (!has_focus.replace(true)).then_some(Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::Focused(true),
Expand All @@ -365,26 +379,36 @@ impl<T> EventLoopWindowTarget<T> {
}
});

runner.send_events(focus_changed.into_iter().chain(modifiers_changed))
}
},
{
let runner = self.runner.clone();

move |pointer_id, position, button| {
// A mouse down event may come in without any prior CursorMoved events,
// therefore we should send a CursorMoved event to make sure that the
// user code has the correct cursor position.
runner.send_events(focus_changed.into_iter().chain(modifiers_changed).chain([
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::CursorMoved {
device_id: RootDeviceId(DeviceId(pointer_id)),
position,
runner.send_events(
[
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::CursorMoved {
device_id: RootDeviceId(DeviceId(pointer_id)),
position,
},
},
},
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::MouseInput {
device_id: RootDeviceId(DeviceId(pointer_id)),
state: ElementState::Pressed,
button,
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::MouseInput {
device_id: RootDeviceId(DeviceId(pointer_id)),
state: ElementState::Pressed,
button,
},
},
},
]));
]
.into_iter(),
);
}
},
{
Expand Down Expand Up @@ -417,39 +441,46 @@ impl<T> EventLoopWindowTarget<T> {
canvas.on_mouse_release(
{
let runner = self.runner.clone();
let modifiers = self.modifiers.clone();
let has_focus = has_focus.clone();
let modifiers = self.modifiers.clone();

move |pointer_id, position, button, active_modifiers| {
let modifiers_changed =
(has_focus.get() && modifiers.get() != active_modifiers).then(|| {
modifiers.set(active_modifiers);
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::ModifiersChanged(active_modifiers.into()),
}
move |active_modifiers| {
if has_focus.get() && modifiers.get() != active_modifiers {
modifiers.set(active_modifiers);
runner.send_event(Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::ModifiersChanged(active_modifiers.into()),
});
}
}
},
{
let runner = self.runner.clone();

move |pointer_id, position, button| {
// A mouse up event may come in without any prior CursorMoved events,
// therefore we should send a CursorMoved event to make sure that the
// user code has the correct cursor position.
runner.send_events(modifiers_changed.into_iter().chain([
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::CursorMoved {
device_id: RootDeviceId(DeviceId(pointer_id)),
position,
runner.send_events(
[
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::CursorMoved {
device_id: RootDeviceId(DeviceId(pointer_id)),
position,
},
},
},
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::MouseInput {
device_id: RootDeviceId(DeviceId(pointer_id)),
state: ElementState::Released,
button,
Event::WindowEvent {
window_id: RootWindowId(id),
event: WindowEvent::MouseInput {
device_id: RootDeviceId(DeviceId(pointer_id)),
state: ElementState::Released,
button,
},
},
},
]));
]
.into_iter(),
);
}
},
{
Expand Down
42 changes: 29 additions & 13 deletions src/platform_impl/web/web_sys/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,40 +212,56 @@ impl Canvas {
));
}

pub fn on_cursor_leave<F>(&mut self, handler: F)
pub fn on_cursor_leave<MOD, M>(&mut self, modifier_handler: MOD, mouse_handler: M)
where
F: 'static + FnMut(i32, ModifiersState),
MOD: 'static + FnMut(ModifiersState),
M: 'static + FnMut(i32),
{
self.pointer_handler.on_cursor_leave(&self.common, handler)
self.pointer_handler
.on_cursor_leave(&self.common, modifier_handler, mouse_handler)
}

pub fn on_cursor_enter<F>(&mut self, handler: F)
pub fn on_cursor_enter<MOD, M>(&mut self, modifier_handler: MOD, mouse_handler: M)
where
F: 'static + FnMut(i32, ModifiersState),
MOD: 'static + FnMut(ModifiersState),
M: 'static + FnMut(i32),
{
self.pointer_handler.on_cursor_enter(&self.common, handler)
self.pointer_handler
.on_cursor_enter(&self.common, modifier_handler, mouse_handler)
}

pub fn on_mouse_release<M, T>(&mut self, mouse_handler: M, touch_handler: T)
where
M: 'static + FnMut(i32, PhysicalPosition<f64>, MouseButton, ModifiersState),
pub fn on_mouse_release<MOD, M, T>(
&mut self,
modifier_handler: MOD,
mouse_handler: M,
touch_handler: T,
) where
MOD: 'static + FnMut(ModifiersState),
M: 'static + FnMut(i32, PhysicalPosition<f64>, MouseButton),
T: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
{
self.pointer_handler
.on_mouse_release(&self.common, mouse_handler, touch_handler)
self.pointer_handler.on_mouse_release(
&self.common,
modifier_handler,
mouse_handler,
touch_handler,
)
}

pub fn on_mouse_press<M, T>(
pub fn on_mouse_press<MOD, M, T>(
&mut self,
modifier_handler: MOD,
mouse_handler: M,
touch_handler: T,
prevent_default: bool,
) where
M: 'static + FnMut(i32, PhysicalPosition<f64>, MouseButton, ModifiersState),
MOD: 'static + FnMut(ModifiersState),
M: 'static + FnMut(i32, PhysicalPosition<f64>, MouseButton),
T: 'static + FnMut(i32, PhysicalPosition<f64>, Force),
{
self.pointer_handler.on_mouse_press(
&self.common,
modifier_handler,
mouse_handler,
touch_handler,
prevent_default,
Expand Down
Loading

0 comments on commit 967abbb

Please sign in to comment.