diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 17b9ea9ced..7579441595 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -5114,19 +5114,21 @@ impl EditorElement { cx, ) }); - let Some((position, hover_popovers)) = hover_popovers else { + let Some((popover_position, hover_popovers)) = hover_popovers else { return; }; // This is safe because we check on layout whether the required row is available - let hovered_row_layout = - &line_layouts[position.row().minus(visible_display_row_range.start) as usize]; + let hovered_row_layout = &line_layouts[popover_position + .row() + .minus(visible_display_row_range.start) + as usize]; // Compute Hovered Point - let x = hovered_row_layout.x_for_index(position.column() as usize) + let x = hovered_row_layout.x_for_index(popover_position.column() as usize) - Pixels::from(scroll_pixel_position.x); let y = Pixels::from( - position.row().as_f64() * ScrollPixelOffset::from(line_height) + popover_position.row().as_f64() * ScrollPixelOffset::from(line_height) - scroll_pixel_position.y, ); let hovered_point = content_origin + point(x, y); diff --git a/crates/editor/src/hover_popover.rs b/crates/editor/src/hover_popover.rs index 6227d90e9b..7446b21b9c 100644 --- a/crates/editor/src/hover_popover.rs +++ b/crates/editor/src/hover_popover.rs @@ -797,9 +797,18 @@ impl HoverState { }) })?; let mut point = anchor.to_display_point(&snapshot.display_snapshot); - // Clamp the point within the visible rows in case the popup source spans multiple lines - if point.row() < visible_rows.start { + if visible_rows.end <= point.row() { + point = crate::movement::up_by_rows( + &snapshot.display_snapshot, + point, + 1 + (point.row() - visible_rows.end).0, + text::SelectionGoal::None, + true, + text_layout_details, + ) + .0; + } else if point.row() < visible_rows.start { point = crate::movement::down_by_rows( &snapshot.display_snapshot, point, @@ -809,16 +818,11 @@ impl HoverState { text_layout_details, ) .0; - } else if visible_rows.end <= point.row() { - point = crate::movement::up_by_rows( - &snapshot.display_snapshot, - point, - (visible_rows.end - point.row()).0, - text::SelectionGoal::None, - true, - text_layout_details, - ) - .0; + } + + if !visible_rows.contains(&point.row()) { + log::error!("Hover popover point out of bounds after moving"); + return None; } let mut elements = Vec::new();