diff --git a/src/tests/e2e/cases.rs b/src/tests/e2e/cases.rs index 3fb0d44d..807d71e8 100644 --- a/src/tests/e2e/cases.rs +++ b/src/tests/e2e/cases.rs @@ -1663,3 +1663,40 @@ pub fn bracketed_paste() { }; assert_snapshot!(last_snapshot); } + +#[test] +#[ignore] +pub fn focus_tab_with_layout() { + let fake_win_size = Size { + cols: 120, + rows: 24, + }; + let layout_file_name = "focus-tab-layout.yaml"; + let mut test_attempts = 10; + let last_snapshot = loop { + RemoteRunner::kill_running_sessions(fake_win_size); + let mut runner = RemoteRunner::new_with_layout(fake_win_size, layout_file_name); + runner.run_all_steps(); + let last_snapshot = runner.take_snapshot_after(Step { + name: "Wait for app to load", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.status_bar_appears() + && remote_terminal.tip_appears() + && remote_terminal.snapshot_contains("Tab #3") + && remote_terminal.cursor_position_is(63, 2) + { + step_is_complete = true; + } + step_is_complete + }, + }); + if runner.test_timed_out && test_attempts > 0 { + test_attempts -= 1; + continue; + } else { + break last_snapshot; + } + }; + assert_snapshot!(last_snapshot); +} diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__focus_tab_with_layout.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__focus_tab_with_layout.snap new file mode 100644 index 00000000..fc4ff6d4 --- /dev/null +++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__focus_tab_with_layout.snap @@ -0,0 +1,29 @@ +--- +source: src/tests/e2e/cases.rs +expression: last_snapshot + +--- + Zellij (e2e-test)  Tab #1  Tab #2  Tab #3  Tab #4  Tab #5  Tab #6  Tab #7  Tab #8  Tab #9  +┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐ +│$ ││$ █ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘ + Ctrl + LOCK 

