@@ -776,17 +776,9 @@ impl Dock {
}
}
- pub fn panel_size(&self, panel: &dyn PanelHandle, window: &Window, cx: &App) -> Option<Pixels> {
- self.panel_entries
- .iter()
- .find(|entry| entry.panel.panel_id() == panel.panel_id())
- .map(|entry| self.resolved_panel_size(entry, window, cx))
- }
-
- pub fn active_panel_size(&self, window: &Window, cx: &App) -> Option<Pixels> {
+ pub fn active_panel_size(&self) -> Option<PanelSizeState> {
if self.is_open {
- self.active_panel_entry()
- .map(|entry| self.resolved_panel_size(entry, window, cx))
+ self.active_panel_entry().map(|entry| entry.size_state)
} else {
None
}
@@ -947,28 +939,6 @@ impl Dock {
}
}
- fn resolved_panel_size(&self, entry: &PanelEntry, window: &Window, cx: &App) -> Pixels {
- if self.position.axis() == Axis::Horizontal
- && entry.panel.supports_flexible_size(window, cx)
- {
- if let Some(workspace) = self.workspace.upgrade() {
- let workspace = workspace.read(cx);
- return resolve_panel_size(
- entry.size_state,
- entry.panel.as_ref(),
- self.position,
- workspace,
- window,
- cx,
- );
- }
- }
- entry
- .size_state
- .size
- .unwrap_or_else(|| entry.panel.default_size(window, cx))
- }
-
pub(crate) fn load_persisted_size_state(
workspace: &Workspace,
panel_key: &'static str,
@@ -988,41 +958,10 @@ impl Dock {
}
}
-pub(crate) fn resolve_panel_size(
- size_state: PanelSizeState,
- panel: &dyn PanelHandle,
- position: DockPosition,
- workspace: &Workspace,
- window: &Window,
- cx: &App,
-) -> Pixels {
- if position.axis() == Axis::Horizontal && panel.supports_flexible_size(window, cx) {
- let ratio = size_state
- .flexible_size_ratio
- .or_else(|| workspace.default_flexible_dock_ratio(position));
-
- if let Some(ratio) = ratio {
- return workspace
- .flexible_dock_size(position, ratio, window, cx)
- .unwrap_or_else(|| {
- size_state
- .size
- .unwrap_or_else(|| panel.default_size(window, cx))
- });
- }
- }
-
- size_state
- .size
- .unwrap_or_else(|| panel.default_size(window, cx))
-}
-
impl Render for Dock {
- fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
+ fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let dispatch_context = Self::dispatch_context();
if let Some(entry) = self.visible_entry() {
- let size = self.resolved_panel_size(entry, window, cx);
-
let position = self.position;
let create_resize_handle = || {
let handle = div()
@@ -1091,8 +1030,10 @@ impl Render for Dock {
.border_color(cx.theme().colors().border)
.overflow_hidden()
.map(|this| match self.position().axis() {
- Axis::Horizontal => this.w(size).h_full().flex_row(),
- Axis::Vertical => this.h(size).w_full().flex_col(),
+ // Width and height are always set on the workspace wrapper in
+ // render_dock, so fill whatever space the wrapper provides.
+ Axis::Horizontal => this.w_full().h_full().flex_row(),
+ Axis::Vertical => this.h_full().w_full().flex_col(),
})
.map(|this| match self.position() {
DockPosition::Left => this.border_r_1(),
@@ -1102,8 +1043,8 @@ impl Render for Dock {
.child(
div()
.map(|this| match self.position().axis() {
- Axis::Horizontal => this.min_w(size).h_full(),
- Axis::Vertical => this.min_h(size).w_full(),
+ Axis::Horizontal => this.w_full().h_full(),
+ Axis::Vertical => this.h_full().w_full(),
})
.child(
entry
@@ -2208,30 +2208,29 @@ impl Workspace {
did_set
}
- pub fn flexible_dock_size(
- &self,
- position: DockPosition,
- ratio: f32,
- window: &Window,
- cx: &App,
- ) -> Option<Pixels> {
- if position.axis() != Axis::Horizontal {
- return None;
+ fn dock_size(&self, dock: &Dock, window: &Window, cx: &App) -> Option<Pixels> {
+ let panel = dock.active_panel()?;
+ let size_state = dock
+ .stored_panel_size_state(panel.as_ref())
+ .unwrap_or_default();
+ let position = dock.position();
+
+ if position.axis() == Axis::Horizontal
+ && panel.supports_flexible_size(window, cx)
+ && let Some(ratio) = size_state
+ .flexible_size_ratio
+ .or_else(|| self.default_flexible_dock_ratio(position))
+ && let Some(available_width) =
+ self.available_width_for_horizontal_dock(position, window, cx)
+ {
+ return Some((available_width * ratio.clamp(0.0, 1.0)).max(RESIZE_HANDLE_SIZE));
}
- let available_width = self.available_width_for_horizontal_dock(position, window, cx)?;
- Some((available_width * ratio.clamp(0.0, 1.0)).max(RESIZE_HANDLE_SIZE))
- }
-
- pub fn resolved_dock_panel_size(
- &self,
- dock: &Dock,
- panel: &dyn PanelHandle,
- window: &Window,
- cx: &App,
- ) -> Pixels {
- let size_state = dock.stored_panel_size_state(panel).unwrap_or_default();
- dock::resolve_panel_size(size_state, panel, dock.position(), self, window, cx)
+ Some(
+ size_state
+ .size
+ .unwrap_or_else(|| panel.default_size(window, cx)),
+ )
}
pub fn flexible_dock_ratio_for_size(
@@ -4908,10 +4907,7 @@ impl Workspace {
if let Some(dock_entity) = active_dock {
let dock = dock_entity.read(cx);
- let Some(panel_size) = dock
- .active_panel()
- .map(|panel| self.resolved_dock_panel_size(&dock, panel.as_ref(), window, cx))
- else {
+ let Some(panel_size) = self.dock_size(&dock, window, cx) else {
return;
};
match dock.position() {
@@ -7274,14 +7270,46 @@ impl Workspace {
leader_border_for_pane(follower_states, &pane, window, cx)
});
- Some(
- div()
- .flex()
- .flex_none()
- .overflow_hidden()
- .child(dock.clone())
- .children(leader_border),
- )
+ let mut container = div()
+ .flex()
+ .overflow_hidden()
+ .flex_none()
+ .child(dock.clone())
+ .children(leader_border);
+
+ // Apply sizing only when the dock is open. When closed the dock is still
+ // included in the element tree so its focus handle remains mounted — without
+ // this, toggle_panel_focus cannot focus the panel when the dock is closed.
+ let dock = dock.read(cx);
+ if let Some(panel) = dock.visible_panel() {
+ let size_state = dock.stored_panel_size_state(panel.as_ref());
+ if position.axis() == Axis::Horizontal {
+ if let Some(ratio) = size_state
+ .and_then(|state| state.flexible_size_ratio)
+ .or_else(|| self.default_flexible_dock_ratio(position))
+ && panel.supports_flexible_size(window, cx)
+ {
+ let ratio = ratio.clamp(0.001, 0.999);
+ let grow = ratio / (1.0 - ratio);
+ let style = container.style();
+ style.flex_grow = Some(grow);
+ style.flex_shrink = Some(1.0);
+ style.flex_basis = Some(relative(0.).into());
+ } else {
+ let size = size_state
+ .and_then(|state| state.size)
+ .unwrap_or_else(|| panel.default_size(window, cx));
+ container = container.w(size);
+ }
+ } else {
+ let size = size_state
+ .and_then(|state| state.size)
+ .unwrap_or_else(|| panel.default_size(window, cx));
+ container = container.h(size);
+ }
+ }
+
+ Some(container)
}
pub fn for_window(window: &Window, cx: &App) -> Option<Entity<Workspace>> {
@@ -7351,18 +7379,17 @@ impl Workspace {
}
}
- fn adjust_dock_size_by_px(
+ fn resize_dock(
&mut self,
- panel_size: Pixels,
dock_pos: DockPosition,
- px: Pixels,
+ new_size: Pixels,
window: &mut Window,
cx: &mut Context<Self>,
) {
match dock_pos {
- DockPosition::Left => self.resize_left_dock(panel_size + px, window, cx),
- DockPosition::Right => self.resize_right_dock(panel_size + px, window, cx),
- DockPosition::Bottom => self.resize_bottom_dock(panel_size + px, window, cx),
+ DockPosition::Left => self.resize_left_dock(new_size, window, cx),
+ DockPosition::Right => self.resize_right_dock(new_size, window, cx),
+ DockPosition::Bottom => self.resize_bottom_dock(new_size, window, cx),
}
}
@@ -7806,14 +7833,10 @@ fn adjust_active_dock_size_by_px(
return;
};
let dock = active_dock.read(cx);
- let Some(panel_size) = dock
- .active_panel()
- .map(|panel| workspace.resolved_dock_panel_size(&dock, panel.as_ref(), window, cx))
- else {
+ let Some(panel_size) = workspace.dock_size(&dock, window, cx) else {
return;
};
- let dock_pos = dock.position();
- workspace.adjust_dock_size_by_px(panel_size, dock_pos, px, window, cx);
+ workspace.resize_dock(dock.position(), panel_size + px, window, cx);
}
fn adjust_open_docks_size_by_px(
@@ -7828,22 +7851,18 @@ fn adjust_open_docks_size_by_px(
.filter_map(|dock_entity| {
let dock = dock_entity.read(cx);
if dock.is_open() {
- let panel_size = dock.active_panel().map(|panel| {
- workspace.resolved_dock_panel_size(&dock, panel.as_ref(), window, cx)
- })?;
let dock_pos = dock.position();
- Some((panel_size, dock_pos, px))
+ let panel_size = workspace.dock_size(&dock, window, cx)?;
+ Some((dock_pos, panel_size + px))
} else {
None
}
})
.collect::<Vec<_>>();
- docks
- .into_iter()
- .for_each(|(panel_size, dock_pos, offset)| {
- workspace.adjust_dock_size_by_px(panel_size, dock_pos, offset, window, cx);
- });
+ for (position, new_size) in docks {
+ workspace.resize_dock(position, new_size, window, cx);
+ }
}
impl Focusable for Workspace {
@@ -12286,11 +12305,8 @@ mod tests {
let dock = workspace.right_dock().read(cx);
let workspace_width = workspace.bounds.size.width;
- let initial_width = dock
- .active_panel()
- .map(|panel| {
- workspace.resolved_dock_panel_size(&dock, panel.as_ref(), window, cx)
- })
+ let initial_width = workspace
+ .dock_size(&dock, window, cx)
.expect("flexible dock should have an initial width");
assert_eq!(initial_width, workspace_width / 2.);
@@ -12298,11 +12314,8 @@ mod tests {
workspace.resize_right_dock(px(300.), window, cx);
let dock = workspace.right_dock().read(cx);
- let resized_width = dock
- .active_panel()
- .map(|panel| {
- workspace.resolved_dock_panel_size(&dock, panel.as_ref(), window, cx)
- })
+ let resized_width = workspace
+ .dock_size(&dock, window, cx)
.expect("flexible dock should keep its resized width");
assert_eq!(resized_width, px(300.));
@@ -12322,9 +12335,8 @@ mod tests {
workspace.toggle_dock(DockPosition::Right, window, cx);
let dock = workspace.right_dock().read(cx);
- let reopened_width = dock
- .active_panel()
- .map(|panel| workspace.resolved_dock_panel_size(&dock, panel.as_ref(), window, cx))
+ let reopened_width = workspace
+ .dock_size(&dock, window, cx)
.expect("flexible dock should restore when reopened");
assert_eq!(reopened_width, resized_width);
@@ -12351,9 +12363,8 @@ mod tests {
);
let dock = workspace.right_dock().read(cx);
- let split_width = dock
- .active_panel()
- .map(|panel| workspace.resolved_dock_panel_size(&dock, panel.as_ref(), window, cx))
+ let split_width = workspace
+ .dock_size(&dock, window, cx)
.expect("flexible dock should keep its user-resized proportion");
assert_eq!(split_width, px(300.));
@@ -12361,9 +12372,8 @@ mod tests {
workspace.bounds.size.width = px(1600.);
let dock = workspace.right_dock().read(cx);
- let resized_window_width = dock
- .active_panel()
- .map(|panel| workspace.resolved_dock_panel_size(&dock, panel.as_ref(), window, cx))
+ let resized_window_width = workspace
+ .dock_size(&dock, window, cx)
.expect("flexible dock should preserve proportional size on window resize");
assert_eq!(
@@ -12533,9 +12543,8 @@ mod tests {
workspace.toggle_dock(DockPosition::Left, window, cx);
let left_dock = workspace.left_dock().read(cx);
- let left_width = left_dock
- .active_panel()
- .map(|p| workspace.resolved_dock_panel_size(&left_dock, p.as_ref(), window, cx))
+ let left_width = workspace
+ .dock_size(&left_dock, window, cx)
.expect("left dock should have an active panel");
assert_eq!(
@@ -12557,9 +12566,8 @@ mod tests {
);
let left_dock = workspace.left_dock().read(cx);
- let left_width = left_dock
- .active_panel()
- .map(|p| workspace.resolved_dock_panel_size(&left_dock, p.as_ref(), window, cx))
+ let left_width = workspace
+ .dock_size(&left_dock, window, cx)
.expect("left dock should still have an active panel after vertical split");
assert_eq!(
@@ -12578,15 +12586,13 @@ mod tests {
workspace.toggle_dock(DockPosition::Right, window, cx);
let right_dock = workspace.right_dock().read(cx);
- let right_width = right_dock
- .active_panel()
- .map(|p| workspace.resolved_dock_panel_size(&right_dock, p.as_ref(), window, cx))
+ let right_width = workspace
+ .dock_size(&right_dock, window, cx)
.expect("right dock should have an active panel");
let left_dock = workspace.left_dock().read(cx);
- let left_width = left_dock
- .active_panel()
- .map(|p| workspace.resolved_dock_panel_size(&left_dock, p.as_ref(), window, cx))
+ let left_width = workspace
+ .dock_size(&left_dock, window, cx)
.expect("left dock should still have an active panel");
let available_width = workspace.bounds.size.width - right_width;
@@ -12650,8 +12656,8 @@ mod tests {
panel_1.panel_id()
);
assert_eq!(
- left_dock.read(cx).active_panel_size(window, cx).unwrap(),
- px(300.)
+ workspace.dock_size(&left_dock.read(cx), window, cx),
+ Some(px(300.))
);
workspace.resize_left_dock(px(1337.), window, cx);
@@ -12684,7 +12690,12 @@ mod tests {
panel_1.panel_id()
);
assert_eq!(
- right_dock.read(cx).active_panel_size(window, cx).unwrap(),
+ right_dock
+ .read(cx)
+ .active_panel_size()
+ .unwrap()
+ .size
+ .unwrap(),
px(1337.)
);
@@ -12722,8 +12733,8 @@ mod tests {
panel_1.panel_id()
);
assert_eq!(
- left_dock.read(cx).active_panel_size(window, cx).unwrap(),
- px(1337.)
+ workspace.dock_size(&left_dock.read(cx), window, cx),
+ Some(px(1337.))
);
// And the right dock should be closed as it no longer has any panels.
assert!(!workspace.right_dock().read(cx).is_open());
@@ -12739,8 +12750,8 @@ mod tests {
// since the panel orientation changed from vertical to horizontal.
let bottom_dock = workspace.bottom_dock();
assert_eq!(
- bottom_dock.read(cx).active_panel_size(window, cx).unwrap(),
- px(300.),
+ workspace.dock_size(&bottom_dock.read(cx), window, cx),
+ Some(px(300.))
);
// Close bottom dock and move panel_1 back to the left.
bottom_dock.update(cx, |bottom_dock, cx| {