Fix scrolling in collab panel (#4105)
When the `List` element's state is `ListState::reset()`, it eagerly trashes it's cached element heights in anticipation of a prompt render. But, due to the recent `display_layer` changes, that re-render is not always forthcoming. This is a problem for `ListState::scroll()`, which depends on these cached elements to correctly calculate the new logical scroll offset. Solutions we attempted: - Cache the element heights and continue the scroll calculation - This was conceptually incorrect, reset should only be called when the underlying data has been changed, making any calculation with the old results meaningless. - Lazily re-compute the element heights in scroll - Beyond being a non-trivial refactor, this would probably also cause us to double-render the list in a single frame, which is bad. - Cache the scroll offset and only calculate it in paint - This solution felt awkward to implement and meant we can't supply synchronous list scroll events. - Delay resetting until paint - This means that all of the other APIs that `ListState` supplies would give temporarily incorrect results, worsening the problem Given these issues, we settled on the solution with the least compromises: drop scroll events if the state has been `reset()` between `paint()` and `scroll()`. This shifts the responsibility for the problem out of the List element and into consumers of `List`, if you want perfectly smooth scrolling then you need to use `reset()` judiciously and prefer `splice()`. That said, I tested this by aggressively scrolling the Collab panel, and it seems to work as well as it did before. This PR also includes some initial testing infrastructure for working with input from the platform and rendered elements. Release Notes: - N/A
This commit is contained in:
@@ -1167,7 +1167,7 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
use editor::{DisplayPoint, Editor};
|
||||
use gpui::{Context, EmptyView, Hsla, TestAppContext, VisualTestContext};
|
||||
use gpui::{Context, Hsla, TestAppContext, VisualTestContext};
|
||||
use language::Buffer;
|
||||
use smol::stream::StreamExt as _;
|
||||
use unindent::Unindent as _;
|
||||
@@ -1200,7 +1200,7 @@ mod tests {
|
||||
.unindent(),
|
||||
)
|
||||
});
|
||||
let (_, cx) = cx.add_window_view(|_| EmptyView {});
|
||||
let cx = cx.add_empty_window();
|
||||
let editor = cx.new_view(|cx| Editor::for_buffer(buffer.clone(), None, cx));
|
||||
|
||||
let search_bar = cx.new_view(|cx| {
|
||||
@@ -1547,7 +1547,7 @@ mod tests {
|
||||
"Should pick a query with multiple results"
|
||||
);
|
||||
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), buffer_text));
|
||||
let window = cx.add_window(|_| EmptyView {});
|
||||
let window = cx.add_window(|_| ());
|
||||
|
||||
let editor = window.build_view(cx, |cx| Editor::for_buffer(buffer.clone(), None, cx));
|
||||
|
||||
@@ -1743,7 +1743,7 @@ mod tests {
|
||||
"#
|
||||
.unindent();
|
||||
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), buffer_text));
|
||||
let (_, cx) = cx.add_window_view(|_| EmptyView {});
|
||||
let cx = cx.add_empty_window();
|
||||
|
||||
let editor = cx.new_view(|cx| Editor::for_buffer(buffer.clone(), None, cx));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user