From 100ff89b2a9bc1c60b9bc4a9a8117c911b7e8d82 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Tue, 27 Feb 2024 14:46:09 -0800 Subject: [PATCH] sctk: Map subsurface pointer events to parent surface, with offset --- sctk/src/application.rs | 34 ++++++++++++++++++++++++++++------ sctk/src/sctk_event.rs | 12 ++++++++++-- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/sctk/src/application.rs b/sctk/src/application.rs index ac830d5653..5c9113793d 100644 --- a/sctk/src/application.rs +++ b/sctk/src/application.rs @@ -437,22 +437,30 @@ where variant, .. } => { + let mut offset = (0., 0.); let (state, _native_id) = match surface_ids .get(&variant.surface.id()) .and_then(|id| states.get_mut(&id.inner()).map(|state| (state, id))) { Some(s) => s, - None => continue, + None => { + if let Some((x_offset, y_offset, id)) = subsurface_ids.get(&variant.surface.id()) { + offset = (f64::from(*x_offset), f64::from(*y_offset)); + states.get_mut(&id.inner()).map(|state| (state, id)).unwrap() + } else { + continue + } + }, }; match variant.kind { PointerEventKind::Enter { .. } => { - state.set_cursor_position(Some(LogicalPosition { x: variant.position.0, y: variant.position.1 })); + state.set_cursor_position(Some(LogicalPosition { x: variant.position.0 + offset.0, y: variant.position.1 + offset.1 })); } PointerEventKind::Leave { .. } => { state.set_cursor_position(None); } PointerEventKind::Motion { .. } => { - state.set_cursor_position(Some(LogicalPosition { x: variant.position.0, y: variant.position.1 })); + state.set_cursor_position(Some(LogicalPosition { x: variant.position.0 + offset.0, y: variant.position.1 + offset.1 })); } PointerEventKind::Press { .. } | PointerEventKind::Release { .. } @@ -952,6 +960,7 @@ where &mut mods, &surface_ids, &destroyed_surface_ids, + &subsurface_ids, ) { runtime.broadcast(native_event, Status::Ignored); } @@ -1017,6 +1026,7 @@ where if event_is_for_surface( &sctk_events[i], object_id, + state, has_kbd_focus, ) { filtered_sctk.push(sctk_events.remove(i)); @@ -1034,6 +1044,7 @@ where &mut mods, &surface_ids, &destroyed_surface_ids, + &subsurface_ids, ) }) .collect(); @@ -2217,15 +2228,26 @@ where } // Determine if `SctkEvent` is for surface with given object id. -fn event_is_for_surface( +fn event_is_for_surface<'a, A, C>( evt: &SctkEvent, object_id: &ObjectId, + state: &State, has_kbd_focus: bool, -) -> bool { +) -> bool +where + A: Application + 'static, + ::Theme: StyleSheet, + C: Compositor, +{ match evt { SctkEvent::SeatEvent { id, .. } => &id.id() == object_id, SctkEvent::PointerEvent { variant, .. } => { - &variant.surface.id() == object_id + let event_object_id = variant.surface.id(); + &event_object_id == object_id + || state + .subsurfaces + .iter() + .any(|s| s.wl_surface.id() == event_object_id) } SctkEvent::KeyboardEvent { variant, .. } => match variant { KeyboardEventVariant::Leave(id) => &id.id() == object_id, diff --git a/sctk/src/sctk_event.rs b/sctk/src/sctk_event.rs index f5370e7318..3d9a3c6da3 100755 --- a/sctk/src/sctk_event.rs +++ b/sctk/src/sctk_event.rs @@ -393,6 +393,7 @@ impl SctkEvent { modifiers: &mut Modifiers, surface_ids: &HashMap, destroyed_surface_ids: &HashMap, + subsurface_ids: &HashMap, ) -> Vec { match self { // TODO Ashley: Platform specific multi-seat events? @@ -409,11 +410,18 @@ impl SctkEvent { )] } PointerEventKind::Motion { .. } => { + let offset = if let Some((x_offset, y_offset, _)) = + subsurface_ids.get(&variant.surface.id()) + { + (*x_offset, *y_offset) + } else { + (0, 0) + }; vec![iced_runtime::core::Event::Mouse( mouse::Event::CursorMoved { position: Point::new( - variant.position.0 as f32, - variant.position.1 as f32, + variant.position.0 as f32 + offset.0 as f32, + variant.position.1 as f32 + offset.1 as f32, ), }, )]