From 853f9d73a8fdadf82e6a1407d179ce9baae86267 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 22 Oct 2025 13:10:34 -0400 Subject: [PATCH] fix(applet): improve cursor handling --- src/applet/column.rs | 25 +++++++++++++++++++++---- src/applet/row.rs | 27 ++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/applet/column.rs b/src/applet/column.rs index 16362d39..8fa2fa9f 100644 --- a/src/applet/column.rs +++ b/src/applet/column.rs @@ -336,7 +336,17 @@ where ) && cursor.is_over(c_layout.bounds()) { my_state.hovered = Some(i); - } else if my_state.hovered.is_some_and(|h| i == h) { + return child.as_widget_mut().on_event( + state, + event.clone(), + c_layout.with_virtual_offset(layout.virtual_offset()), + cursor_virtual, + renderer, + clipboard, + shell, + viewport, + ); + } else if my_state.hovered.is_some_and(|h| i != h) { cursor_virtual = mouse::Cursor::Unavailable; } @@ -344,7 +354,7 @@ where state, event.clone(), c_layout.with_virtual_offset(layout.virtual_offset()), - cursor, + cursor_virtual, renderer, clipboard, shell, @@ -390,18 +400,21 @@ where viewport: &Rectangle, ) { if let Some(clipped_viewport) = layout.bounds().intersection(viewport) { + let my_state = tree.state.downcast_ref::(); + let viewport = if self.clip { &clipped_viewport } else { viewport }; - for ((child, state), c_layout) in self + for (i, ((child, state), c_layout)) in self .children .iter() .zip(&tree.children) .zip(layout.children()) .filter(|(_, layout)| layout.bounds().intersects(viewport)) + .enumerate() { child.as_widget().draw( state, @@ -409,7 +422,11 @@ where theme, style, c_layout.with_virtual_offset(layout.virtual_offset()), - cursor, + if my_state.hovered.is_some_and(|h| i == h) { + cursor + } else { + mouse::Cursor::Unavailable + }, viewport, ); } diff --git a/src/applet/row.rs b/src/applet/row.rs index 3a98e6f1..b5cf851f 100644 --- a/src/applet/row.rs +++ b/src/applet/row.rs @@ -314,6 +314,8 @@ where .zip(&mut tree.children) .zip(layout.children()) .map(|(((i, child), state), c_layout)| { + let mut cursor_virtual = cursor; + if matches!( event, Event::Mouse(mouse::Event::CursorMoved { .. } | mouse::Event::CursorEntered) @@ -324,13 +326,25 @@ where ) && cursor.is_over(c_layout.bounds()) { my_state.hovered = Some(i); + return child.as_widget_mut().on_event( + state, + event.clone(), + c_layout.with_virtual_offset(layout.virtual_offset()), + cursor_virtual, + renderer, + clipboard, + shell, + viewport, + ); + } else if my_state.hovered.is_some_and(|h| i != h) { + cursor_virtual = mouse::Cursor::Unavailable; } child.as_widget_mut().on_event( state, event.clone(), c_layout.with_virtual_offset(layout.virtual_offset()), - cursor, + cursor_virtual, renderer, clipboard, shell, @@ -376,18 +390,21 @@ where viewport: &Rectangle, ) { if let Some(clipped_viewport) = layout.bounds().intersection(viewport) { + let my_state = tree.state.downcast_ref::(); + let viewport = if self.clip { &clipped_viewport } else { viewport }; - for ((child, state), c_layout) in self + for (i, ((child, state), c_layout)) in self .children .iter() .zip(&tree.children) .zip(layout.children()) .filter(|(_, layout)| layout.bounds().intersects(viewport)) + .enumerate() { child.as_widget().draw( state, @@ -395,7 +412,11 @@ where theme, style, c_layout.with_virtual_offset(layout.virtual_offset()), - cursor, + if my_state.hovered.is_some_and(|h| i == h) { + cursor + } else { + mouse::Cursor::Unavailable + }, viewport, ); }