aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/api/layouts.rs39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/app/api/layouts.rs b/src/app/api/layouts.rs
index 9c492937..32dec32a 100644
--- a/src/app/api/layouts.rs
+++ b/src/app/api/layouts.rs
@@ -159,10 +159,12 @@ impl App {
let terminal_ids = self
.state
.terminal_ids_for_tab(target_ws_idx, target_tab_idx);
+ let plugin_pane_ids = self.state.pane_ids_for_tab(target_ws_idx, target_tab_idx);
let Some(ws) = self.state.workspaces.get_mut(target_ws_idx) else {
return encode_error(id, "tab_not_found", "tab not found");
};
if ws.close_tab(target_tab_idx) {
+ self.state.remove_plugin_pane_records(plugin_pane_ids);
self.state.remove_unattached_terminal_ids(terminal_ids);
self.shutdown_detached_terminal_runtimes();
self.emit_event(EventEnvelope {
@@ -464,12 +466,14 @@ impl App {
return;
};
let terminal_ids = self.state.terminal_ids_for_tab(ws_idx, tab_idx);
+ let plugin_pane_ids = self.state.pane_ids_for_tab(ws_idx, tab_idx);
if self
.state
.workspaces
.get_mut(ws_idx)
.is_some_and(|ws| ws.close_tab(tab_idx))
{
+ self.state.remove_plugin_pane_records(plugin_pane_ids);
self.state.remove_unattached_terminal_ids(terminal_ids);
self.shutdown_detached_terminal_runtimes();
}
@@ -700,6 +704,41 @@ mod tests {
}
#[tokio::test]
+ async fn layout_apply_replace_drops_plugin_pane_records_of_replaced_tab() {
+ let mut app = app_with_workspace();
+ let original_tab_id = app.public_tab_id(0, 0).unwrap();
+ let replaced_pane = app.state.workspaces[0].tabs[0].root_pane;
+ app.state.plugin_panes.insert(
+ replaced_pane,
+ crate::app::state::PluginPaneRecord {
+ plugin_id: "example.layout".into(),
+ entrypoint: "board".into(),
+ },
+ );
+
+ let response = app.handle_layout_apply(
+ "req".into(),
+ LayoutApplyParams {
+ workspace_id: None,
+ tab_id: Some(original_tab_id),
+ tab_label: Some("dev".into()),
+ focus: true,
+ root: LayoutNode::Pane {
+ pane: LayoutPane {
+ label: Some("editor".into()),
+ ..Default::default()
+ },
+ },
+ },
+ );
+
+ let success: SuccessResponse = serde_json::from_str(&response).unwrap();
+ assert!(matches!(success.result, ResponseResult::LayoutApply { .. }));
+ assert!(!app.state.plugin_panes.contains_key(&replaced_pane));
+ app.state.assert_invariants_for_test();
+ }
+
+ #[tokio::test]
async fn layout_apply_rejects_invalid_deep_leaf_without_creating_tab() {
let mut app = app_with_workspace();
let original_tab_count = app.state.workspaces[0].tabs.len();