Add window entity to TouchInput events (#11128)

# Objective

If you have multiple windows, there is no way to determine which window
a `TouchInput` event applies to. This fixes that.

## Solution

- Add the window entity directly to `TouchInput`, just like the other
input events.
- Fixes #6011.

## Migration Guide

+ Add a `window` field when constructing or destructuring a `TouchInput`
struct.
This commit is contained in:
Miles Silberling-Cook 2024-01-01 21:03:05 -06:00 committed by GitHub
parent d8d8bcfb21
commit 4034740396
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 1 deletions

View File

@ -1,5 +1,6 @@
//! The touch input functionality. //! The touch input functionality.
use bevy_ecs::entity::Entity;
use bevy_ecs::event::{Event, EventReader}; use bevy_ecs::event::{Event, EventReader};
use bevy_ecs::system::{ResMut, Resource}; use bevy_ecs::system::{ResMut, Resource};
use bevy_math::Vec2; use bevy_math::Vec2;
@ -44,6 +45,8 @@ pub struct TouchInput {
pub phase: TouchPhase, pub phase: TouchPhase,
/// The position of the finger on the touchscreen. /// The position of the finger on the touchscreen.
pub position: Vec2, pub position: Vec2,
/// The window entity registering the touch.
pub window: Entity,
/// Describes how hard the screen was pressed. /// Describes how hard the screen was pressed.
/// ///
/// May be [`None`] if the platform does not support pressure sensitivity. /// May be [`None`] if the platform does not support pressure sensitivity.
@ -408,6 +411,7 @@ mod test {
#[test] #[test]
fn touch_process() { fn touch_process() {
use crate::{touch::TouchPhase, TouchInput, Touches}; use crate::{touch::TouchPhase, TouchInput, Touches};
use bevy_ecs::entity::Entity;
use bevy_math::Vec2; use bevy_math::Vec2;
let mut touches = Touches::default(); let mut touches = Touches::default();
@ -417,6 +421,7 @@ mod test {
let touch_event = TouchInput { let touch_event = TouchInput {
phase: TouchPhase::Started, phase: TouchPhase::Started,
position: Vec2::splat(4.0), position: Vec2::splat(4.0),
window: Entity::PLACEHOLDER,
force: None, force: None,
id: 4, id: 4,
}; };
@ -432,6 +437,7 @@ mod test {
let moved_touch_event = TouchInput { let moved_touch_event = TouchInput {
phase: TouchPhase::Moved, phase: TouchPhase::Moved,
position: Vec2::splat(5.0), position: Vec2::splat(5.0),
window: Entity::PLACEHOLDER,
force: None, force: None,
id: touch_event.id, id: touch_event.id,
}; };
@ -453,6 +459,7 @@ mod test {
let cancel_touch_event = TouchInput { let cancel_touch_event = TouchInput {
phase: TouchPhase::Canceled, phase: TouchPhase::Canceled,
position: Vec2::ONE, position: Vec2::ONE,
window: Entity::PLACEHOLDER,
force: None, force: None,
id: touch_event.id, id: touch_event.id,
}; };
@ -468,6 +475,7 @@ mod test {
let end_touch_event = TouchInput { let end_touch_event = TouchInput {
phase: TouchPhase::Ended, phase: TouchPhase::Ended,
position: Vec2::splat(4.0), position: Vec2::splat(4.0),
window: Entity::PLACEHOLDER,
force: None, force: None,
id: touch_event.id, id: touch_event.id,
}; };
@ -487,6 +495,7 @@ mod test {
#[test] #[test]
fn touch_pressed() { fn touch_pressed() {
use crate::{touch::TouchPhase, TouchInput, Touches}; use crate::{touch::TouchPhase, TouchInput, Touches};
use bevy_ecs::entity::Entity;
use bevy_math::Vec2; use bevy_math::Vec2;
let mut touches = Touches::default(); let mut touches = Touches::default();
@ -494,6 +503,7 @@ mod test {
let touch_event = TouchInput { let touch_event = TouchInput {
phase: TouchPhase::Started, phase: TouchPhase::Started,
position: Vec2::splat(4.0), position: Vec2::splat(4.0),
window: Entity::PLACEHOLDER,
force: None, force: None,
id: 4, id: 4,
}; };
@ -509,6 +519,7 @@ mod test {
#[test] #[test]
fn touch_released() { fn touch_released() {
use crate::{touch::TouchPhase, TouchInput, Touches}; use crate::{touch::TouchPhase, TouchInput, Touches};
use bevy_ecs::entity::Entity;
use bevy_math::Vec2; use bevy_math::Vec2;
let mut touches = Touches::default(); let mut touches = Touches::default();
@ -516,6 +527,7 @@ mod test {
let touch_event = TouchInput { let touch_event = TouchInput {
phase: TouchPhase::Ended, phase: TouchPhase::Ended,
position: Vec2::splat(4.0), position: Vec2::splat(4.0),
window: Entity::PLACEHOLDER,
force: None, force: None,
id: 4, id: 4,
}; };
@ -531,6 +543,7 @@ mod test {
#[test] #[test]
fn touch_canceled() { fn touch_canceled() {
use crate::{touch::TouchPhase, TouchInput, Touches}; use crate::{touch::TouchPhase, TouchInput, Touches};
use bevy_ecs::entity::Entity;
use bevy_math::Vec2; use bevy_math::Vec2;
let mut touches = Touches::default(); let mut touches = Touches::default();
@ -538,6 +551,7 @@ mod test {
let touch_event = TouchInput { let touch_event = TouchInput {
phase: TouchPhase::Canceled, phase: TouchPhase::Canceled,
position: Vec2::splat(4.0), position: Vec2::splat(4.0),
window: Entity::PLACEHOLDER,
force: None, force: None,
id: 4, id: 4,
}; };

View File

@ -40,6 +40,7 @@ pub fn convert_mouse_button(mouse_button: winit::event::MouseButton) -> MouseBut
pub fn convert_touch_input( pub fn convert_touch_input(
touch_input: winit::event::Touch, touch_input: winit::event::Touch,
location: winit::dpi::LogicalPosition<f64>, location: winit::dpi::LogicalPosition<f64>,
window_entity: Entity,
) -> TouchInput { ) -> TouchInput {
TouchInput { TouchInput {
phase: match touch_input.phase { phase: match touch_input.phase {
@ -49,6 +50,7 @@ pub fn convert_touch_input(
winit::event::TouchPhase::Cancelled => TouchPhase::Canceled, winit::event::TouchPhase::Cancelled => TouchPhase::Canceled,
}, },
position: Vec2::new(location.x as f32, location.y as f32), position: Vec2::new(location.x as f32, location.y as f32),
window: window_entity,
force: touch_input.force.map(|f| match f { force: touch_input.force.map(|f| match f {
winit::event::Force::Calibrated { winit::event::Force::Calibrated {
force, force,

View File

@ -515,7 +515,11 @@ pub fn winit_runner(mut app: App) {
.to_logical(window.resolution.scale_factor() as f64); .to_logical(window.resolution.scale_factor() as f64);
event_writers event_writers
.touch_input .touch_input
.send(converters::convert_touch_input(touch, location)); .send(converters::convert_touch_input(
touch,
location,
window_entity,
));
} }
WindowEvent::ScaleFactorChanged { WindowEvent::ScaleFactorChanged {
scale_factor, scale_factor,