PANE  TAB  RESIZE  MOVE  SCROLL  SESSION  QUIT  + Tip: Alt + => new pane. Alt + <[] or hjkl> => navigate. Alt + <+-> => resize pane. diff --git a/src/tests/fixtures/layouts/focus-tab-layout.yaml b/src/tests/fixtures/layouts/focus-tab-layout.yaml new file mode 100644 index 00000000..1d019020 --- /dev/null +++ b/src/tests/fixtures/layouts/focus-tab-layout.yaml @@ -0,0 +1,92 @@ +--- +template: + direction: Horizontal + parts: + - direction: Vertical + split_size: + Fixed: 1 + run: + plugin: + location: "zellij:tab-bar" + borderless: true + - direction: Vertical + body: true + - direction: Vertical + split_size: + Fixed: 2 + run: + plugin: + location: "zellij:status-bar" + borderless: true + +tabs: +- direction: Vertical + parts: + - direction: Vertical + split_size: + Percent: 50 + - direction: Vertical + split_size: + Percent: 50 +- direction: Vertical +- direction: Vertical + focus: true + parts: + - direction: Vertical + split_size: + Percent: 50 + - direction: Vertical + focus: true + split_size: + Percent: 50 +- direction: Vertical + parts: + - direction: Vertical + split_size: + Percent: 50 + - direction: Horizontal + split_size: + Percent: 50 + parts: + - direction: Vertical + split_size: + Percent: 50 + - direction: Vertical + split_size: + Percent: 50 +- direction: Vertical +- direction: Vertical +- direction: Vertical +- direction: Vertical + parts: + - direction: Vertical + split_size: + Percent: 20 + run: + plugin: + location: "zellij:strider" + - direction: Horizontal + split_size: + Percent: 80 + parts: + - direction: Vertical + split_size: + Percent: 50 + - direction: Vertical + split_size: + Percent: 50 +- direction: Vertical + parts: + - direction: Vertical + split_size: + Percent: 40 + - direction: Horizontal + split_size: + Percent: 60 + parts: + - direction: Vertical + split_size: + Percent: 50 + - direction: Vertical + split_size: + Percent: 50 diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs index 96b7e7fa..3f7ac989 100644 --- a/zellij-server/src/lib.rs +++ b/zellij-server/src/lib.rs @@ -313,9 +313,25 @@ pub fn start_server(mut os_input: Box, socket_path: PathBuf) { }; if !&layout.tabs.is_empty() { - for tab_layout in layout.tabs { + for tab_layout in layout.clone().tabs { spawn_tabs(Some(tab_layout.clone())); } + + let focused_tab = layout + .tabs + .into_iter() + .enumerate() + .find(|(_, tab_layout)| tab_layout.focus.unwrap_or(false)); + if let Some((tab_index, _)) = focused_tab { + session_data + .read() + .unwrap() + .as_ref() + .unwrap() + .senders + .send_to_pty(PtyInstruction::GoToTab((tab_index + 1) as u32, client_id)) + .unwrap(); + } } else { spawn_tabs(None); } diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs index 99f7e375..327347cb 100644 --- a/zellij-server/src/pty.rs +++ b/zellij-server/src/pty.rs @@ -29,6 +29,7 @@ use zellij_utils::{ }; pub type VteBytes = Vec; +pub type TabIndex = u32; #[derive(Clone, Copy, Debug)] pub enum ClientOrTabIndex { @@ -43,6 +44,7 @@ pub(crate) enum PtyInstruction { SpawnTerminalVertically(Option, ClientId), SpawnTerminalHorizontally(Option, ClientId), UpdateActivePane(Option, ClientId), + GoToTab(TabIndex, ClientId), NewTab(Option, Option, ClientId), ClosePane(PaneId), CloseTab(Vec), @@ -56,6 +58,7 @@ impl From<&PtyInstruction> for PtyContext { PtyInstruction::SpawnTerminalVertically(..) => PtyContext::SpawnTerminalVertically, PtyInstruction::SpawnTerminalHorizontally(..) => PtyContext::SpawnTerminalHorizontally, PtyInstruction::UpdateActivePane(..) => PtyContext::UpdateActivePane, + PtyInstruction::GoToTab(..) => PtyContext::GoToTab, PtyInstruction::ClosePane(_) => PtyContext::ClosePane, PtyInstruction::CloseTab(_) => PtyContext::CloseTab, PtyInstruction::NewTab(..) => PtyContext::NewTab, @@ -114,6 +117,12 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box) { PtyInstruction::UpdateActivePane(pane_id, client_id) => { pty.set_active_pane(pane_id, client_id); } + PtyInstruction::GoToTab(tab_index, client_id) => { + pty.bus + .senders + .send_to_screen(ScreenInstruction::GoToTab(tab_index, Some(client_id))) + .unwrap(); + } PtyInstruction::NewTab(terminal_action, tab_layout, client_id) => { let tab_name = tab_layout.as_ref().and_then(|layout| { if layout.name.is_empty() { diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index 98871c63..66533aa3 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -122,6 +122,9 @@ pub(crate) struct Tab { pending_vte_events: HashMap>, selecting_with_mouse: bool, copy_command: Option, + // TODO: used only to focus the pane when the layout is loaded + // it seems that optimization is possible using `active_panes` + focus_pane_id: Option, } #[derive(Clone, Debug, Default, Serialize, Deserialize)] @@ -340,6 +343,7 @@ impl Tab { connected_clients, selecting_with_mouse: false, copy_command, + focus_pane_id: None, } } @@ -374,6 +378,13 @@ impl Tab { } let mut new_pids = new_pids.iter(); + let mut focus_pane_id: Option = None; + let mut set_focus_pane_id = |layout: &Layout, pane_id: PaneId| { + if layout.focus.unwrap_or(false) && focus_pane_id.is_none() { + focus_pane_id = Some(pane_id); + } + }; + for (layout, position_and_size) in positions_and_size { // A plugin pane if let Some(Run::Plugin(run)) = layout.run.clone() { @@ -392,6 +403,7 @@ impl Tab { ); new_plugin.set_borderless(layout.borderless); self.panes.insert(PaneId::Plugin(pid), Box::new(new_plugin)); + set_focus_pane_id(layout, PaneId::Plugin(pid)); } else { // there are still panes left to fill, use the pids we received in this method let pid = new_pids.next().unwrap(); // if this crashes it means we got less pids than there are panes in this layout @@ -406,6 +418,7 @@ impl Tab { new_pane.set_borderless(layout.borderless); self.panes .insert(PaneId::Terminal(*pid), Box::new(new_pane)); + set_focus_pane_id(layout, PaneId::Terminal(*pid)); } } for unused_pid in new_pids { @@ -435,24 +448,33 @@ impl Tab { self.offset_viewport(&geom) } self.set_pane_frames(self.draw_pane_frames); - // This is the end of the nasty viewport hack... - let next_selectable_pane_id = self - .panes - .iter() - .filter(|(_id, pane)| pane.selectable()) - .map(|(id, _)| id.to_owned()) - .next(); - match next_selectable_pane_id { - Some(active_pane_id) => { - let connected_clients: Vec = - self.connected_clients.iter().copied().collect(); - for client_id in connected_clients { - self.active_panes.insert(client_id, active_pane_id); - } + + let mut active_pane = |pane_id: PaneId| { + let connected_clients: Vec = self.connected_clients.iter().copied().collect(); + for client_id in connected_clients { + self.active_panes.insert(client_id, pane_id); } - None => { - // this is very likely a configuration error (layout with no selectable panes) - self.active_panes.clear(); + }; + + if let Some(pane_id) = focus_pane_id { + self.focus_pane_id = Some(pane_id); + active_pane(pane_id); + } else { + // This is the end of the nasty viewport hack... + let next_selectable_pane_id = self + .panes + .iter() + .filter(|(_id, pane)| pane.selectable()) + .map(|(id, _)| id.to_owned()) + .next(); + match next_selectable_pane_id { + Some(active_pane_id) => { + active_pane(active_pane_id); + } + None => { + // this is very likely a configuration error (layout with no selectable panes) + self.active_panes.clear(); + } } } } @@ -489,11 +511,15 @@ impl Tab { // no panes here, bye bye return; } - pane_ids.sort(); // TODO: make this predictable - pane_ids.retain(|p| !self.panes_to_hide.contains(p)); - let first_pane_id = pane_ids.get(0).unwrap(); + self.active_panes.insert( + client_id, + self.focus_pane_id.unwrap_or_else(|| { + pane_ids.sort(); // TODO: make this predictable + pane_ids.retain(|p| !self.panes_to_hide.contains(p)); + *pane_ids.get(0).unwrap() + }), + ); self.connected_clients.insert(client_id); - self.active_panes.insert(client_id, *first_pane_id); self.mode_info.insert( client_id, mode_info.unwrap_or_else(|| self.default_mode_info.clone()), @@ -515,6 +541,7 @@ impl Tab { } } pub fn remove_client(&mut self, client_id: ClientId) { + self.focus_pane_id = None; self.connected_clients.remove(&client_id); self.set_force_render(); } diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs index a546e6cc..88410389 100644 --- a/zellij-utils/src/errors.rs +++ b/zellij-utils/src/errors.rs @@ -281,6 +281,7 @@ pub enum PtyContext { SpawnTerminalVertically, SpawnTerminalHorizontally, UpdateActivePane, + GoToTab, NewTab, ClosePane, CloseTab, diff --git a/zellij-utils/src/input/layout.rs b/zellij-utils/src/input/layout.rs index 9fa6709c..d2125096 100644 --- a/zellij-utils/src/input/layout.rs +++ b/zellij-utils/src/input/layout.rs @@ -140,6 +140,7 @@ pub struct Layout { pub run: Option, #[serde(default)] pub borderless: bool, + pub focus: Option, } // The struct that is used to deserialize the layout from @@ -421,6 +422,7 @@ pub struct LayoutTemplate { #[serde(default)] pub body: bool, pub split_size: Option, + pub focus: Option, pub run: Option, } @@ -466,6 +468,7 @@ pub struct TabLayout { pub split_size: Option, #[serde(default)] pub name: String, + pub focus: Option, pub run: Option, } @@ -712,6 +715,7 @@ impl TryFrom for Layout { borderless: tab.borderless, parts: Self::from_vec_tab_layout(tab.parts)?, split_size: tab.split_size, + focus: tab.focus, run: tab.run.map(Run::try_from).transpose()?, }) } @@ -726,6 +730,7 @@ impl From for LayoutTemplate { parts: Self::from_vec_tab_layout(tab.parts), body: false, split_size: tab.split_size, + focus: tab.focus, run: tab.run, } } @@ -741,6 +746,7 @@ impl TryFrom for Layout { borderless: template.borderless, parts: Self::from_vec_template_layout(template.parts)?, split_size: template.split_size, + focus: template.focus, run: template .run .map(Run::try_from) @@ -761,6 +767,7 @@ impl Default for TabLayout { run: None, name: String::new(), pane_name: None, + focus: None, } } } @@ -778,10 +785,12 @@ impl Default for LayoutTemplate { body: true, borderless: false, split_size: None, + focus: None, run: None, parts: vec![], }], split_size: None, + focus: None, run: None, } } diff --git a/zellij-utils/src/input/unit/layout_test.rs b/zellij-utils/src/input/unit/layout_test.rs index aec34c45..292b6b01 100644 --- a/zellij-utils/src/input/unit/layout_test.rs +++ b/zellij-utils/src/input/unit/layout_test.rs @@ -41,11 +41,13 @@ fn default_layout_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: true, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Fixed(1)), run: Some(Run::Plugin(RunPlugin { @@ -57,6 +59,7 @@ fn default_layout_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: None, run: None, @@ -65,6 +68,7 @@ fn default_layout_merged_correctly() { direction: Direction::Vertical, borderless: true, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Fixed(2)), run: Some(Run::Plugin(RunPlugin { @@ -89,11 +93,13 @@ fn default_layout_new_tab_correct() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: true, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Fixed(1)), run: Some(Run::Plugin(RunPlugin { @@ -105,6 +111,7 @@ fn default_layout_new_tab_correct() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: None, run: None, @@ -113,6 +120,7 @@ fn default_layout_new_tab_correct() { direction: Direction::Vertical, borderless: true, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Fixed(2)), run: Some(Run::Plugin(RunPlugin { @@ -177,15 +185,18 @@ fn three_panes_with_tab_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![Layout { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -194,11 +205,13 @@ fn three_panes_with_tab_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -207,6 +220,7 @@ fn three_panes_with_tab_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -235,10 +249,12 @@ fn three_panes_with_tab_new_tab_is_correct() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![Layout { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: None, run: None, @@ -277,11 +293,13 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Fixed(1)), run: Some(Run::Plugin(RunPlugin { @@ -293,11 +311,13 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -306,11 +326,13 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -319,6 +341,7 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -335,6 +358,7 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Fixed(2)), run: Some(Run::Plugin(RunPlugin { @@ -359,11 +383,13 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Fixed(1)), run: Some(Run::Plugin(RunPlugin { @@ -375,6 +401,7 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: None, run: None, @@ -383,6 +410,7 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Fixed(2)), run: Some(Run::Plugin(RunPlugin { @@ -425,16 +453,19 @@ fn deeply_nested_tab_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(21.0)), run: None, @@ -443,11 +474,13 @@ fn deeply_nested_tab_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(22.0)), run: None, @@ -456,11 +489,13 @@ fn deeply_nested_tab_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(23.0)), run: None, @@ -469,6 +504,7 @@ fn deeply_nested_tab_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(24.0)), run: None, @@ -489,6 +525,7 @@ fn deeply_nested_tab_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(15.0)), run: None, @@ -497,6 +534,7 @@ fn deeply_nested_tab_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(15.0)), run: None, @@ -505,6 +543,7 @@ fn deeply_nested_tab_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(15.0)), run: None, @@ -544,11 +583,13 @@ fn three_tabs_tab_one_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -557,6 +598,7 @@ fn three_tabs_tab_one_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: None, run: None, @@ -582,16 +624,19 @@ fn three_tabs_tab_two_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -600,6 +645,7 @@ fn three_tabs_tab_two_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: None, run: None, @@ -612,6 +658,7 @@ fn three_tabs_tab_two_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: None, run: None, @@ -637,16 +684,19 @@ fn three_tabs_tab_three_merged_correctly() { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -655,6 +705,7 @@ fn three_tabs_tab_three_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: None, run: None, @@ -667,6 +718,7 @@ fn three_tabs_tab_three_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: None, run: None, @@ -703,10 +755,12 @@ fn no_tabs_merged_correctly() { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![Layout { direction: Direction::Horizontal, borderless: false, pane_name: None, + focus: None, parts: vec![], split_size: None, run: None, @@ -754,6 +808,7 @@ fn no_layout_template_merged_correctly() { run: None, borderless: false, pane_name: None, + focus: None, }, Layout { direction: Direction::Horizontal, @@ -762,17 +817,20 @@ fn no_layout_template_merged_correctly() { run: None, borderless: false, pane_name: None, + focus: None, }, ], split_size: None, run: None, borderless: false, pane_name: None, + focus: None, }], split_size: None, run: None, borderless: false, pane_name: None, + focus: None, }; assert_eq!(merged_layout, tab_layout.try_into().unwrap());