table: a mouse click on a cell no longer scrolls it - #2865
Conversation
set_selected_cell's ScrollStrategy::Center is right for keyboard and programmatic selection, which can land on an off-screen cell -- but a mouse click can only land on a cell the user can already see, so forcing it to the viewport's centre moved content out from under the pointer for no reason. on_cell_click now selects with scroll: false; every keyboard path still scrolls, since those keep set_selected_cell's default.
huacnlee
left a comment
There was a problem hiding this comment.
Thanks for digging into this. The jump is real, but the cause is different from the description, and that changes the fix.
Center is not applied on every click. In gpui's uniform_list the scroll block sits behind a visibility check:
if scroll_strict || is_above || is_below {
match strategy { Top => …, Center => …, Bottom => …, Nearest => {} }
}and scroll_to_item passes scroll_strict: false. So on a fully visible row, Center already does nothing today. What jumps is a row partly cut off at an edge: is_below is true, and Center pulls it to the middle.
Not scrolling is not right for that case either — you select a row you still cannot see in full. gpui has what you want as ScrollStrategy::Nearest: nothing when the row is visible, minimal reveal when it is not. So this can be one line:
- .scroll_to_item(row_ix, ScrollStrategy::Center);
+ .scroll_to_item(row_ix, ScrollStrategy::Nearest);which also fixes the keyboard — arrow and Page keys go through set_selected_cell too, so stepping one row past the bottom edge recenters the whole table. This PR keeps that.
One question: you mention the first, already-visible row scrolling. Per the code above that should only happen if the table was scrolled and the row was clipped. If it reproduces on a fully visible row, something else is going on and I would rather find it than cover it up.
|
hi @huacnlee |
|
Just to clarify - in my use case, row is fully visible vertically, but some columns may require horizontal scrolling. When you say "row is fully visible" - does that require both horizontal and vertical visibility of the row in order for Center to do nothing ? |
|
On On horizontal: no, the check is purely vertical. So this PR can be one line, and the extra method and - .scroll_to_item(row_ix, ScrollStrategy::Center);
+ .scroll_to_item(row_ix, ScrollStrategy::Nearest);That also fixes the keyboard, which the current version doesn't: arrow and Page keys reach One thing I still want to pin down before merging: does the table in your app declare fixed-left columns ( |
Summary
Table::on_cell_clickselects the clicked cell viaset_selected_cell, which unconditionally callsvertical_scroll_handle.scroll_to_item(row_ix, ScrollStrategy::Center). A mouse click can only land on a cell the user can already see, so forcing it to the centre of the viewport on every click recentres the table under the pointer for no reason. This is most noticeable on a short/medium table, where the clicked row visibly jumps.Keyboard and programmatic selection are unaffected:
set_selected_cell's default behaviour (scroll: true) is unchanged, since either can legitimately land on a cell that's off screen and does need scrolling into view.Change
set_selected_cell's body intoset_selected_cell_with_scroll(row_ix, col_ix, scroll, cx), withset_selected_cellcalling it withscroll: true(unchanged public behaviour).on_cell_clicknow callsset_selected_cell_with_scroll(row_ix, col_ix, false, cx).Test plan
cargo check -p gpui-componentpasses