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

View file

@ -324,10 +324,11 @@ where
&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 {
self.vertical_scroll_handle
.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) {
let (width, inset, radius) = match cx.theme().scrollbar_show {
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_hovered_on_bar = state.get().hovered_axis == 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) =
if state.get().dragged_axis == Some(axis) {
@ -554,6 +566,8 @@ impl Element for Scrollbar {
} else {
Self::style_for_hovered_bar(cx)
}
} else if is_offset_changed {
Self::style_for_normal(cx)
} else if is_always_to_show {
if is_hovered_on_thumb {
Self::style_for_hovered_thumb(cx)
@ -677,6 +691,7 @@ impl Element for Scrollbar {
.get()
.with_last_scroll(self.scroll_handle.offset(), Some(Instant::now())),
);
cx.notify(view_id);
}
window.with_content_mask(