mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-20 02:47:34 +03:00
Automatically close terminal dock when the last terminal was closed
This commit is contained in:
parent
916612caf1
commit
506f978c41
@ -1,44 +1,66 @@
|
||||
use gpui::{elements::*, Entity, ModelHandle, View, ViewContext, ViewHandle, WeakViewHandle};
|
||||
use crate::TerminalView;
|
||||
use gpui::{
|
||||
elements::*, AppContext, Entity, ModelHandle, Subscription, View, ViewContext, ViewHandle,
|
||||
WeakViewHandle,
|
||||
};
|
||||
use project::Project;
|
||||
use settings::{Settings, WorkingDirectory};
|
||||
use util::ResultExt;
|
||||
use workspace::{dock::Panel, DraggedItem, Pane, Workspace};
|
||||
use workspace::{dock::Panel, pane, DraggedItem, Pane, Workspace};
|
||||
|
||||
use crate::TerminalView;
|
||||
pub enum Event {
|
||||
Close,
|
||||
}
|
||||
|
||||
pub struct TerminalPanel {
|
||||
project: ModelHandle<Project>,
|
||||
pane: ViewHandle<Pane>,
|
||||
workspace: WeakViewHandle<Workspace>,
|
||||
_subscription: Subscription,
|
||||
}
|
||||
|
||||
impl TerminalPanel {
|
||||
pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
||||
let pane = cx.add_view(|cx| {
|
||||
let window_id = cx.window_id();
|
||||
let mut pane = Pane::new(
|
||||
workspace.weak_handle(),
|
||||
workspace.app_state().background_actions,
|
||||
cx,
|
||||
);
|
||||
pane.on_can_drop(move |drag_and_drop, cx| {
|
||||
drag_and_drop
|
||||
.currently_dragged::<DraggedItem>(window_id)
|
||||
.map_or(false, |(_, item)| {
|
||||
item.handle.act_as::<TerminalView>(cx).is_some()
|
||||
})
|
||||
});
|
||||
pane
|
||||
});
|
||||
let subscription = cx.subscribe(&pane, Self::handle_pane_event);
|
||||
Self {
|
||||
project: workspace.project().clone(),
|
||||
pane: cx.add_view(|cx| {
|
||||
let window_id = cx.window_id();
|
||||
let mut pane = Pane::new(
|
||||
workspace.weak_handle(),
|
||||
workspace.app_state().background_actions,
|
||||
cx,
|
||||
);
|
||||
pane.on_can_drop(move |drag_and_drop, cx| {
|
||||
drag_and_drop
|
||||
.currently_dragged::<DraggedItem>(window_id)
|
||||
.map_or(false, |(_, item)| {
|
||||
item.handle.act_as::<TerminalView>(cx).is_some()
|
||||
})
|
||||
});
|
||||
pane
|
||||
}),
|
||||
pane,
|
||||
workspace: workspace.weak_handle(),
|
||||
_subscription: subscription,
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_pane_event(
|
||||
&mut self,
|
||||
_pane: ViewHandle<Pane>,
|
||||
event: &pane::Event,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
match event {
|
||||
pane::Event::Remove => cx.emit(Event::Close),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for TerminalPanel {
|
||||
type Event = ();
|
||||
type Event = Event;
|
||||
}
|
||||
|
||||
impl View for TerminalPanel {
|
||||
@ -82,4 +104,8 @@ impl View for TerminalPanel {
|
||||
}
|
||||
}
|
||||
|
||||
impl Panel for TerminalPanel {}
|
||||
impl Panel for TerminalPanel {
|
||||
fn should_close_on_event(&self, event: &Event, _: &AppContext) -> bool {
|
||||
matches!(event, Event::Close)
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,10 @@ use settings::Settings;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub trait Panel: View {
|
||||
fn should_activate_item_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
|
||||
fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
|
||||
false
|
||||
}
|
||||
fn should_close_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
|
||||
false
|
||||
}
|
||||
fn should_show_badge(&self, _: &AppContext) -> bool {
|
||||
@ -53,6 +56,10 @@ impl From<&dyn PanelHandle> for AnyViewHandle {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Event {
|
||||
Close,
|
||||
}
|
||||
|
||||
pub struct Dock {
|
||||
position: DockPosition,
|
||||
items: Vec<Item>,
|
||||
@ -138,7 +145,7 @@ impl Dock {
|
||||
let subscriptions = [
|
||||
cx.observe(&view, |_, _, cx| cx.notify()),
|
||||
cx.subscribe(&view, |this, view, event, cx| {
|
||||
if view.read(cx).should_activate_item_on_event(event, cx) {
|
||||
if view.read(cx).should_activate_on_event(event, cx) {
|
||||
if let Some(ix) = this
|
||||
.items
|
||||
.iter()
|
||||
@ -146,6 +153,8 @@ impl Dock {
|
||||
{
|
||||
this.activate_item(ix, cx);
|
||||
}
|
||||
} else if view.read(cx).should_close_on_event(event, cx) {
|
||||
cx.emit(Event::Close);
|
||||
}
|
||||
}),
|
||||
];
|
||||
@ -183,7 +192,7 @@ impl Dock {
|
||||
}
|
||||
|
||||
impl Entity for Dock {
|
||||
type Event = ();
|
||||
type Event = Event;
|
||||
}
|
||||
|
||||
impl View for Dock {
|
||||
|
@ -461,7 +461,7 @@ pub struct Workspace {
|
||||
leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
|
||||
database_id: WorkspaceId,
|
||||
app_state: Arc<AppState>,
|
||||
_window_subscriptions: [Subscription; 3],
|
||||
_subscriptions: Vec<Subscription>,
|
||||
_apply_leader_updates: Task<Result<()>>,
|
||||
_observe_current_user: Task<Result<()>>,
|
||||
}
|
||||
@ -592,7 +592,7 @@ impl Workspace {
|
||||
active_call = Some((call, subscriptions));
|
||||
}
|
||||
|
||||
let subscriptions = [
|
||||
let subscriptions = vec![
|
||||
cx.observe_fullscreen(|_, _, cx| cx.notify()),
|
||||
cx.observe_window_activation(Self::on_window_activation_changed),
|
||||
cx.observe_window_bounds(move |_, mut bounds, display, cx| {
|
||||
@ -612,6 +612,9 @@ impl Workspace {
|
||||
.spawn(DB.set_window_bounds(workspace_id, bounds, display))
|
||||
.detach_and_log_err(cx);
|
||||
}),
|
||||
Self::register_dock(&left_dock, cx),
|
||||
Self::register_dock(&bottom_dock, cx),
|
||||
Self::register_dock(&right_dock, cx),
|
||||
];
|
||||
|
||||
let mut this = Workspace {
|
||||
@ -640,7 +643,7 @@ impl Workspace {
|
||||
_observe_current_user,
|
||||
_apply_leader_updates,
|
||||
leader_updates_tx,
|
||||
_window_subscriptions: subscriptions,
|
||||
_subscriptions: subscriptions,
|
||||
};
|
||||
this.project_remote_id_changed(project.read(cx).remote_id(), cx);
|
||||
cx.defer(|this, cx| this.update_window_title(cx));
|
||||
@ -1316,6 +1319,26 @@ impl Workspace {
|
||||
}
|
||||
}
|
||||
|
||||
fn register_dock(dock: &ViewHandle<Dock>, cx: &mut ViewContext<Self>) -> Subscription {
|
||||
cx.subscribe(dock, Self::handle_dock_event)
|
||||
}
|
||||
|
||||
fn handle_dock_event(
|
||||
&mut self,
|
||||
dock: ViewHandle<Dock>,
|
||||
event: &dock::Event,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
match event {
|
||||
dock::Event::Close => {
|
||||
dock.update(cx, |dock, cx| dock.set_open(false, cx));
|
||||
self.serialize_workspace(cx);
|
||||
cx.focus_self();
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_dock(&mut self, dock_side: DockPosition, cx: &mut ViewContext<Self>) {
|
||||
let dock = match dock_side {
|
||||
DockPosition::Left => &mut self.left_dock,
|
||||
|
Loading…
Reference in New Issue
Block a user