fix(web): clear hover under dropdown overlays

This commit is contained in:
Kayshen-X 2026-06-19 06:21:10 +08:00
parent b4c7e08048
commit b9f0856b79
2 changed files with 63 additions and 2 deletions

View file

@ -130,8 +130,8 @@ impl WidgetHost {
let over_dropdown =
self.over_dropdown_overlay(x, y, self.last_viewport_w, self.last_viewport_h);
let dropdown_changed = self.update_dropdown_hover(x, y);
let layer_cleared = over_dropdown && self.clear_layer_panel_hover();
if dropdown_changed || layer_cleared || over_dropdown {
let underlay_cleared = over_dropdown && self.clear_hover_under_dropdown_overlay();
if dropdown_changed || underlay_cleared || over_dropdown {
return true;
}
if self.editor_state.editor_ui.variables_panel_open {
@ -155,6 +155,40 @@ impl WidgetHost {
false
}
fn clear_hover_under_dropdown_overlay(&mut self) -> bool {
let mut changed = false;
{
let ui = &mut self.editor_state.editor_ui;
changed |= ui.canvas_hover_node.take().is_some();
changed |= ui.hovered_layer_id.take().is_some();
changed |= ui.hovered_page_index.take().is_some();
changed |= ui.fill_type_picker.hover.take().is_some();
changed |= ui.toolbar_hover.take().is_some();
changed |= ui.align_toolbar_hover.take().is_some();
changed |= ui.statusbar_hover.take().is_some();
changed |= ui.topbar_button_hover.take().is_some();
changed |= ui.chat_model_picker.hover.take().is_some();
changed |= ui.chat_design_block_hover.take().is_some();
changed |= ui.chat_footer_hover.take().is_some();
changed |= ui.chat_example_hover.take().is_some();
changed |= ui.export_picker_hover.take().is_some();
changed |= ui.property_action_hover.take().is_some();
changed |= ui.property_tab_hover.take().is_some();
if let Some(menu) = ui.layer_context_menu.as_mut() {
changed |= menu.menu.hover.take().is_some();
}
}
if let Some(menu) = self.editor_state.ui.path_anchor_menu.as_mut() {
changed |= menu.menu.hover.take().is_some();
}
changed |= self.editor_state.codegen.framework_hover.take().is_some();
changed |= self.editor_state.codegen.action_hover.take().is_some();
if changed {
self.mark_dirty();
}
changed
}
/// Update the file-menu / locale / shape-picker dropdown hover highlights
/// from the cursor. At most one is open at a time; a top-most
/// floating panel covering the point suppresses updates. Returns

View file

@ -80,6 +80,33 @@ fn property_panel_blank_hover_consumes_and_clears_lower_hover() {
assert_eq!(host.editor_state.editor_ui.canvas_hover_node, None);
}
#[test]
fn locale_dropdown_hover_clears_property_panel_hover_underlay() {
let mut host = WidgetHost::new();
host.editor_state = EditorState::sample();
host.mark_dirty();
host.last_viewport_w = 1200.0;
host.last_viewport_h = 800.0;
host.editor_state.editor_ui.property_action_hover = Some(0);
host.editor_state.editor_ui.locale_picker.open = true;
let picker = host.locale_picker_rect(host.last_viewport_w);
let point = Point2D::new(
picker.origin.x + picker.size.x / 2.0,
picker.origin.y + op_editor_ui::widgets::LocalePicker::row_height() * 1.5,
);
assert!(host.apply_cursor_move(point.x, point.y));
assert_eq!(
host.editor_state.editor_ui.property_action_hover, None,
"top-bar dropdowns are visually above the inspector and must clear stale inspector hover"
);
assert!(
host.editor_state.editor_ui.locale_picker.hover.is_some(),
"the dropdown row hover itself should still update"
);
}
#[test]
fn codegen_hover_tracks_idle_generate_button() {
let mut host = WidgetHost::new();