diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index d34a261bfe..c2f7eb36e4 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -22,7 +22,7 @@ const TERMINAL_PANEL_KEY: &'static str = "TerminalPanel"; actions!(terminal_panel, [ToggleFocus]); pub fn init(cx: &mut AppContext) { - cx.add_action(TerminalPanel::add_terminal); + cx.add_action(TerminalPanel::new_terminal); } pub enum Event { @@ -80,7 +80,7 @@ impl TerminalPanel { cx.window_context().defer(move |cx| { if let Some(this) = this.upgrade(cx) { this.update(cx, |this, cx| { - this.add_terminal(&Default::default(), cx); + this.add_terminal(cx); }); } }) @@ -220,7 +220,18 @@ impl TerminalPanel { } } - fn add_terminal(&mut self, _: &workspace::NewTerminal, cx: &mut ViewContext) { + + fn new_terminal(workspace: &mut Workspace, _: &workspace::NewTerminal, cx: &mut ViewContext) { + let Some(this) = workspace.focus_panel::(cx) else { + return; + }; + + this.update(cx, |this, cx| { + this.add_terminal(cx) + }) + } + + fn add_terminal(&mut self, cx: &mut ViewContext) { let workspace = self.workspace.clone(); cx.spawn(|this, mut cx| async move { let pane = this.read_with(&cx, |this, _| this.pane.clone())?; @@ -363,7 +374,7 @@ impl Panel for TerminalPanel { fn set_active(&mut self, active: bool, cx: &mut ViewContext) { if active && self.pane.read(cx).items_len() == 0 { - self.add_terminal(&Default::default(), cx) + self.add_terminal(cx) } } diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 767e3bf4db..633b83afb8 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -38,7 +38,7 @@ use workspace::{ notifications::NotifyResultExt, pane, register_deserializable_item, searchable::{SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle}, - Pane, ToolbarItemLocation, Workspace, WorkspaceId, + Pane, ToolbarItemLocation, Workspace, WorkspaceId, NewCenterTerminal, }; pub use terminal::TerminalSettings; @@ -66,10 +66,10 @@ pub fn init(cx: &mut AppContext) { terminal_panel::init(cx); terminal::init(cx); - cx.add_action(TerminalView::deploy); - register_deserializable_item::(cx); + cx.add_action(TerminalView::deploy); + //Useful terminal views cx.add_action(TerminalView::send_text); cx.add_action(TerminalView::send_keystroke); @@ -101,7 +101,7 @@ impl TerminalView { ///Create a new Terminal in the current working directory or the user's home directory pub fn deploy( workspace: &mut Workspace, - _: &workspace::NewTerminal, + _: &NewCenterTerminal, cx: &mut ViewContext, ) { let strategy = settings::get::(cx); diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index e722b3be6a..23d3d6f378 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -3,7 +3,7 @@ mod dragged_item_receiver; use super::{ItemHandle, SplitDirection}; use crate::{ item::WeakItemHandle, toolbar::Toolbar, AutosaveSetting, Item, NewFile, NewSearch, NewTerminal, - ToggleZoom, Workspace, WorkspaceSettings, + ToggleZoom, Workspace, WorkspaceSettings, NewCenterTerminal, }; use anyhow::Result; use collections::{HashMap, HashSet, VecDeque}; @@ -131,7 +131,6 @@ pub enum Event { pub struct Pane { items: Vec>, activation_history: Vec, - is_active: bool, zoomed: bool, active_item_index: usize, last_focused_view_by_item: HashMap, @@ -238,7 +237,6 @@ impl Pane { Self { items: Vec::new(), activation_history: Vec::new(), - is_active: true, zoomed: false, active_item_index: 0, last_focused_view_by_item: Default::default(), @@ -996,7 +994,7 @@ impl Pane { AnchorCorner::TopRight, vec![ ContextMenuItem::action("New File", NewFile), - ContextMenuItem::action("New Terminal", NewTerminal), + ContextMenuItem::action("New Terminal", NewCenterTerminal), ContextMenuItem::action("New Search", NewSearch), ], cx, diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index e51a0bf812..9285e911ef 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -55,7 +55,7 @@ use std::{ path::{Path, PathBuf}, str, sync::{atomic::AtomicUsize, Arc}, - time::Duration, + time::Duration, rc::Rc, }; use crate::{ @@ -119,6 +119,7 @@ actions!( ActivateNextPane, FollowNextCollaborator, NewTerminal, + NewCenterTerminal, ToggleTerminalFocus, NewSearch, Feedback, @@ -1621,44 +1622,15 @@ impl Workspace { self.serialize_workspace(cx); } - pub fn toggle_panel( - &mut self, - position: DockPosition, - panel_index: usize, - cx: &mut ViewContext, - ) { - let dock = match position { - DockPosition::Left => &mut self.left_dock, - DockPosition::Bottom => &mut self.bottom_dock, - DockPosition::Right => &mut self.right_dock, - }; - let active_item = dock.update(cx, move |dock, cx| { - if dock.is_open() && dock.active_panel_index() == panel_index { - dock.set_open(false, cx); - None - } else { - dock.set_open(true, cx); - dock.activate_panel(panel_index, cx); - dock.visible_panel().cloned() - } - }); - - if let Some(active_item) = active_item { - if active_item.has_focus(cx) { - cx.focus_self(); - } else { - cx.focus(active_item.as_any()); - } - } else { - cx.focus_self(); - } - - self.serialize_workspace(cx); - - cx.notify(); + pub fn focus_panel(&mut self, cx: &mut ViewContext) -> Option> { + self.show_or_hide_panel::(cx, |_, _| true)?.as_any().clone().downcast() } pub fn toggle_panel_focus(&mut self, cx: &mut ViewContext) { + self.show_or_hide_panel::(cx, |panel, cx| !panel.has_focus(cx)); + } + + fn show_or_hide_panel(&mut self, cx: &mut ViewContext, show: impl Fn(&dyn PanelHandle, &mut ViewContext) -> bool) -> Option> { for (dock, position) in [ self.left_dock.clone(), self.bottom_dock.clone(), @@ -1676,21 +1648,24 @@ impl Workspace { if let Some(panel_index) = dock.read(cx).panel_index_for_type::() { let mut focus_center = false; let mut zoom_out = false; - dock.update(cx, |dock, cx| { + let panel = dock.update(cx, |dock, cx| { dock.activate_panel(panel_index, cx); - if let Some(panel) = dock.active_panel().cloned() { - if panel.has_focus(cx) { + let panel = dock.active_panel().cloned(); + if let Some(panel) = panel.as_ref() { + let should_show = show(&**panel, cx); + if should_show { + dock.set_open(true, cx); + cx.focus(panel.as_any()); + zoom_out = true; + } else { if panel.is_zoomed(cx) { dock.set_open(false, cx); } focus_center = true; - } else { - dock.set_open(true, cx); - cx.focus(panel.as_any()); - zoom_out = true; } } + panel }); if zoom_out { @@ -1702,9 +1677,10 @@ impl Workspace { self.serialize_workspace(cx); cx.notify(); - break; + return panel; } } + None } fn zoom_out(&mut self, cx: &mut ViewContext) {