scrollbar: Update scrollbar hitbox to it bounds, not fill the full of parent view. (#624)

And revert some #621 wrong changes for hover to show scrollbar.
This commit is contained in:
Jason Lee 2025-02-14 13:54:02 +08:00 committed by GitHub
parent c7257d36cf
commit 6e2bb3fb58
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 37 additions and 12 deletions

View file

@ -32,7 +32,7 @@ impl ScrollbarShow {
}
const BORDER_WIDTH: Pixels = px(0.);
const WIDTH: Pixels = px(12.);
pub(crate) const WIDTH: Pixels = px(12.);
const MIN_THUMB_SIZE: f32 = 80.;
const THUMB_RADIUS: Pixels = Pixels(4.0);
const THUMB_INSET: Pixels = Pixels(3.);
@ -123,8 +123,8 @@ impl ScrollbarState {
fn with_hovered(&self, axis: Option<ScrollbarAxis>) -> Self {
let mut state = *self;
state.hovered_axis = axis;
if self.is_scrollbar_visible() {
state.last_scroll_time = Some(Instant::now());
if axis.is_some() {
state.last_scroll_time = Some(std::time::Instant::now());
}
state
}
@ -132,6 +132,9 @@ impl ScrollbarState {
fn with_hovered_on_thumb(&self, axis: Option<ScrollbarAxis>) -> Self {
let mut state = *self;
state.hovered_on_thumb = axis;
if axis.is_some() {
state.last_scroll_time = Some(std::time::Instant::now());
}
state
}
@ -159,7 +162,8 @@ impl ScrollbarState {
}
fn is_scrollbar_visible(&self) -> bool {
if self.hovered_axis.is_some() || self.dragged_axis.is_some() {
// On drag
if self.dragged_axis.is_some() {
return true;
}
@ -629,6 +633,15 @@ impl Element for Scrollbar {
let is_visible = self.state.get().is_scrollbar_visible();
let is_hover_to_show = cx.theme().scrollbar_show.is_hover();
// Update last_scroll_time when offset is changed.
if self.scroll_handle.offset() != self.state.get().last_scroll_offset {
self.state.set(
self.state
.get()
.with_last_scroll(self.scroll_handle.offset(), Some(Instant::now())),
);
}
window.with_content_mask(
Some(ContentMask {
bounds: hitbox_bounds,
@ -754,10 +767,14 @@ impl Element for Scrollbar {
move |event: &MouseMoveEvent, _, _, cx| {
let mut notify = false;
// When is hover to show mode or it was visible,
// we need to update the hovered state and increase the last_scroll_time.
let need_hover_to_update = is_hover_to_show || is_visible;
// Update hovered state for scrollbar
if bounds.contains(&event.position) {
if bounds.contains(&event.position) && need_hover_to_update {
state.set(state.get().with_hovered(Some(axis)));
if state.get().hovered_axis != Some(axis) {
state.set(state.get().with_hovered(Some(axis)));
notify = true;
}
} else {

View file

@ -4,15 +4,16 @@ use crate::{
context_menu::ContextMenuExt,
h_flex,
popup_menu::PopupMenu,
scroll::{ScrollableMask, Scrollbar, ScrollbarState},
scroll::{self, ScrollableMask, Scrollbar, ScrollbarState},
v_flex, ActiveTheme, Icon, IconName, Sizable, Size, StyleSized as _,
};
use gpui::{
actions, canvas, div, prelude::FluentBuilder, px, uniform_list, App, AppContext, Axis, Bounds,
Context, Div, DragMoveEvent, Edges, Empty, EntityId, EventEmitter, FocusHandle, Focusable,
InteractiveElement, IntoElement, KeyBinding, ListSizingBehavior, MouseButton, MouseDownEvent,
ParentElement, Pixels, Point, Render, ScrollHandle, ScrollStrategy, SharedString, Stateful,
StatefulInteractiveElement as _, Styled, Task, UniformListScrollHandle, Window,
ParentElement, Pixels, Point, Render, ScrollHandle, ScrollStrategy, ScrollWheelEvent,
SharedString, Stateful, StatefulInteractiveElement as _, Styled, Task, UniformListScrollHandle,
Window,
};
mod loading;
@ -861,11 +862,15 @@ where
Some(
div()
.occlude()
.absolute()
.top(self.size.table_row_height())
.left_0()
.right_0()
.bottom_0()
.w(scroll::WIDTH)
.on_scroll_wheel(cx.listener(|_, _: &ScrollWheelEvent, _, cx| {
cx.notify();
}))
.child(
Scrollbar::uniform_scroll(
cx.entity().entity_id(),
@ -885,12 +890,15 @@ where
let state = self.horizontal_scrollbar_state.clone();
div()
.occlude()
.absolute()
.top_0()
.left_0()
.right_0()
.bottom_0()
.size_full()
.h(scroll::WIDTH)
.on_scroll_wheel(cx.listener(|_, _: &ScrollWheelEvent, _, cx| {
cx.notify();
}))
.child(Scrollbar::horizontal(
cx.entity().entity_id(),
state,