ui: Fix scrollbar content size calculation for non-uniform lists with single element (#20237)

Piotr Osiewicz created

Previously we were always adding the origin coordinate of last item to
the content size, which is incorrect when the list has just one item; in
that case, we should just use the size of that item as the content size
of a list.

Closes #ISSUE

Release Notes:

- N/A

Change summary

crates/editor/src/hover_popover.rs    | 8 ++++++--
crates/ui/src/components/scrollbar.rs | 8 +++++---
2 files changed, 11 insertions(+), 5 deletions(-)

Detailed changes

crates/editor/src/hover_popover.rs 🔗

@@ -615,7 +615,7 @@ impl HoverState {
         !self.info_popovers.is_empty() || self.diagnostic_popover.is_some()
     }
 
-    pub fn render(
+    pub(crate) fn render(
         &mut self,
         snapshot: &EditorSnapshot,
         visible_rows: Range<DisplayRow>,
@@ -694,7 +694,11 @@ pub(crate) struct InfoPopover {
 }
 
 impl InfoPopover {
-    pub fn render(&mut self, max_size: Size<Pixels>, cx: &mut ViewContext<Editor>) -> AnyElement {
+    pub(crate) fn render(
+        &mut self,
+        max_size: Size<Pixels>,
+        cx: &mut ViewContext<Editor>,
+    ) -> AnyElement {
         let keyboard_grace = Rc::clone(&self.keyboard_grace);
         let mut d = div()
             .id("info_popover")

crates/ui/src/components/scrollbar.rs 🔗

@@ -37,13 +37,14 @@ impl ScrollableHandle {
             }),
             ScrollableHandle::NonUniform(handle) => {
                 let last_children_index = handle.children_count().checked_sub(1)?;
-                // todo: PO: this is slightly wrong for horizontal scrollbar, as the last item is not necessarily the longest one.
+
                 let mut last_item = handle.bounds_for_item(last_children_index)?;
-                last_item.size.height += last_item.origin.y;
-                last_item.size.width += last_item.origin.x;
                 let mut scroll_adjustment = None;
                 if last_children_index != 0 {
+                    // todo: PO: this is slightly wrong for horizontal scrollbar, as the last item is not necessarily the longest one.
                     let first_item = handle.bounds_for_item(0)?;
+                    last_item.size.height += last_item.origin.y;
+                    last_item.size.width += last_item.origin.x;
 
                     scroll_adjustment = Some(first_item.origin);
                     last_item.size.height -= first_item.origin.y;
@@ -140,6 +141,7 @@ impl ScrollbarState {
         }) {
             current_offset -= adjustment;
         }
+
         let mut percentage = current_offset / main_dimension_size;
         let viewport_size = self.scroll_handle.viewport().size;
         let end_offset = (current_offset + viewport_size.along(axis).0) / main_dimension_size;