Reduce amount of workspace serialization happening (#22730)
Part of https://github.com/zed-industries/zed/issues/16472 Reduces amount of workspace serialization happening by: * fixing the deserialization logic: now it does not set panels that are hidden to active * cleaning up `active_panel_index` for docks that are closed, to avoid emitting extra events for such closed docks * adjusting outline panel to drop active editor subscriptions on deactivation — this way, `cx.observe` on the dock with outline panel is not triggered (used to be triggered on every selection change before) * adjusting workspace dock drag listener to remember previous coordinates and only resize the dock if those had changed * adjusting workspace pane event listener to ignore `pane::Event::UserSavedItem` and `pane::Event::ChangeItemTitle` that seem to happen relatively frequently but not influence values that are serialized for the workspace * not using `cx.observe` on docks, instead explicitly serializing on panel zoom and size changes Release Notes: - Reduced amount of workspace serialization happening
This commit is contained in:
parent
4c47728d6f
commit
a827f54022
3 changed files with 101 additions and 66 deletions
|
@ -4656,18 +4656,27 @@ impl Panel for OutlinePanel {
|
||||||
.update(&mut cx, |outline_panel, cx| {
|
.update(&mut cx, |outline_panel, cx| {
|
||||||
let old_active = outline_panel.active;
|
let old_active = outline_panel.active;
|
||||||
outline_panel.active = active;
|
outline_panel.active = active;
|
||||||
if active && old_active != active {
|
if old_active != active {
|
||||||
if let Some((active_item, active_editor)) = outline_panel
|
if active {
|
||||||
.workspace
|
if let Some((active_item, active_editor)) =
|
||||||
.upgrade()
|
outline_panel.workspace.upgrade().and_then(|workspace| {
|
||||||
.and_then(|workspace| workspace_active_editor(workspace.read(cx), cx))
|
workspace_active_editor(workspace.read(cx), cx)
|
||||||
{
|
})
|
||||||
if outline_panel.should_replace_active_item(active_item.as_ref()) {
|
{
|
||||||
outline_panel.replace_active_editor(active_item, active_editor, cx);
|
if outline_panel.should_replace_active_item(active_item.as_ref()) {
|
||||||
} else {
|
outline_panel.replace_active_editor(
|
||||||
outline_panel.update_fs_entries(active_editor, None, cx)
|
active_item,
|
||||||
|
active_editor,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
outline_panel.update_fs_entries(active_editor, None, cx)
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else if !outline_panel.pinned {
|
}
|
||||||
|
|
||||||
|
if !outline_panel.pinned {
|
||||||
outline_panel.clear_previous(cx);
|
outline_panel.clear_previous(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4814,9 +4823,11 @@ fn subscribe_for_editor_events(
|
||||||
cx: &mut ViewContext<OutlinePanel>,
|
cx: &mut ViewContext<OutlinePanel>,
|
||||||
) -> Subscription {
|
) -> Subscription {
|
||||||
let debounce = Some(UPDATE_DEBOUNCE);
|
let debounce = Some(UPDATE_DEBOUNCE);
|
||||||
cx.subscribe(
|
cx.subscribe(editor, move |outline_panel, editor, e: &EditorEvent, cx| {
|
||||||
editor,
|
if !outline_panel.active {
|
||||||
move |outline_panel, editor, e: &EditorEvent, cx| match e {
|
return;
|
||||||
|
}
|
||||||
|
match e {
|
||||||
EditorEvent::SelectionsChanged { local: true } => {
|
EditorEvent::SelectionsChanged { local: true } => {
|
||||||
outline_panel.reveal_entry_for_selection(editor, cx);
|
outline_panel.reveal_entry_for_selection(editor, cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
@ -4921,8 +4932,8 @@ fn subscribe_for_editor_events(
|
||||||
outline_panel.update_non_fs_items(cx);
|
outline_panel.update_non_fs_items(cx);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
}
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn empty_icon() -> AnyElement {
|
fn empty_icon() -> AnyElement {
|
||||||
|
|
|
@ -170,6 +170,7 @@ impl From<&dyn PanelHandle> for AnyView {
|
||||||
pub struct Dock {
|
pub struct Dock {
|
||||||
position: DockPosition,
|
position: DockPosition,
|
||||||
panel_entries: Vec<PanelEntry>,
|
panel_entries: Vec<PanelEntry>,
|
||||||
|
workspace: WeakView<Workspace>,
|
||||||
is_open: bool,
|
is_open: bool,
|
||||||
active_panel_index: Option<usize>,
|
active_panel_index: Option<usize>,
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
|
@ -236,6 +237,7 @@ impl Dock {
|
||||||
});
|
});
|
||||||
Self {
|
Self {
|
||||||
position,
|
position,
|
||||||
|
workspace: workspace.downgrade(),
|
||||||
panel_entries: Default::default(),
|
panel_entries: Default::default(),
|
||||||
active_panel_index: None,
|
active_panel_index: None,
|
||||||
is_open: false,
|
is_open: false,
|
||||||
|
@ -337,6 +339,9 @@ impl Dock {
|
||||||
self.is_open = open;
|
self.is_open = open;
|
||||||
if let Some(active_panel) = self.active_panel_entry() {
|
if let Some(active_panel) = self.active_panel_entry() {
|
||||||
active_panel.panel.set_active(open, cx);
|
active_panel.panel.set_active(open, cx);
|
||||||
|
if !open {
|
||||||
|
self.active_panel_index = None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
@ -354,6 +359,11 @@ impl Dock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.workspace
|
||||||
|
.update(cx, |workspace, cx| {
|
||||||
|
workspace.serialize_workspace(cx);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +494,8 @@ impl Dock {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if !self.restore_state(cx) && panel.read(cx).starts_open(cx) {
|
self.restore_state(cx);
|
||||||
|
if panel.read(cx).starts_open(cx) {
|
||||||
self.activate_panel(index, cx);
|
self.activate_panel(index, cx);
|
||||||
self.set_open(true, cx);
|
self.set_open(true, cx);
|
||||||
}
|
}
|
||||||
|
@ -652,9 +663,14 @@ impl Render for Dock {
|
||||||
)
|
)
|
||||||
.on_mouse_up(
|
.on_mouse_up(
|
||||||
MouseButton::Left,
|
MouseButton::Left,
|
||||||
cx.listener(|v, e: &MouseUpEvent, cx| {
|
cx.listener(|dock, e: &MouseUpEvent, cx| {
|
||||||
if e.click_count == 2 {
|
if e.click_count == 2 {
|
||||||
v.resize_active_panel(None, cx);
|
dock.resize_active_panel(None, cx);
|
||||||
|
dock.workspace
|
||||||
|
.update(cx, |workspace, cx| {
|
||||||
|
workspace.serialize_workspace(cx);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -743,6 +743,7 @@ pub struct Workspace {
|
||||||
weak_self: WeakView<Self>,
|
weak_self: WeakView<Self>,
|
||||||
workspace_actions: Vec<Box<dyn Fn(Div, &mut ViewContext<Self>) -> Div>>,
|
workspace_actions: Vec<Box<dyn Fn(Div, &mut ViewContext<Self>) -> Div>>,
|
||||||
zoomed: Option<AnyWeakView>,
|
zoomed: Option<AnyWeakView>,
|
||||||
|
previous_dock_drag_coordinates: Option<Point<Pixels>>,
|
||||||
zoomed_position: Option<DockPosition>,
|
zoomed_position: Option<DockPosition>,
|
||||||
center: PaneGroup,
|
center: PaneGroup,
|
||||||
left_dock: View<Dock>,
|
left_dock: View<Dock>,
|
||||||
|
@ -1020,18 +1021,6 @@ impl Workspace {
|
||||||
|
|
||||||
ThemeSettings::reload_current_theme(cx);
|
ThemeSettings::reload_current_theme(cx);
|
||||||
}),
|
}),
|
||||||
cx.observe(&left_dock, |this, _, cx| {
|
|
||||||
this.serialize_workspace(cx);
|
|
||||||
cx.notify();
|
|
||||||
}),
|
|
||||||
cx.observe(&bottom_dock, |this, _, cx| {
|
|
||||||
this.serialize_workspace(cx);
|
|
||||||
cx.notify();
|
|
||||||
}),
|
|
||||||
cx.observe(&right_dock, |this, _, cx| {
|
|
||||||
this.serialize_workspace(cx);
|
|
||||||
cx.notify();
|
|
||||||
}),
|
|
||||||
cx.on_release(|this, window, cx| {
|
cx.on_release(|this, window, cx| {
|
||||||
this.app_state.workspace_store.update(cx, |store, _| {
|
this.app_state.workspace_store.update(cx, |store, _| {
|
||||||
let window = window.downcast::<Self>().unwrap();
|
let window = window.downcast::<Self>().unwrap();
|
||||||
|
@ -1047,6 +1036,7 @@ impl Workspace {
|
||||||
weak_self: weak_handle.clone(),
|
weak_self: weak_handle.clone(),
|
||||||
zoomed: None,
|
zoomed: None,
|
||||||
zoomed_position: None,
|
zoomed_position: None,
|
||||||
|
previous_dock_drag_coordinates: None,
|
||||||
center: PaneGroup::new(center_pane.clone()),
|
center: PaneGroup::new(center_pane.clone()),
|
||||||
panes: vec![center_pane.clone()],
|
panes: vec![center_pane.clone()],
|
||||||
panes_by_item: Default::default(),
|
panes_by_item: Default::default(),
|
||||||
|
@ -3060,6 +3050,7 @@ impl Workspace {
|
||||||
event: &pane::Event,
|
event: &pane::Event,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
|
let mut serialize_workspace = true;
|
||||||
match event {
|
match event {
|
||||||
pane::Event::AddItem { item } => {
|
pane::Event::AddItem { item } => {
|
||||||
item.added_to_pane(self, pane, cx);
|
item.added_to_pane(self, pane, cx);
|
||||||
|
@ -3070,10 +3061,14 @@ impl Workspace {
|
||||||
pane::Event::Split(direction) => {
|
pane::Event::Split(direction) => {
|
||||||
self.split_and_clone(pane, *direction, cx);
|
self.split_and_clone(pane, *direction, cx);
|
||||||
}
|
}
|
||||||
pane::Event::JoinIntoNext => self.join_pane_into_next(pane, cx),
|
pane::Event::JoinIntoNext => {
|
||||||
pane::Event::JoinAll => self.join_all_panes(cx),
|
self.join_pane_into_next(pane, cx);
|
||||||
|
}
|
||||||
|
pane::Event::JoinAll => {
|
||||||
|
self.join_all_panes(cx);
|
||||||
|
}
|
||||||
pane::Event::Remove { focus_on_pane } => {
|
pane::Event::Remove { focus_on_pane } => {
|
||||||
self.remove_pane(pane, focus_on_pane.clone(), cx)
|
self.remove_pane(pane, focus_on_pane.clone(), cx);
|
||||||
}
|
}
|
||||||
pane::Event::ActivateItem { local } => {
|
pane::Event::ActivateItem { local } => {
|
||||||
cx.on_next_frame(|_, cx| {
|
cx.on_next_frame(|_, cx| {
|
||||||
|
@ -3091,16 +3086,20 @@ impl Workspace {
|
||||||
self.update_active_view_for_followers(cx);
|
self.update_active_view_for_followers(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pane::Event::UserSavedItem { item, save_intent } => cx.emit(Event::UserSavedItem {
|
pane::Event::UserSavedItem { item, save_intent } => {
|
||||||
pane: pane.downgrade(),
|
cx.emit(Event::UserSavedItem {
|
||||||
item: item.boxed_clone(),
|
pane: pane.downgrade(),
|
||||||
save_intent: *save_intent,
|
item: item.boxed_clone(),
|
||||||
}),
|
save_intent: *save_intent,
|
||||||
|
});
|
||||||
|
serialize_workspace = false;
|
||||||
|
}
|
||||||
pane::Event::ChangeItemTitle => {
|
pane::Event::ChangeItemTitle => {
|
||||||
if pane == self.active_pane {
|
if pane == self.active_pane {
|
||||||
self.active_item_path_changed(cx);
|
self.active_item_path_changed(cx);
|
||||||
}
|
}
|
||||||
self.update_window_edited(cx);
|
self.update_window_edited(cx);
|
||||||
|
serialize_workspace = false;
|
||||||
}
|
}
|
||||||
pane::Event::RemoveItem { .. } => {}
|
pane::Event::RemoveItem { .. } => {}
|
||||||
pane::Event::RemovedItem { item_id } => {
|
pane::Event::RemovedItem { item_id } => {
|
||||||
|
@ -3139,7 +3138,9 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.serialize_workspace(cx);
|
if serialize_workspace {
|
||||||
|
self.serialize_workspace(cx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unfollow_in_pane(
|
pub fn unfollow_in_pane(
|
||||||
|
@ -4900,32 +4901,39 @@ impl Render for Workspace {
|
||||||
})
|
})
|
||||||
.when(self.zoomed.is_none(), |this| {
|
.when(self.zoomed.is_none(), |this| {
|
||||||
this.on_drag_move(cx.listener(
|
this.on_drag_move(cx.listener(
|
||||||
|workspace, e: &DragMoveEvent<DraggedDock>, cx| {
|
move |workspace, e: &DragMoveEvent<DraggedDock>, cx| {
|
||||||
match e.drag(cx).0 {
|
if workspace.previous_dock_drag_coordinates
|
||||||
DockPosition::Left => {
|
!= Some(e.event.position)
|
||||||
resize_left_dock(
|
{
|
||||||
e.event.position.x
|
workspace.previous_dock_drag_coordinates =
|
||||||
- workspace.bounds.left(),
|
Some(e.event.position);
|
||||||
workspace,
|
match e.drag(cx).0 {
|
||||||
cx,
|
DockPosition::Left => {
|
||||||
);
|
resize_left_dock(
|
||||||
}
|
e.event.position.x
|
||||||
DockPosition::Right => {
|
- workspace.bounds.left(),
|
||||||
resize_right_dock(
|
workspace,
|
||||||
workspace.bounds.right()
|
cx,
|
||||||
- e.event.position.x,
|
);
|
||||||
workspace,
|
}
|
||||||
cx,
|
DockPosition::Right => {
|
||||||
);
|
resize_right_dock(
|
||||||
}
|
workspace.bounds.right()
|
||||||
DockPosition::Bottom => {
|
- e.event.position.x,
|
||||||
resize_bottom_dock(
|
workspace,
|
||||||
workspace.bounds.bottom()
|
cx,
|
||||||
- e.event.position.y,
|
);
|
||||||
workspace,
|
}
|
||||||
cx,
|
DockPosition::Bottom => {
|
||||||
);
|
resize_bottom_dock(
|
||||||
}
|
workspace.bounds.bottom()
|
||||||
|
- e.event.position.y,
|
||||||
|
workspace,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
workspace.serialize_workspace(cx);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue