editor: Fix signature help popover goes off screen (#28566)
Closes #27731 Uses similar logic as other popovers for layouting signature help popover. Release Notes: - Fixed case where signature help popover goes off the screen.
This commit is contained in:
parent
d4736a5427
commit
bd4c9b45b6
2 changed files with 41 additions and 26 deletions
|
@ -18,7 +18,8 @@ use crate::{
|
||||||
},
|
},
|
||||||
git::blame::{BlameRenderer, GitBlame, GlobalBlameRenderer},
|
git::blame::{BlameRenderer, GitBlame, GlobalBlameRenderer},
|
||||||
hover_popover::{
|
hover_popover::{
|
||||||
self, HOVER_POPOVER_GAP, MIN_POPOVER_CHARACTER_WIDTH, MIN_POPOVER_LINE_HEIGHT, hover_at,
|
self, HOVER_POPOVER_GAP, MIN_POPOVER_CHARACTER_WIDTH, MIN_POPOVER_LINE_HEIGHT,
|
||||||
|
POPOVER_RIGHT_OFFSET, hover_at,
|
||||||
},
|
},
|
||||||
inlay_hint_settings,
|
inlay_hint_settings,
|
||||||
items::BufferSearchHighlights,
|
items::BufferSearchHighlights,
|
||||||
|
@ -3958,7 +3959,8 @@ impl EditorElement {
|
||||||
for mut hover_popover in hover_popovers {
|
for mut hover_popover in hover_popovers {
|
||||||
let size = hover_popover.layout_as_root(AvailableSpace::min_size(), window, cx);
|
let size = hover_popover.layout_as_root(AvailableSpace::min_size(), window, cx);
|
||||||
let horizontal_offset =
|
let horizontal_offset =
|
||||||
(text_hitbox.top_right().x - (hovered_point.x + size.width)).min(Pixels::ZERO);
|
(text_hitbox.top_right().x - POPOVER_RIGHT_OFFSET - (hovered_point.x + size.width))
|
||||||
|
.min(Pixels::ZERO);
|
||||||
|
|
||||||
overall_height += HOVER_POPOVER_GAP + size.height;
|
overall_height += HOVER_POPOVER_GAP + size.height;
|
||||||
|
|
||||||
|
@ -4110,6 +4112,7 @@ impl EditorElement {
|
||||||
fn layout_signature_help(
|
fn layout_signature_help(
|
||||||
&self,
|
&self,
|
||||||
hitbox: &Hitbox,
|
hitbox: &Hitbox,
|
||||||
|
text_hitbox: &Hitbox,
|
||||||
content_origin: gpui::Point<Pixels>,
|
content_origin: gpui::Point<Pixels>,
|
||||||
scroll_pixel_position: gpui::Point<Pixels>,
|
scroll_pixel_position: gpui::Point<Pixels>,
|
||||||
newest_selection_head: Option<DisplayPoint>,
|
newest_selection_head: Option<DisplayPoint>,
|
||||||
|
@ -4126,20 +4129,6 @@ impl EditorElement {
|
||||||
let Some(newest_selection_head) = newest_selection_head else {
|
let Some(newest_selection_head) = newest_selection_head else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let selection_row = newest_selection_head.row();
|
|
||||||
if selection_row < start_row {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let Some(cursor_row_layout) = line_layouts.get(selection_row.minus(start_row) as usize)
|
|
||||||
else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let start_x = cursor_row_layout.x_for_index(newest_selection_head.column() as usize)
|
|
||||||
- scroll_pixel_position.x
|
|
||||||
+ content_origin.x;
|
|
||||||
let start_y =
|
|
||||||
selection_row.as_f32() * line_height + content_origin.y - scroll_pixel_position.y;
|
|
||||||
|
|
||||||
let max_size = size(
|
let max_size = size(
|
||||||
(120. * em_width) // Default size
|
(120. * em_width) // Default size
|
||||||
|
@ -4158,18 +4147,42 @@ impl EditorElement {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if let Some(mut element) = maybe_element {
|
let Some(mut element) = maybe_element else {
|
||||||
let window_size = window.viewport_size();
|
return;
|
||||||
let size = element.layout_as_root(Size::<AvailableSpace>::default(), window, cx);
|
};
|
||||||
let mut point = point(start_x, start_y - size.height);
|
|
||||||
|
|
||||||
// Adjusting to ensure the popover does not overflow in the X-axis direction.
|
let selection_row = newest_selection_head.row();
|
||||||
if point.x + size.width >= window_size.width {
|
let Some(cursor_row_layout) = (selection_row >= start_row)
|
||||||
point.x = window_size.width - size.width;
|
.then(|| line_layouts.get(selection_row.minus(start_row) as usize))
|
||||||
}
|
.flatten()
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
window.defer_draw(element, point, 1)
|
let target_x = cursor_row_layout.x_for_index(newest_selection_head.column() as usize)
|
||||||
}
|
- scroll_pixel_position.x;
|
||||||
|
let target_y = selection_row.as_f32() * line_height - scroll_pixel_position.y;
|
||||||
|
let target_point = content_origin + point(target_x, target_y);
|
||||||
|
|
||||||
|
let actual_size = element.layout_as_root(max_size.into(), window, cx);
|
||||||
|
let overall_height = actual_size.height + HOVER_POPOVER_GAP;
|
||||||
|
|
||||||
|
let popover_origin = if target_point.y > overall_height {
|
||||||
|
point(target_point.x, target_point.y - actual_size.height)
|
||||||
|
} else {
|
||||||
|
point(
|
||||||
|
target_point.x,
|
||||||
|
target_point.y + line_height + HOVER_POPOVER_GAP,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let horizontal_offset = (text_hitbox.top_right().x
|
||||||
|
- POPOVER_RIGHT_OFFSET
|
||||||
|
- (popover_origin.x + actual_size.width))
|
||||||
|
.min(Pixels::ZERO);
|
||||||
|
let final_origin = point(popover_origin.x + horizontal_offset, popover_origin.y);
|
||||||
|
|
||||||
|
window.defer_draw(element, final_origin, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_background(&self, layout: &EditorLayout, window: &mut Window, cx: &mut App) {
|
fn paint_background(&self, layout: &EditorLayout, window: &mut Window, cx: &mut App) {
|
||||||
|
@ -7415,6 +7428,7 @@ impl Element for EditorElement {
|
||||||
|
|
||||||
self.layout_signature_help(
|
self.layout_signature_help(
|
||||||
&hitbox,
|
&hitbox,
|
||||||
|
&text_hitbox,
|
||||||
content_origin,
|
content_origin,
|
||||||
scroll_pixel_position,
|
scroll_pixel_position,
|
||||||
newest_selection_head,
|
newest_selection_head,
|
||||||
|
|
|
@ -30,6 +30,7 @@ pub const HOVER_REQUEST_DELAY_MILLIS: u64 = 200;
|
||||||
|
|
||||||
pub const MIN_POPOVER_CHARACTER_WIDTH: f32 = 20.;
|
pub const MIN_POPOVER_CHARACTER_WIDTH: f32 = 20.;
|
||||||
pub const MIN_POPOVER_LINE_HEIGHT: f32 = 4.;
|
pub const MIN_POPOVER_LINE_HEIGHT: f32 = 4.;
|
||||||
|
pub const POPOVER_RIGHT_OFFSET: Pixels = px(8.0);
|
||||||
pub const HOVER_POPOVER_GAP: Pixels = px(10.);
|
pub const HOVER_POPOVER_GAP: Pixels = px(10.);
|
||||||
|
|
||||||
/// Bindable action which uses the most recent selection head to trigger a hover
|
/// Bindable action which uses the most recent selection head to trigger a hover
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue