Fix zoomed terminal pane issues on split (#21668)
Closes https://github.com/zed-industries/zed/issues/21652 * prevents zooming out the panel when any terminal pane is closed * forces focus on new terminal panes, to prevent the workspace from getting odd pane events in the background Release Notes: - (Preview only) Fixed zoomed terminal pane issues on split
This commit is contained in:
parent
fa7dddd6b5
commit
14ba4a9c94
3 changed files with 87 additions and 28 deletions
|
@ -214,8 +214,13 @@ async fn deserialize_pane_group(
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let pane = panel
|
let pane = panel
|
||||||
.update(cx, |_, cx| {
|
.update(cx, |terminal_panel, cx| {
|
||||||
new_terminal_pane(workspace.clone(), project.clone(), cx)
|
new_terminal_pane(
|
||||||
|
workspace.clone(),
|
||||||
|
project.clone(),
|
||||||
|
terminal_panel.active_pane.read(cx).is_zoomed(),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.log_err()?;
|
.log_err()?;
|
||||||
let active_item = serialized_pane.active_item;
|
let active_item = serialized_pane.active_item;
|
||||||
|
|
|
@ -84,9 +84,10 @@ pub struct TerminalPanel {
|
||||||
impl TerminalPanel {
|
impl TerminalPanel {
|
||||||
pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
||||||
let project = workspace.project();
|
let project = workspace.project();
|
||||||
let pane = new_terminal_pane(workspace.weak_handle(), project.clone(), cx);
|
let pane = new_terminal_pane(workspace.weak_handle(), project.clone(), false, cx);
|
||||||
let center = PaneGroup::new(pane.clone());
|
let center = PaneGroup::new(pane.clone());
|
||||||
let enabled = project.read(cx).supports_terminal(cx);
|
let enabled = project.read(cx).supports_terminal(cx);
|
||||||
|
cx.focus_view(&pane);
|
||||||
let terminal_panel = Self {
|
let terminal_panel = Self {
|
||||||
center,
|
center,
|
||||||
active_pane: pane,
|
active_pane: pane,
|
||||||
|
@ -299,6 +300,9 @@ impl TerminalPanel {
|
||||||
let pane_count_before_removal = self.center.panes().len();
|
let pane_count_before_removal = self.center.panes().len();
|
||||||
let _removal_result = self.center.remove(&pane);
|
let _removal_result = self.center.remove(&pane);
|
||||||
if pane_count_before_removal == 1 {
|
if pane_count_before_removal == 1 {
|
||||||
|
self.center.first_pane().update(cx, |pane, cx| {
|
||||||
|
pane.set_zoomed(false, cx);
|
||||||
|
});
|
||||||
cx.emit(PanelEvent::Close);
|
cx.emit(PanelEvent::Close);
|
||||||
} else {
|
} else {
|
||||||
if let Some(focus_on_pane) =
|
if let Some(focus_on_pane) =
|
||||||
|
@ -308,25 +312,47 @@ impl TerminalPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pane::Event::ZoomIn => cx.emit(PanelEvent::ZoomIn),
|
pane::Event::ZoomIn => {
|
||||||
pane::Event::ZoomOut => cx.emit(PanelEvent::ZoomOut),
|
for pane in self.center.panes() {
|
||||||
|
pane.update(cx, |pane, cx| {
|
||||||
|
pane.set_zoomed(true, cx);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
cx.emit(PanelEvent::ZoomIn);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
pane::Event::ZoomOut => {
|
||||||
|
for pane in self.center.panes() {
|
||||||
|
pane.update(cx, |pane, cx| {
|
||||||
|
pane.set_zoomed(false, cx);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
cx.emit(PanelEvent::ZoomOut);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
pane::Event::AddItem { item } => {
|
pane::Event::AddItem { item } => {
|
||||||
if let Some(workspace) = self.workspace.upgrade() {
|
if let Some(workspace) = self.workspace.upgrade() {
|
||||||
workspace.update(cx, |workspace, cx| {
|
workspace.update(cx, |workspace, cx| {
|
||||||
item.added_to_pane(workspace, pane.clone(), cx)
|
item.added_to_pane(workspace, pane.clone(), cx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
self.serialize(cx);
|
||||||
}
|
}
|
||||||
pane::Event::Split(direction) => {
|
pane::Event::Split(direction) => {
|
||||||
let new_pane = self.new_pane_with_cloned_active_terminal(cx);
|
let new_pane = self.new_pane_with_cloned_active_terminal(cx);
|
||||||
let pane = pane.clone();
|
let pane = pane.clone();
|
||||||
let direction = *direction;
|
let direction = *direction;
|
||||||
cx.spawn(move |this, mut cx| async move {
|
cx.spawn(move |terminal_panel, mut cx| async move {
|
||||||
let Some(new_pane) = new_pane.await else {
|
let Some(new_pane) = new_pane.await else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
this.update(&mut cx, |this, _| {
|
terminal_panel
|
||||||
this.center.split(&pane, &new_pane, direction).log_err();
|
.update(&mut cx, |terminal_panel, cx| {
|
||||||
|
terminal_panel
|
||||||
|
.center
|
||||||
|
.split(&pane, &new_pane, direction)
|
||||||
|
.log_err();
|
||||||
|
cx.focus_view(&new_pane);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
})
|
})
|
||||||
|
@ -365,7 +391,7 @@ impl TerminalPanel {
|
||||||
.or_else(|| default_working_directory(workspace.read(cx), cx));
|
.or_else(|| default_working_directory(workspace.read(cx), cx));
|
||||||
let kind = TerminalKind::Shell(working_directory);
|
let kind = TerminalKind::Shell(working_directory);
|
||||||
let window = cx.window_handle();
|
let window = cx.window_handle();
|
||||||
cx.spawn(move |this, mut cx| async move {
|
cx.spawn(move |terminal_panel, mut cx| async move {
|
||||||
let terminal = project
|
let terminal = project
|
||||||
.update(&mut cx, |project, cx| {
|
.update(&mut cx, |project, cx| {
|
||||||
project.create_terminal(kind, window, cx)
|
project.create_terminal(kind, window, cx)
|
||||||
|
@ -380,10 +406,15 @@ impl TerminalPanel {
|
||||||
})
|
})
|
||||||
.ok()?,
|
.ok()?,
|
||||||
);
|
);
|
||||||
let pane = this
|
let pane = terminal_panel
|
||||||
.update(&mut cx, |this, cx| {
|
.update(&mut cx, |terminal_panel, cx| {
|
||||||
let pane = new_terminal_pane(weak_workspace, project, cx);
|
let pane = new_terminal_pane(
|
||||||
this.apply_tab_bar_buttons(&pane, cx);
|
weak_workspace,
|
||||||
|
project,
|
||||||
|
terminal_panel.active_pane.read(cx).is_zoomed(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
terminal_panel.apply_tab_bar_buttons(&pane, cx);
|
||||||
pane
|
pane
|
||||||
})
|
})
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
@ -392,7 +423,6 @@ impl TerminalPanel {
|
||||||
pane.add_item(terminal_view, true, true, None, cx);
|
pane.add_item(terminal_view, true, true, None, cx);
|
||||||
})
|
})
|
||||||
.ok()?;
|
.ok()?;
|
||||||
cx.focus_view(&pane).ok()?;
|
|
||||||
|
|
||||||
Some(pane)
|
Some(pane)
|
||||||
})
|
})
|
||||||
|
@ -814,6 +844,7 @@ impl TerminalPanel {
|
||||||
pub fn new_terminal_pane(
|
pub fn new_terminal_pane(
|
||||||
workspace: WeakView<Workspace>,
|
workspace: WeakView<Workspace>,
|
||||||
project: Model<Project>,
|
project: Model<Project>,
|
||||||
|
zoomed: bool,
|
||||||
cx: &mut ViewContext<TerminalPanel>,
|
cx: &mut ViewContext<TerminalPanel>,
|
||||||
) -> View<Pane> {
|
) -> View<Pane> {
|
||||||
let is_local = project.read(cx).is_local();
|
let is_local = project.read(cx).is_local();
|
||||||
|
@ -827,9 +858,11 @@ pub fn new_terminal_pane(
|
||||||
NewTerminal.boxed_clone(),
|
NewTerminal.boxed_clone(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
pane.set_zoomed(zoomed, cx);
|
||||||
pane.set_can_navigate(false, cx);
|
pane.set_can_navigate(false, cx);
|
||||||
pane.display_nav_history_buttons(None);
|
pane.display_nav_history_buttons(None);
|
||||||
pane.set_should_display_tab_bar(|_| true);
|
pane.set_should_display_tab_bar(|_| true);
|
||||||
|
pane.set_zoom_out_on_close(false);
|
||||||
|
|
||||||
let terminal_panel_for_split_check = terminal_panel.clone();
|
let terminal_panel_for_split_check = terminal_panel.clone();
|
||||||
pane.set_can_split(Some(Arc::new(move |pane, dragged_item, cx| {
|
pane.set_can_split(Some(Arc::new(move |pane, dragged_item, cx| {
|
||||||
|
@ -879,8 +912,12 @@ pub fn new_terminal_pane(
|
||||||
|
|
||||||
let new_pane = pane.drag_split_direction().and_then(|split_direction| {
|
let new_pane = pane.drag_split_direction().and_then(|split_direction| {
|
||||||
terminal_panel.update(cx, |terminal_panel, cx| {
|
terminal_panel.update(cx, |terminal_panel, cx| {
|
||||||
let new_pane =
|
let new_pane = new_terminal_pane(
|
||||||
new_terminal_pane(workspace.clone(), project.clone(), cx);
|
workspace.clone(),
|
||||||
|
project.clone(),
|
||||||
|
terminal_panel.active_pane.read(cx).is_zoomed(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
terminal_panel.apply_tab_bar_buttons(&new_pane, cx);
|
terminal_panel.apply_tab_bar_buttons(&new_pane, cx);
|
||||||
terminal_panel
|
terminal_panel
|
||||||
.center
|
.center
|
||||||
|
@ -1062,12 +1099,19 @@ impl Render for TerminalPanel {
|
||||||
cx.focus_view(&pane);
|
cx.focus_view(&pane);
|
||||||
} else {
|
} else {
|
||||||
let new_pane = terminal_panel.new_pane_with_cloned_active_terminal(cx);
|
let new_pane = terminal_panel.new_pane_with_cloned_active_terminal(cx);
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|terminal_panel, mut cx| async move {
|
||||||
if let Some(new_pane) = new_pane.await {
|
if let Some(new_pane) = new_pane.await {
|
||||||
this.update(&mut cx, |this, _| {
|
terminal_panel
|
||||||
this.center
|
.update(&mut cx, |terminal_panel, cx| {
|
||||||
.split(&this.active_pane, &new_pane, SplitDirection::Right)
|
terminal_panel
|
||||||
|
.center
|
||||||
|
.split(
|
||||||
|
&terminal_panel.active_pane,
|
||||||
|
&new_pane,
|
||||||
|
SplitDirection::Right,
|
||||||
|
)
|
||||||
.log_err();
|
.log_err();
|
||||||
|
cx.focus_view(&new_pane);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
@ -1152,8 +1196,12 @@ impl Panel for TerminalPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext<Self>) {
|
fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext<Self>) {
|
||||||
self.active_pane
|
for pane in self.center.panes() {
|
||||||
.update(cx, |pane, cx| pane.set_zoomed(zoomed, cx));
|
pane.update(cx, |pane, cx| {
|
||||||
|
pane.set_zoomed(zoomed, cx);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_active(&mut self, active: bool, cx: &mut ViewContext<Self>) {
|
fn set_active(&mut self, active: bool, cx: &mut ViewContext<Self>) {
|
||||||
|
|
|
@ -306,6 +306,7 @@ pub struct Pane {
|
||||||
pub split_item_context_menu_handle: PopoverMenuHandle<ContextMenu>,
|
pub split_item_context_menu_handle: PopoverMenuHandle<ContextMenu>,
|
||||||
pinned_tab_count: usize,
|
pinned_tab_count: usize,
|
||||||
diagnostics: HashMap<ProjectPath, DiagnosticSeverity>,
|
diagnostics: HashMap<ProjectPath, DiagnosticSeverity>,
|
||||||
|
zoom_out_on_close: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ActivationHistoryEntry {
|
pub struct ActivationHistoryEntry {
|
||||||
|
@ -507,6 +508,7 @@ impl Pane {
|
||||||
new_item_context_menu_handle: Default::default(),
|
new_item_context_menu_handle: Default::default(),
|
||||||
pinned_tab_count: 0,
|
pinned_tab_count: 0,
|
||||||
diagnostics: Default::default(),
|
diagnostics: Default::default(),
|
||||||
|
zoom_out_on_close: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1586,7 +1588,7 @@ impl Pane {
|
||||||
.remove(&item.item_id());
|
.remove(&item.item_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.items.is_empty() && close_pane_if_empty && self.zoomed {
|
if self.zoom_out_on_close && self.items.is_empty() && close_pane_if_empty && self.zoomed {
|
||||||
cx.emit(Event::ZoomOut);
|
cx.emit(Event::ZoomOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2787,6 +2789,10 @@ impl Pane {
|
||||||
pub fn drag_split_direction(&self) -> Option<SplitDirection> {
|
pub fn drag_split_direction(&self) -> Option<SplitDirection> {
|
||||||
self.drag_split_direction
|
self.drag_split_direction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_zoom_out_on_close(&mut self, zoom_out_on_close: bool) {
|
||||||
|
self.zoom_out_on_close = zoom_out_on_close;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FocusableView for Pane {
|
impl FocusableView for Pane {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue