scrollbar: Show scrollbar immediately when scroll offset changed. (#1111)

https://github.com/user-attachments/assets/823f3ac7-4335-4dae-a540-a2ccd11b8fc8
This commit is contained in:
Jason Lee 2025-08-04 17:00:20 +08:00 committed by GitHub
parent 4b85cf6ad2
commit fe8a1e8e9f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 25 additions and 5 deletions

View file

@ -165,8 +165,9 @@ impl VirtualListStory {
.small() .small()
.outline() .outline()
.label("Scroll to Top") .label("Scroll to Top")
.on_click(cx.listener(|this, _, _, _| { .on_click(cx.listener(|this, _, _, cx| {
this.scroll_handle.scroll_to_item(0, ScrollStrategy::Top); this.scroll_handle.scroll_to_item(0, ScrollStrategy::Top);
cx.notify();
})), })),
) )
.child( .child(
@ -174,8 +175,9 @@ impl VirtualListStory {
.small() .small()
.outline() .outline()
.label("Scroll to 50") .label("Scroll to 50")
.on_click(cx.listener(|this, _, _, _| { .on_click(cx.listener(|this, _, _, cx| {
this.scroll_handle.scroll_to_item(50, ScrollStrategy::Top); this.scroll_handle.scroll_to_item(50, ScrollStrategy::Top);
cx.notify();
})), })),
) )
.child( .child(
@ -183,9 +185,10 @@ impl VirtualListStory {
.small() .small()
.outline() .outline()
.label("Scroll to 25 (center)") .label("Scroll to 25 (center)")
.on_click(cx.listener(|this, _, _, _| { .on_click(cx.listener(|this, _, _, cx| {
this.scroll_handle this.scroll_handle
.scroll_to_item(25, ScrollStrategy::Center); .scroll_to_item(25, ScrollStrategy::Center);
cx.notify();
})), })),
) )
.child( .child(
@ -193,8 +196,9 @@ impl VirtualListStory {
.small() .small()
.outline() .outline()
.label("Scroll to Bottom") .label("Scroll to Bottom")
.on_click(cx.listener(|this, _, _, _| { .on_click(cx.listener(|this, _, _, cx| {
this.scroll_handle.scroll_to_bottom(); this.scroll_handle.scroll_to_bottom();
cx.notify();
})), })),
), ),
) )

View file

@ -324,10 +324,11 @@ where
&self.vertical_scroll_handle &self.vertical_scroll_handle
} }
pub fn scroll_to_selected_item(&mut self, _window: &mut Window, _cx: &mut Context<Self>) { pub fn scroll_to_selected_item(&mut self, _window: &mut Window, cx: &mut Context<Self>) {
if let Some(ix) = self.selected_index { if let Some(ix) = self.selected_index {
self.vertical_scroll_handle self.vertical_scroll_handle
.scroll_to_item(ix, ScrollStrategy::Top); .scroll_to_item(ix, ScrollStrategy::Top);
cx.notify();
} }
} }

View file

@ -385,6 +385,17 @@ impl Scrollbar {
) )
} }
fn style_for_normal(cx: &App) -> (Hsla, Hsla, Hsla, Pixels, Pixels, Pixels) {
(
cx.theme().scrollbar_thumb,
cx.theme().scrollbar,
gpui::transparent_black(),
THUMB_WIDTH,
THUMB_INSET,
THUMB_RADIUS,
)
}
fn style_for_idle(cx: &App) -> (Hsla, Hsla, Hsla, Pixels, Pixels, Pixels) { fn style_for_idle(cx: &App) -> (Hsla, Hsla, Hsla, Pixels, Pixels, Pixels) {
let (width, inset, radius) = match cx.theme().scrollbar_show { let (width, inset, radius) = match cx.theme().scrollbar_show {
ScrollbarShow::Scrolling => (THUMB_WIDTH, THUMB_INSET, THUMB_RADIUS), ScrollbarShow::Scrolling => (THUMB_WIDTH, THUMB_INSET, THUMB_RADIUS),
@ -544,6 +555,7 @@ impl Element for Scrollbar {
let is_hover_to_show = cx.theme().scrollbar_show.is_hover(); let is_hover_to_show = cx.theme().scrollbar_show.is_hover();
let is_hovered_on_bar = state.get().hovered_axis == Some(axis); let is_hovered_on_bar = state.get().hovered_axis == Some(axis);
let is_hovered_on_thumb = state.get().hovered_on_thumb == Some(axis); let is_hovered_on_thumb = state.get().hovered_on_thumb == Some(axis);
let is_offset_changed = state.get().last_scroll_offset != self.scroll_handle.offset();
let (thumb_bg, bar_bg, bar_border, thumb_width, inset, radius) = let (thumb_bg, bar_bg, bar_border, thumb_width, inset, radius) =
if state.get().dragged_axis == Some(axis) { if state.get().dragged_axis == Some(axis) {
@ -554,6 +566,8 @@ impl Element for Scrollbar {
} else { } else {
Self::style_for_hovered_bar(cx) Self::style_for_hovered_bar(cx)
} }
} else if is_offset_changed {
Self::style_for_normal(cx)
} else if is_always_to_show { } else if is_always_to_show {
if is_hovered_on_thumb { if is_hovered_on_thumb {
Self::style_for_hovered_thumb(cx) Self::style_for_hovered_thumb(cx)
@ -677,6 +691,7 @@ impl Element for Scrollbar {
.get() .get()
.with_last_scroll(self.scroll_handle.offset(), Some(Instant::now())), .with_last_scroll(self.scroll_handle.offset(), Some(Instant::now())),
); );
cx.notify(view_id);
} }
window.with_content_mask( window.with_content_mask(