Avoid flicker when toggling project browser on workspace open

This commit is contained in:
Antonio Scandurra 2022-04-22 11:45:18 +02:00
parent 9730213ed7
commit 3def7a6803
3 changed files with 57 additions and 40 deletions

View file

@ -566,6 +566,18 @@ impl AsyncAppContext {
self.update(|cx| cx.add_view(window_id, build_view)) self.update(|cx| cx.add_view(window_id, build_view))
} }
pub fn add_window<T, F>(
&mut self,
window_options: WindowOptions,
build_root_view: F,
) -> (usize, ViewHandle<T>)
where
T: View,
F: FnOnce(&mut ViewContext<T>) -> T,
{
self.update(|cx| cx.add_window(window_options, build_root_view))
}
pub fn platform(&self) -> Arc<dyn Platform> { pub fn platform(&self) -> Arc<dyn Platform> {
self.0.borrow().platform() self.0.borrow().platform()
} }

View file

@ -8,7 +8,8 @@ pub struct Sidebar {
side: Side, side: Side,
items: Vec<Item>, items: Vec<Item>,
active_item_ix: Option<usize>, active_item_ix: Option<usize>,
width: Rc<RefCell<f32>>, actual_width: Rc<RefCell<f32>>,
custom_width: Rc<RefCell<f32>>,
} }
#[derive(Clone, Copy, Deserialize)] #[derive(Clone, Copy, Deserialize)]
@ -42,7 +43,8 @@ impl Sidebar {
side, side,
items: Default::default(), items: Default::default(),
active_item_ix: None, active_item_ix: None,
width: Rc::new(RefCell::new(260.)), actual_width: Rc::new(RefCell::new(260.)),
custom_width: Rc::new(RefCell::new(260.)),
} }
} }
@ -137,12 +139,12 @@ impl Sidebar {
container.add_child( container.add_child(
Hook::new( Hook::new(
ConstrainedBox::new(ChildView::new(active_item).boxed()) ConstrainedBox::new(ChildView::new(active_item).boxed())
.with_max_width(*self.width.borrow()) .with_max_width(*self.custom_width.borrow())
.boxed(), .boxed(),
) )
.on_after_layout({ .on_after_layout({
let width = self.width.clone(); let actual_width = self.actual_width.clone();
move |size, _| *width.borrow_mut() = size.x() move |size, _| *actual_width.borrow_mut() = size.x()
}) })
.flex(1., false) .flex(1., false)
.boxed(), .boxed(),
@ -157,7 +159,8 @@ impl Sidebar {
} }
fn render_resize_handle(&self, theme: &Theme, cx: &mut RenderContext<Workspace>) -> ElementBox { fn render_resize_handle(&self, theme: &Theme, cx: &mut RenderContext<Workspace>) -> ElementBox {
let width = self.width.clone(); let actual_width = self.actual_width.clone();
let custom_width = self.custom_width.clone();
let side = self.side; let side = self.side;
MouseEventHandler::new::<Self, _, _>(side as usize, cx, |_, _| { MouseEventHandler::new::<Self, _, _>(side as usize, cx, |_, _| {
Container::new(Empty::new().boxed()) Container::new(Empty::new().boxed())
@ -171,10 +174,10 @@ impl Sidebar {
}) })
.with_cursor_style(CursorStyle::ResizeLeftRight) .with_cursor_style(CursorStyle::ResizeLeftRight)
.on_drag(move |delta, cx| { .on_drag(move |delta, cx| {
let prev_width = *width.borrow(); let prev_width = *actual_width.borrow();
match side { match side {
Side::Left => *width.borrow_mut() = 0f32.max(prev_width + delta.x()), Side::Left => *custom_width.borrow_mut() = 0f32.max(prev_width + delta.x()),
Side::Right => *width.borrow_mut() = 0f32.max(prev_width - delta.x()), Side::Right => *custom_width.borrow_mut() = 0f32.max(prev_width - delta.x()),
} }
cx.notify(); cx.notify();

View file

@ -2141,8 +2141,17 @@ pub fn open_paths(
} }
} }
let is_new_workspace = existing.is_none(); let app_state = app_state.clone();
let workspace = existing.unwrap_or_else(|| { let abs_paths = abs_paths.to_vec();
cx.spawn(|mut cx| async move {
let workspace = if let Some(existing) = existing {
existing
} else {
let contains_directory =
futures::future::join_all(abs_paths.iter().map(|path| app_state.fs.is_file(path)))
.await
.contains(&false);
cx.add_window((app_state.build_window_options)(), |cx| { cx.add_window((app_state.build_window_options)(), |cx| {
let project = Project::local( let project = Project::local(
app_state.client.clone(), app_state.client.clone(),
@ -2151,21 +2160,8 @@ pub fn open_paths(
app_state.fs.clone(), app_state.fs.clone(),
cx, cx,
); );
(app_state.build_workspace)(project, &app_state, cx) let mut workspace = (app_state.build_workspace)(project, &app_state, cx);
}) if contains_directory {
.1
});
let task = workspace.update(cx, |workspace, cx| {
workspace.open_paths(abs_paths.to_vec(), cx)
});
cx.spawn(|mut cx| async move {
let items = task.await;
let opened_dir = items.iter().any(|item| item.is_none());
// Toggle project browser when opening a new workspace that contains a directory.
if is_new_workspace && opened_dir {
workspace.update(&mut cx, |workspace, cx| {
workspace.toggle_sidebar_item( workspace.toggle_sidebar_item(
&ToggleSidebarItem(SidebarItemId { &ToggleSidebarItem(SidebarItemId {
side: Side::Left, side: Side::Left,
@ -2173,9 +2169,15 @@ pub fn open_paths(
}), }),
cx, cx,
); );
cx.focus_self();
});
} }
workspace
})
.1
};
let items = workspace
.update(&mut cx, |workspace, cx| workspace.open_paths(abs_paths, cx))
.await;
(workspace, items) (workspace, items)
}) })
} }