fix(applet): improve cursor handling

This commit is contained in:
Ashley Wulber 2025-10-22 13:10:34 -04:00
parent 7cae9aa47d
commit 853f9d73a8
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
2 changed files with 45 additions and 7 deletions

View file

@ -336,7 +336,17 @@ where
) && cursor.is_over(c_layout.bounds()) ) && cursor.is_over(c_layout.bounds())
{ {
my_state.hovered = Some(i); 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; cursor_virtual = mouse::Cursor::Unavailable;
} }
@ -344,7 +354,7 @@ where
state, state,
event.clone(), event.clone(),
c_layout.with_virtual_offset(layout.virtual_offset()), c_layout.with_virtual_offset(layout.virtual_offset()),
cursor, cursor_virtual,
renderer, renderer,
clipboard, clipboard,
shell, shell,
@ -390,18 +400,21 @@ where
viewport: &Rectangle, viewport: &Rectangle,
) { ) {
if let Some(clipped_viewport) = layout.bounds().intersection(viewport) { if let Some(clipped_viewport) = layout.bounds().intersection(viewport) {
let my_state = tree.state.downcast_ref::<State>();
let viewport = if self.clip { let viewport = if self.clip {
&clipped_viewport &clipped_viewport
} else { } else {
viewport viewport
}; };
for ((child, state), c_layout) in self for (i, ((child, state), c_layout)) in self
.children .children
.iter() .iter()
.zip(&tree.children) .zip(&tree.children)
.zip(layout.children()) .zip(layout.children())
.filter(|(_, layout)| layout.bounds().intersects(viewport)) .filter(|(_, layout)| layout.bounds().intersects(viewport))
.enumerate()
{ {
child.as_widget().draw( child.as_widget().draw(
state, state,
@ -409,7 +422,11 @@ where
theme, theme,
style, style,
c_layout.with_virtual_offset(layout.virtual_offset()), 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, viewport,
); );
} }

View file

@ -314,6 +314,8 @@ where
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.map(|(((i, child), state), c_layout)| { .map(|(((i, child), state), c_layout)| {
let mut cursor_virtual = cursor;
if matches!( if matches!(
event, event,
Event::Mouse(mouse::Event::CursorMoved { .. } | mouse::Event::CursorEntered) Event::Mouse(mouse::Event::CursorMoved { .. } | mouse::Event::CursorEntered)
@ -324,13 +326,25 @@ where
) && cursor.is_over(c_layout.bounds()) ) && cursor.is_over(c_layout.bounds())
{ {
my_state.hovered = Some(i); 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( child.as_widget_mut().on_event(
state, state,
event.clone(), event.clone(),
c_layout.with_virtual_offset(layout.virtual_offset()), c_layout.with_virtual_offset(layout.virtual_offset()),
cursor, cursor_virtual,
renderer, renderer,
clipboard, clipboard,
shell, shell,
@ -376,18 +390,21 @@ where
viewport: &Rectangle, viewport: &Rectangle,
) { ) {
if let Some(clipped_viewport) = layout.bounds().intersection(viewport) { if let Some(clipped_viewport) = layout.bounds().intersection(viewport) {
let my_state = tree.state.downcast_ref::<State>();
let viewport = if self.clip { let viewport = if self.clip {
&clipped_viewport &clipped_viewport
} else { } else {
viewport viewport
}; };
for ((child, state), c_layout) in self for (i, ((child, state), c_layout)) in self
.children .children
.iter() .iter()
.zip(&tree.children) .zip(&tree.children)
.zip(layout.children()) .zip(layout.children())
.filter(|(_, layout)| layout.bounds().intersects(viewport)) .filter(|(_, layout)| layout.bounds().intersects(viewport))
.enumerate()
{ {
child.as_widget().draw( child.as_widget().draw(
state, state,
@ -395,7 +412,11 @@ where
theme, theme,
style, style,
c_layout.with_virtual_offset(layout.virtual_offset()), 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, viewport,
); );
} }