From 3def7a6803aecf266b225c7f6a0cf1eb6c2ef06f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Apr 2022 11:45:18 +0200 Subject: [PATCH] Avoid flicker when toggling project browser on workspace open --- crates/gpui/src/app.rs | 12 ++++++ crates/workspace/src/sidebar.rs | 21 +++++----- crates/workspace/src/workspace.rs | 66 ++++++++++++++++--------------- 3 files changed, 58 insertions(+), 41 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 91497c178f1638c4f330a2a83f0c117c1818f245..99c92b74128783c620deb10c22bb795b6fc8de7c 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -566,6 +566,18 @@ impl AsyncAppContext { self.update(|cx| cx.add_view(window_id, build_view)) } + pub fn add_window( + &mut self, + window_options: WindowOptions, + build_root_view: F, + ) -> (usize, ViewHandle) + where + T: View, + F: FnOnce(&mut ViewContext) -> T, + { + self.update(|cx| cx.add_window(window_options, build_root_view)) + } + pub fn platform(&self) -> Arc { self.0.borrow().platform() } diff --git a/crates/workspace/src/sidebar.rs b/crates/workspace/src/sidebar.rs index cd5ec3220127609805bae9b285d39ee8a20d9339..46ec3089e7219fe2ca8c1eb6ae0288fb3642036c 100644 --- a/crates/workspace/src/sidebar.rs +++ b/crates/workspace/src/sidebar.rs @@ -8,7 +8,8 @@ pub struct Sidebar { side: Side, items: Vec, active_item_ix: Option, - width: Rc>, + actual_width: Rc>, + custom_width: Rc>, } #[derive(Clone, Copy, Deserialize)] @@ -42,7 +43,8 @@ impl Sidebar { side, items: Default::default(), 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( Hook::new( ConstrainedBox::new(ChildView::new(active_item).boxed()) - .with_max_width(*self.width.borrow()) + .with_max_width(*self.custom_width.borrow()) .boxed(), ) .on_after_layout({ - let width = self.width.clone(); - move |size, _| *width.borrow_mut() = size.x() + let actual_width = self.actual_width.clone(); + move |size, _| *actual_width.borrow_mut() = size.x() }) .flex(1., false) .boxed(), @@ -157,7 +159,8 @@ impl Sidebar { } fn render_resize_handle(&self, theme: &Theme, cx: &mut RenderContext) -> ElementBox { - let width = self.width.clone(); + let actual_width = self.actual_width.clone(); + let custom_width = self.custom_width.clone(); let side = self.side; MouseEventHandler::new::(side as usize, cx, |_, _| { Container::new(Empty::new().boxed()) @@ -171,10 +174,10 @@ impl Sidebar { }) .with_cursor_style(CursorStyle::ResizeLeftRight) .on_drag(move |delta, cx| { - let prev_width = *width.borrow(); + let prev_width = *actual_width.borrow(); match side { - Side::Left => *width.borrow_mut() = 0f32.max(prev_width + delta.x()), - Side::Right => *width.borrow_mut() = 0f32.max(prev_width - delta.x()), + Side::Left => *custom_width.borrow_mut() = 0f32.max(prev_width + delta.x()), + Side::Right => *custom_width.borrow_mut() = 0f32.max(prev_width - delta.x()), } cx.notify(); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index efb9527533539ccc25dfc3f8a7edfd3bb0b48241..e8048e0953048e0b0de4c7969278aef50c279cc6 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -2141,41 +2141,43 @@ pub fn open_paths( } } - let is_new_workspace = existing.is_none(); - let workspace = existing.unwrap_or_else(|| { - cx.add_window((app_state.build_window_options)(), |cx| { - let project = Project::local( - app_state.client.clone(), - app_state.user_store.clone(), - app_state.languages.clone(), - app_state.fs.clone(), - cx, - ); - (app_state.build_workspace)(project, &app_state, cx) - }) - .1 - }); - - let task = workspace.update(cx, |workspace, cx| { - workspace.open_paths(abs_paths.to_vec(), cx) - }); + let app_state = app_state.clone(); + let abs_paths = abs_paths.to_vec(); 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( - &ToggleSidebarItem(SidebarItemId { - side: Side::Left, - item_index: 0, - }), + 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| { + let project = Project::local( + app_state.client.clone(), + app_state.user_store.clone(), + app_state.languages.clone(), + app_state.fs.clone(), cx, ); - cx.focus_self(); - }); - } + let mut workspace = (app_state.build_workspace)(project, &app_state, cx); + if contains_directory { + workspace.toggle_sidebar_item( + &ToggleSidebarItem(SidebarItemId { + side: Side::Left, + item_index: 0, + }), + cx, + ); + } + workspace + }) + .1 + }; + + let items = workspace + .update(&mut cx, |workspace, cx| workspace.open_paths(abs_paths, cx)) + .await; (workspace, items) }) }