
This PR reapplies #27402 which was reverted in https://github.com/zed-industries/zed/pull/30544 due to the issue @ConradIrwin reported in https://github.com/zed-industries/zed/pull/27402#issuecomment-2871745132. The reported issue is already present on main but not visible, see https://github.com/zed-industries/zed/pull/27402#issuecomment-2872546903 for more context and reproduction steps. The fix here was to move the padding for the hover popover up to the parent container. This does not fix the underlying problem but serves as workaround without any disadvantages until a better solution is found. I would currently guess that the underlying issue might be related to some rem-size calculations for small font sizes or something similar (e.g. https://github.com/zed-industries/zed/pull/22732 could possibly be somewhat related). Notably, the fix here does not cause any difference in layouting (the following screenshots are actually distinct images), yet fixes the problem at hand. ### Default font size (`15px`) | `main` | This PR | | --- | --- | |  | | ### Smaller font size (`12px`) | `main` | This PR | | --- | --- | |  |  | Furthermore, for the second scenario, the popover would be scrollable on main. As there is no scrollbar in the second image for this PR, this no longer happens with this branch. Release Notes: - N/A
84 lines
2.4 KiB
Rust
84 lines
2.4 KiB
Rust
use std::{
|
|
cell::{Cell, RefCell},
|
|
rc::Rc,
|
|
};
|
|
|
|
use gpui::{Bounds, Point, Size, size};
|
|
use terminal::Terminal;
|
|
use ui::{Pixels, ScrollableHandle, px};
|
|
|
|
#[derive(Debug)]
|
|
struct ScrollHandleState {
|
|
line_height: Pixels,
|
|
total_lines: usize,
|
|
viewport_lines: usize,
|
|
display_offset: usize,
|
|
}
|
|
|
|
impl ScrollHandleState {
|
|
fn new(terminal: &Terminal) -> Self {
|
|
Self {
|
|
line_height: terminal.last_content().terminal_bounds.line_height,
|
|
total_lines: terminal.total_lines(),
|
|
viewport_lines: terminal.viewport_lines(),
|
|
display_offset: terminal.last_content().display_offset,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct TerminalScrollHandle {
|
|
state: Rc<RefCell<ScrollHandleState>>,
|
|
pub future_display_offset: Rc<Cell<Option<usize>>>,
|
|
}
|
|
|
|
impl TerminalScrollHandle {
|
|
pub fn new(terminal: &Terminal) -> Self {
|
|
Self {
|
|
state: Rc::new(RefCell::new(ScrollHandleState::new(terminal))),
|
|
future_display_offset: Rc::new(Cell::new(None)),
|
|
}
|
|
}
|
|
|
|
pub fn update(&self, terminal: &Terminal) {
|
|
*self.state.borrow_mut() = ScrollHandleState::new(terminal);
|
|
}
|
|
}
|
|
|
|
impl ScrollableHandle for TerminalScrollHandle {
|
|
fn content_size(&self) -> Size<Pixels> {
|
|
let state = self.state.borrow();
|
|
size(Pixels::ZERO, state.total_lines as f32 * state.line_height)
|
|
}
|
|
|
|
fn offset(&self) -> Point<Pixels> {
|
|
let state = self.state.borrow();
|
|
let scroll_offset = state.total_lines - state.viewport_lines - state.display_offset;
|
|
Point::new(
|
|
px(0.),
|
|
-px(scroll_offset as f32 * self.state.borrow().line_height.0),
|
|
)
|
|
}
|
|
|
|
fn set_offset(&self, point: Point<Pixels>) {
|
|
let state = self.state.borrow();
|
|
let offset_delta = (point.y.0 / state.line_height.0).round() as i32;
|
|
|
|
let max_offset = state.total_lines - state.viewport_lines;
|
|
let display_offset = (max_offset as i32 + offset_delta).clamp(0, max_offset as i32);
|
|
|
|
self.future_display_offset
|
|
.set(Some(display_offset as usize));
|
|
}
|
|
|
|
fn viewport(&self) -> Bounds<Pixels> {
|
|
let state = self.state.borrow();
|
|
Bounds::new(
|
|
Point::new(px(0.), px(0.)),
|
|
size(
|
|
px(0.),
|
|
px(state.viewport_lines as f32 * state.line_height.0),
|
|
),
|
|
)
|
|
}
|
|
}
|