Fix project panel scrolling position restoration (#8961)
Project panel loses the last scrolling position every time the user hides/shows it. This PR fixes the problem. The reason of the problem is that `UniformListScrollHandle`, which is intended to store the scrolling position between redrawings, is only used for ad-hoc autoscrollings to the list items, while the `interactivity.scroll_handle` that is responsible for the scrolling position, doesn't survive the project panel hiding. How the problem looks: https://github.com/zed-industries/zed/assets/2101250/7c7e3da6-9a9d-4f28-a181-ee9547349d4c Release Notes: - Fixed scrolling position restoration in the Project Panel.
This commit is contained in:
parent
6bbd09e28e
commit
effc317a06
2 changed files with 8 additions and 5 deletions
|
@ -7,7 +7,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
point, px, size, AnyElement, AvailableSpace, Bounds, ContentMask, Element, ElementContext,
|
point, px, size, AnyElement, AvailableSpace, Bounds, ContentMask, Element, ElementContext,
|
||||||
ElementId, InteractiveElement, InteractiveElementState, Interactivity, IntoElement, LayoutId,
|
ElementId, InteractiveElement, InteractiveElementState, Interactivity, IntoElement, LayoutId,
|
||||||
Pixels, Render, Size, StyleRefinement, Styled, View, ViewContext, WindowContext,
|
Pixels, Render, ScrollHandle, Size, StyleRefinement, Styled, View, ViewContext, WindowContext,
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
|
use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
|
||||||
|
@ -74,6 +74,7 @@ pub struct UniformList {
|
||||||
/// This should be stored in your view and passed to the uniform_list on each frame.
|
/// This should be stored in your view and passed to the uniform_list on each frame.
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct UniformListScrollHandle {
|
pub struct UniformListScrollHandle {
|
||||||
|
base_handle: ScrollHandle,
|
||||||
deferred_scroll_to_item: Rc<RefCell<Option<usize>>>,
|
deferred_scroll_to_item: Rc<RefCell<Option<usize>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +82,7 @@ impl UniformListScrollHandle {
|
||||||
/// Create a new scroll handle to bind to a uniform list.
|
/// Create a new scroll handle to bind to a uniform list.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
base_handle: ScrollHandle::new(),
|
||||||
deferred_scroll_to_item: Rc::new(RefCell::new(None)),
|
deferred_scroll_to_item: Rc::new(RefCell::new(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,6 +301,7 @@ impl UniformList {
|
||||||
|
|
||||||
/// Track and render scroll state of this list with reference to the given scroll handle.
|
/// Track and render scroll state of this list with reference to the given scroll handle.
|
||||||
pub fn track_scroll(mut self, handle: UniformListScrollHandle) -> Self {
|
pub fn track_scroll(mut self, handle: UniformListScrollHandle) -> Self {
|
||||||
|
self.interactivity.scroll_handle = Some(handle.base_handle.clone());
|
||||||
self.scroll_handle = Some(handle);
|
self.scroll_handle = Some(handle);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ const NEW_ENTRY_ID: ProjectEntryId = ProjectEntryId::MAX;
|
||||||
pub struct ProjectPanel {
|
pub struct ProjectPanel {
|
||||||
project: Model<Project>,
|
project: Model<Project>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
list: UniformListScrollHandle,
|
scroll_handle: UniformListScrollHandle,
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
visible_entries: Vec<(WorktreeId, Vec<Entry>)>,
|
visible_entries: Vec<(WorktreeId, Vec<Entry>)>,
|
||||||
last_worktree_root_id: Option<ProjectEntryId>,
|
last_worktree_root_id: Option<ProjectEntryId>,
|
||||||
|
@ -224,7 +224,7 @@ impl ProjectPanel {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
project: project.clone(),
|
project: project.clone(),
|
||||||
fs: workspace.app_state().fs.clone(),
|
fs: workspace.app_state().fs.clone(),
|
||||||
list: UniformListScrollHandle::new(),
|
scroll_handle: UniformListScrollHandle::new(),
|
||||||
focus_handle,
|
focus_handle,
|
||||||
visible_entries: Default::default(),
|
visible_entries: Default::default(),
|
||||||
last_worktree_root_id: Default::default(),
|
last_worktree_root_id: Default::default(),
|
||||||
|
@ -864,7 +864,7 @@ impl ProjectPanel {
|
||||||
|
|
||||||
fn autoscroll(&mut self, cx: &mut ViewContext<Self>) {
|
fn autoscroll(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
if let Some((_, _, index)) = self.selection.and_then(|s| self.index_for_selection(s)) {
|
if let Some((_, _, index)) = self.selection.and_then(|s| self.index_for_selection(s)) {
|
||||||
self.list.scroll_to_item(index);
|
self.scroll_handle.scroll_to_item(index);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1565,7 +1565,7 @@ impl Render for ProjectPanel {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.size_full()
|
.size_full()
|
||||||
.track_scroll(self.list.clone()),
|
.track_scroll(self.scroll_handle.clone()),
|
||||||
)
|
)
|
||||||
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
|
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
|
||||||
overlay()
|
overlay()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue