From 23d5f3f3e832ba68e0a191e7139c2e48a81445eb Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 14 Dec 2023 14:15:56 -0800 Subject: [PATCH] Enable all warnings in workspace, fix all warnings Bring back some workspace tests Co-authored-by: Conrad --- crates/gpui2/src/view.rs | 15 + crates/workspace2/src/dock.rs | 179 +----- crates/workspace2/src/item.rs | 6 +- crates/workspace2/src/modal_layer.rs | 6 +- crates/workspace2/src/notifications.rs | 43 +- crates/workspace2/src/pane.rs | 170 +++--- crates/workspace2/src/pane_group.rs | 416 +------------- crates/workspace2/src/searchable.rs | 4 +- crates/workspace2/src/status_bar.rs | 4 +- crates/workspace2/src/workspace2.rs | 729 ++++++++++++------------- 10 files changed, 474 insertions(+), 1098 deletions(-) diff --git a/crates/gpui2/src/view.rs b/crates/gpui2/src/view.rs index 280c52df2a..351eb0ad06 100644 --- a/crates/gpui2/src/view.rs +++ b/crates/gpui2/src/view.rs @@ -7,6 +7,7 @@ use crate::{ use anyhow::{Context, Result}; use std::{ any::TypeId, + fmt, hash::{Hash, Hasher}, }; @@ -297,6 +298,20 @@ impl From> for AnyWeakView { } } +impl PartialEq for AnyWeakView { + fn eq(&self, other: &Self) -> bool { + self.model == other.model + } +} + +impl std::fmt::Debug for AnyWeakView { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("AnyWeakView") + .field("entity_id", &self.model.entity_id) + .finish_non_exhaustive() + } +} + impl Render for T where T: 'static + FnMut(&mut WindowContext) -> E, diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 6a4740b6e2..54480f0b68 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -41,7 +41,7 @@ pub trait Panel: FocusableView + EventEmitter { } pub trait PanelHandle: Send + Sync { - fn entity_id(&self) -> EntityId; + fn panel_id(&self) -> EntityId; fn persistent_name(&self) -> &'static str; fn position(&self, cx: &WindowContext) -> DockPosition; fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool; @@ -62,7 +62,7 @@ impl PanelHandle for View where T: Panel, { - fn entity_id(&self) -> EntityId { + fn panel_id(&self) -> EntityId { Entity::entity_id(self) } @@ -135,7 +135,7 @@ pub struct Dock { is_open: bool, active_panel_index: usize, focus_handle: FocusHandle, - focus_subscription: Subscription, + _focus_subscription: Subscription, } impl FocusableView for Dock { @@ -187,7 +187,6 @@ struct PanelEntry { pub struct PanelButtons { dock: View, - workspace: WeakView, } impl Dock { @@ -204,7 +203,7 @@ impl Dock { active_panel_index: 0, is_open: false, focus_handle, - focus_subscription, + _focus_subscription: focus_subscription, } } @@ -261,7 +260,7 @@ impl Dock { pub fn set_panel_zoomed(&mut self, panel: &AnyView, zoomed: bool, cx: &mut ViewContext) { for entry in &mut self.panel_entries { - if entry.panel.entity_id() == panel.entity_id() { + if entry.panel.panel_id() == panel.entity_id() { if zoomed != entry.panel.is_zoomed(cx) { entry.panel.set_zoomed(zoomed, cx); } @@ -309,7 +308,7 @@ impl Dock { let was_visible = this.is_open() && this.visible_panel().map_or(false, |active_panel| { - active_panel.entity_id() == Entity::entity_id(&panel) + active_panel.panel_id() == Entity::entity_id(&panel) }); this.remove_panel(&panel, cx); @@ -351,7 +350,7 @@ impl Dock { if let Some(ix) = this .panel_entries .iter() - .position(|entry| entry.panel.entity_id() == Entity::entity_id(&panel)) + .position(|entry| entry.panel.panel_id() == Entity::entity_id(&panel)) { this.set_open(true, cx); this.activate_panel(ix, cx); @@ -361,7 +360,7 @@ impl Dock { PanelEvent::Close => { if this .visible_panel() - .map_or(false, |p| p.entity_id() == Entity::entity_id(&panel)) + .map_or(false, |p| p.panel_id() == Entity::entity_id(&panel)) { this.set_open(false, cx); } @@ -389,7 +388,7 @@ impl Dock { if let Some(panel_ix) = self .panel_entries .iter() - .position(|entry| entry.panel.entity_id() == Entity::entity_id(panel)) + .position(|entry| entry.panel.panel_id() == Entity::entity_id(panel)) { if panel_ix == self.active_panel_index { self.active_panel_index = 0; @@ -450,7 +449,7 @@ impl Dock { pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option { self.panel_entries .iter() - .find(|entry| entry.panel.entity_id() == panel.entity_id()) + .find(|entry| entry.panel.panel_id() == panel.panel_id()) .map(|entry| entry.panel.size(cx)) } @@ -549,166 +548,12 @@ impl Render for Dock { } impl PanelButtons { - pub fn new( - dock: View, - workspace: WeakView, - cx: &mut ViewContext, - ) -> Self { + pub fn new(dock: View, cx: &mut ViewContext) -> Self { cx.observe(&dock, |_, _, cx| cx.notify()).detach(); - Self { dock, workspace } + Self { dock } } } -// impl Render for PanelButtons { -// type Element = (); - -// fn render(&mut self, cx: &mut ViewContext) -> Self::Element { -// todo!("") -// } - -// fn ui_name() -> &'static str { -// "PanelButtons" -// } - -// fn render(&mut self, cx: &mut ViewContext) -> AnyElement { -// let theme = &settings::get::(cx).theme; -// let tooltip_style = theme.tooltip.clone(); -// let theme = &theme.workspace.status_bar.panel_buttons; -// let button_style = theme.button.clone(); -// let dock = self.dock.read(cx); -// let active_ix = dock.active_panel_index; -// let is_open = dock.is_open; -// let dock_position = dock.position; -// let group_style = match dock_position { -// DockPosition::Left => theme.group_left, -// DockPosition::Bottom => theme.group_bottom, -// DockPosition::Right => theme.group_right, -// }; -// let menu_corner = match dock_position { -// DockPosition::Left => AnchorCorner::BottomLeft, -// DockPosition::Bottom | DockPosition::Right => AnchorCorner::BottomRight, -// }; - -// let panels = dock -// .panel_entries -// .iter() -// .map(|item| (item.panel.clone(), item.context_menu.clone())) -// .collect::>(); -// Flex::row() -// .with_children(panels.into_iter().enumerate().filter_map( -// |(panel_ix, (view, context_menu))| { -// let icon_path = view.icon_path(cx)?; -// let is_active = is_open && panel_ix == active_ix; -// let (tooltip, tooltip_action) = if is_active { -// ( -// format!("Close {} dock", dock_position.to_label()), -// Some(match dock_position { -// DockPosition::Left => crate::ToggleLeftDock.boxed_clone(), -// DockPosition::Bottom => crate::ToggleBottomDock.boxed_clone(), -// DockPosition::Right => crate::ToggleRightDock.boxed_clone(), -// }), -// ) -// } else { -// view.icon_tooltip(cx) -// }; -// Some( -// Stack::new() -// .with_child( -// MouseEventHandler::new::(panel_ix, cx, |state, cx| { -// let style = button_style.in_state(is_active); - -// let style = style.style_for(state); -// Flex::row() -// .with_child( -// Svg::new(icon_path) -// .with_color(style.icon_color) -// .constrained() -// .with_width(style.icon_size) -// .aligned(), -// ) -// .with_children(if let Some(label) = view.icon_label(cx) { -// Some( -// Label::new(label, style.label.text.clone()) -// .contained() -// .with_style(style.label.container) -// .aligned(), -// ) -// } else { -// None -// }) -// .constrained() -// .with_height(style.icon_size) -// .contained() -// .with_style(style.container) -// }) -// .with_cursor_style(CursorStyle::PointingHand) -// .on_click(MouseButton::Left, { -// let tooltip_action = -// tooltip_action.as_ref().map(|action| action.boxed_clone()); -// move |_, this, cx| { -// if let Some(tooltip_action) = &tooltip_action { -// let window = cx.window(); -// let view_id = this.workspace.id(); -// let tooltip_action = tooltip_action.boxed_clone(); -// cx.spawn(|_, mut cx| async move { -// window.dispatch_action( -// view_id, -// &*tooltip_action, -// &mut cx, -// ); -// }) -// .detach(); -// } -// } -// }) -// .on_click(MouseButton::Right, { -// let view = view.clone(); -// let menu = context_menu.clone(); -// move |_, _, cx| { -// const POSITIONS: [DockPosition; 3] = [ -// DockPosition::Left, -// DockPosition::Right, -// DockPosition::Bottom, -// ]; - -// menu.update(cx, |menu, cx| { -// let items = POSITIONS -// .into_iter() -// .filter(|position| { -// *position != dock_position -// && view.position_is_valid(*position, cx) -// }) -// .map(|position| { -// let view = view.clone(); -// ContextMenuItem::handler( -// format!("Dock {}", position.to_label()), -// move |cx| view.set_position(position, cx), -// ) -// }) -// .collect(); -// menu.show(Default::default(), menu_corner, items, cx); -// }) -// } -// }) -// .with_tooltip::( -// panel_ix, -// tooltip, -// tooltip_action, -// tooltip_style.clone(), -// cx, -// ), -// ) -// .with_child(ChildView::new(&context_menu, cx)), -// ) -// }, -// )) -// .contained() -// .with_style(group_style) -// .into_any() -// } -// } - -// here be kittens impl Render for PanelButtons { type Element = Div; diff --git a/crates/workspace2/src/item.rs b/crates/workspace2/src/item.rs index c0242ffa17..43597f21a7 100644 --- a/crates/workspace2/src/item.rs +++ b/crates/workspace2/src/item.rs @@ -919,7 +919,7 @@ pub mod test { impl EventEmitter for TestItem {} impl FocusableView for TestItem { - fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle { + fn focus_handle(&self, _: &AppContext) -> gpui::FocusHandle { self.focus_handle.clone() } } @@ -941,8 +941,8 @@ pub mod test { fn tab_content( &self, detail: Option, - selected: bool, - cx: &ui::prelude::WindowContext, + _selected: bool, + _cx: &ui::prelude::WindowContext, ) -> AnyElement { self.tab_detail.set(detail); gpui::div().into_any_element() diff --git a/crates/workspace2/src/modal_layer.rs b/crates/workspace2/src/modal_layer.rs index a428ba3e18..8c1af48667 100644 --- a/crates/workspace2/src/modal_layer.rs +++ b/crates/workspace2/src/modal_layer.rs @@ -5,7 +5,7 @@ use gpui::{ use ui::{h_stack, v_stack}; pub trait ModalView: ManagedView { - fn on_before_dismiss(&mut self, cx: &mut ViewContext) -> bool { + fn on_before_dismiss(&mut self, _: &mut ViewContext) -> bool { true } } @@ -27,7 +27,7 @@ impl ModalViewHandle for View { pub struct ActiveModal { modal: Box, - subscription: Subscription, + _subscription: Subscription, previous_focus_handle: Option, focus_handle: FocusHandle, } @@ -63,7 +63,7 @@ impl ModalLayer { { self.active_modal = Some(ActiveModal { modal: Box::new(new_modal.clone()), - subscription: cx.subscribe(&new_modal, |this, modal, _: &DismissEvent, cx| { + _subscription: cx.subscribe(&new_modal, |this, _, _: &DismissEvent, cx| { this.hide_modal(cx); }), previous_focus_handle: cx.focused(), diff --git a/crates/workspace2/src/notifications.rs b/crates/workspace2/src/notifications.rs index 63475c2aba..a692388a06 100644 --- a/crates/workspace2/src/notifications.rs +++ b/crates/workspace2/src/notifications.rs @@ -104,12 +104,9 @@ impl Workspace { }) { let notification = build_notification(cx); - cx.subscribe( - ¬ification, - move |this, handle, event: &DismissEvent, cx| { - this.dismiss_notification_internal(type_id, id, cx); - }, - ) + cx.subscribe(¬ification, move |this, _, _: &DismissEvent, cx| { + this.dismiss_notification_internal(type_id, id, cx); + }) .detach(); self.notifications .push((type_id, id, Box::new(notification))); @@ -173,21 +170,15 @@ impl Workspace { pub mod simple_message_notification { use gpui::{ - div, AnyElement, AppContext, DismissEvent, Div, EventEmitter, InteractiveElement, - ParentElement, Render, SharedString, StatefulInteractiveElement, Styled, TextStyle, - ViewContext, + div, DismissEvent, Div, EventEmitter, InteractiveElement, ParentElement, Render, + SharedString, StatefulInteractiveElement, Styled, ViewContext, }; use std::sync::Arc; use ui::prelude::*; use ui::{h_stack, v_stack, Button, Icon, IconElement, Label, StyledExt}; - enum NotificationMessage { - Text(SharedString), - Element(fn(TextStyle, &AppContext) -> AnyElement), - } - pub struct MessageNotification { - message: NotificationMessage, + message: SharedString, on_click: Option)>>, click_message: Option, } @@ -200,23 +191,12 @@ pub mod simple_message_notification { S: Into, { Self { - message: NotificationMessage::Text(message.into()), + message: message.into(), on_click: None, click_message: None, } } - // not needed I think (only for the "new panel" toast, which is outdated now) - // pub fn new_element( - // message: fn(TextStyle, &AppContext) -> AnyElement, - // ) -> MessageNotification { - // Self { - // message: NotificationMessage::Element(message), - // on_click: None, - // click_message: None, - // } - // } - pub fn with_click_message(mut self, message: S) -> Self where S: Into, @@ -248,18 +228,13 @@ pub mod simple_message_notification { .child( h_stack() .justify_between() - .child(div().max_w_80().child(match &self.message { - NotificationMessage::Text(text) => Label::new(text.clone()), - NotificationMessage::Element(element) => { - todo!() - } - })) + .child(div().max_w_80().child(Label::new(self.message.clone()))) .child( div() .id("cancel") .child(IconElement::new(Icon::Close)) .cursor_pointer() - .on_click(cx.listener(|this, event, cx| this.dismiss(cx))), + .on_click(cx.listener(|this, _, cx| this.dismiss(cx))), ), ) .children(self.click_message.iter().map(|message| { diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 2f6dec5bc4..4c436daada 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -7,7 +7,7 @@ use crate::{ use anyhow::Result; use collections::{HashMap, HashSet, VecDeque}; use gpui::{ - actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AnyWeakView, AppContext, + actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AppContext, AsyncWindowContext, DismissEvent, Div, EntityId, EventEmitter, FocusHandle, Focusable, FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel, Render, ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext, @@ -164,11 +164,6 @@ impl fmt::Debug for Event { } } -struct FocusedView { - view: AnyWeakView, - focus_handle: FocusHandle, -} - pub struct Pane { focus_handle: FocusHandle, items: Vec>, @@ -187,7 +182,7 @@ pub struct Pane { // can_drop: Rc, &WindowContext) -> bool>, can_split: bool, // render_tab_bar_buttons: Rc) -> AnyElement>, - subscriptions: Vec, + _subscriptions: Vec, tab_bar_scroll_handle: ScrollHandle, } @@ -432,14 +427,10 @@ impl Pane { // }) // .into_any() // }), - subscriptions, + _subscriptions: subscriptions, } } - pub(crate) fn workspace(&self) -> &WeakView { - &self.workspace - } - pub fn has_focus(&self, cx: &WindowContext) -> bool { // todo!(); // inline this manually self.focus_handle.contains_focused(cx) @@ -1468,21 +1459,6 @@ impl Pane { let label = item.tab_content(Some(detail), is_active, cx); let close_side = &ItemSettings::get_global(cx).close_position; - let (text_color, tab_bg, tab_hover_bg, tab_active_bg) = match ix == self.active_item_index { - false => ( - cx.theme().colors().text_muted, - cx.theme().colors().tab_inactive_background, - cx.theme().colors().ghost_element_hover, - cx.theme().colors().ghost_element_active, - ), - true => ( - cx.theme().colors().text, - cx.theme().colors().tab_active_background, - cx.theme().colors().element_hover, - cx.theme().colors().element_active, - ), - }; - let indicator = maybe!({ let indicator_color = match (item.has_conflict(cx), item.is_dirty(cx)) { (true, _) => Color::Warning, @@ -1498,57 +1474,55 @@ impl Pane { let is_last_item = ix == self.items.len() - 1; let position_relative_to_active_item = ix.cmp(&self.active_item_index); - let tab = - Tab::new(ix) - .position(if is_first_item { - TabPosition::First - } else if is_last_item { - TabPosition::Last - } else { - TabPosition::Middle(position_relative_to_active_item) - }) - .close_side(match close_side { - ClosePosition::Left => ui::TabCloseSide::Start, - ClosePosition::Right => ui::TabCloseSide::End, - }) - .selected(is_active) - .on_click(cx.listener(move |pane: &mut Self, event, cx| { - pane.activate_item(ix, true, true, cx) - })) - .on_drag( - DraggedTab { - pane: cx.view().clone(), - detail, - item_id, - is_active, - ix, - }, - |tab, cx| cx.build_view(|cx| tab.clone()), - ) - .drag_over::(|tab| tab.bg(cx.theme().colors().tab_active_background)) - .drag_over::(|tab| tab.bg(gpui::red())) - .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { - this.handle_tab_drop(dragged_tab, ix, cx) - })) - .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { - dbg!(entry_id); - this.handle_project_entry_drop(entry_id, ix, cx) - })) - .when_some(item.tab_tooltip_text(cx), |tab, text| { - tab.tooltip(move |cx| Tooltip::text(text.clone(), cx)) - }) - .start_slot::(indicator) - .end_slot( - IconButton::new("close tab", Icon::Close) - .icon_color(Color::Muted) - .size(ButtonSize::None) - .icon_size(IconSize::XSmall) - .on_click(cx.listener(move |pane, _, cx| { - pane.close_item_by_id(item_id, SaveIntent::Close, cx) - .detach_and_log_err(cx); - })), - ) - .child(label); + let tab = Tab::new(ix) + .position(if is_first_item { + TabPosition::First + } else if is_last_item { + TabPosition::Last + } else { + TabPosition::Middle(position_relative_to_active_item) + }) + .close_side(match close_side { + ClosePosition::Left => ui::TabCloseSide::Start, + ClosePosition::Right => ui::TabCloseSide::End, + }) + .selected(is_active) + .on_click( + cx.listener(move |pane: &mut Self, _, cx| pane.activate_item(ix, true, true, cx)), + ) + .on_drag( + DraggedTab { + pane: cx.view().clone(), + detail, + item_id, + is_active, + ix, + }, + |tab, cx| cx.build_view(|_| tab.clone()), + ) + .drag_over::(|tab| tab.bg(cx.theme().colors().tab_active_background)) + .drag_over::(|tab| tab.bg(gpui::red())) + .on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| { + this.handle_tab_drop(dragged_tab, ix, cx) + })) + .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { + this.handle_project_entry_drop(entry_id, cx) + })) + .when_some(item.tab_tooltip_text(cx), |tab, text| { + tab.tooltip(move |cx| Tooltip::text(text.clone(), cx)) + }) + .start_slot::(indicator) + .end_slot( + IconButton::new("close tab", Icon::Close) + .icon_color(Color::Muted) + .size(ButtonSize::None) + .icon_size(IconSize::XSmall) + .on_click(cx.listener(move |pane, _, cx| { + pane.close_item_by_id(item_id, SaveIntent::Close, cx) + .detach_and_log_err(cx); + })), + ) + .child(label); let single_entry_to_resolve = { let item_entries = self.items[ix].project_entry_ids(cx); @@ -1618,12 +1592,12 @@ impl Pane { IconButton::new("plus", Icon::Plus) .icon_size(IconSize::Small) .on_click(cx.listener(|this, _, cx| { - let menu = ContextMenu::build(cx, |menu, cx| { + let menu = ContextMenu::build(cx, |menu, _| { menu.action("New File", NewFile.boxed_clone()) .action("New Terminal", NewCenterTerminal.boxed_clone()) .action("New Search", NewSearch.boxed_clone()) }); - cx.subscribe(&menu, |this, _, event: &DismissEvent, cx| { + cx.subscribe(&menu, |this, _, _: &DismissEvent, cx| { this.focus(cx); this.new_item_menu = None; }) @@ -1642,13 +1616,13 @@ impl Pane { IconButton::new("split", Icon::Split) .icon_size(IconSize::Small) .on_click(cx.listener(|this, _, cx| { - let menu = ContextMenu::build(cx, |menu, cx| { + let menu = ContextMenu::build(cx, |menu, _| { menu.action("Split Right", SplitRight.boxed_clone()) .action("Split Left", SplitLeft.boxed_clone()) .action("Split Up", SplitUp.boxed_clone()) .action("Split Down", SplitDown.boxed_clone()) }); - cx.subscribe(&menu, |this, _, event: &DismissEvent, cx| { + cx.subscribe(&menu, |this, _, _: &DismissEvent, cx| { this.focus(cx); this.split_item_menu = None; }) @@ -1684,7 +1658,7 @@ impl Pane { this.handle_tab_drop(dragged_tab, this.items.len(), cx) })) .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { - this.handle_project_entry_drop(entry_id, this.items.len(), cx) + this.handle_project_entry_drop(entry_id, cx) })), ) } @@ -1755,7 +1729,7 @@ impl Pane { let from_pane = dragged_tab.pane.clone(); let to_pane = cx.view().clone(); self.workspace - .update(cx, |workspace, cx| { + .update(cx, |_, cx| { cx.defer(move |workspace, cx| { workspace.move_item(from_pane, to_pane, item_id, ix, cx); }); @@ -1766,13 +1740,12 @@ impl Pane { fn handle_project_entry_drop( &mut self, project_entry_id: &ProjectEntryId, - ix: usize, cx: &mut ViewContext<'_, Pane>, ) { let to_pane = cx.view().downgrade(); let project_entry_id = *project_entry_id; self.workspace - .update(cx, |workspace, cx| { + .update(cx, |_, cx| { cx.defer(move |workspace, cx| { if let Some(path) = workspace .project() @@ -1798,19 +1771,10 @@ impl Pane { let from_pane = dragged_tab.pane.clone(); let to_pane = cx.view().clone(); self.workspace - .update(cx, |workspace, cx| { + .update(cx, |_, cx| { cx.defer(move |workspace, cx| { - let item = from_pane - .read(cx) - .items() - .find(|item| item.item_id() == item_id) - .map(|item| item.boxed_clone()); - if let Some(item) = item { - if let Some(item) = item.clone_on_split(workspace.database_id(), cx) { - let pane = workspace.split_pane(to_pane, split_direction, cx); - workspace.move_item(from_pane, pane, item_id, 0, cx); - } - } + let pane = workspace.split_pane(to_pane, split_direction, cx); + workspace.move_item(from_pane, pane, item_id, 0, cx); }); }) .log_err(); @@ -1825,7 +1789,7 @@ impl Pane { let project_entry_id = *project_entry_id; let current_pane = cx.view().clone(); self.workspace - .update(cx, |workspace, cx| { + .update(cx, |_, cx| { cx.defer(move |workspace, cx| { if let Some(path) = workspace .project() @@ -1853,8 +1817,6 @@ impl Render for Pane { type Element = Focusable
; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - let this = cx.view().downgrade(); - v_stack() .key_context("Pane") .track_focus(&self.focus_handle) @@ -1953,11 +1915,7 @@ impl Render for Pane { this.handle_tab_drop(dragged_tab, this.active_item_index(), cx) })) .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { - this.handle_project_entry_drop( - entry_id, - this.active_item_index(), - cx, - ) + this.handle_project_entry_drop(entry_id, cx) })), ) .children( diff --git a/crates/workspace2/src/pane_group.rs b/crates/workspace2/src/pane_group.rs index 5f14df833d..72466d9ce4 100644 --- a/crates/workspace2/src/pane_group.rs +++ b/crates/workspace2/src/pane_group.rs @@ -16,7 +16,7 @@ const HANDLE_HITBOX_SIZE: f32 = 10.0; //todo!(change this back to 4) const HORIZONTAL_MIN_SIZE: f32 = 80.; const VERTICAL_MIN_SIZE: f32 = 100.; -#[derive(Clone, PartialEq)] +#[derive(Clone)] pub struct PaneGroup { pub(crate) root: Member, } @@ -121,7 +121,7 @@ impl PaneGroup { } } -#[derive(Clone, PartialEq)] +#[derive(Clone)] pub(crate) enum Member { Axis(PaneAxis), Pane(View), @@ -426,12 +426,6 @@ pub(crate) struct PaneAxis { pub bounding_boxes: Arc>>>>, } -impl PartialEq for PaneAxis { - fn eq(&self, other: &Self) -> bool { - todo!() - } -} - impl PaneAxis { pub fn new(axis: Axis, members: Vec) -> Self { let flexes = Arc::new(Mutex::new(vec![1.; members.len()])); @@ -816,7 +810,7 @@ mod element { proposed_current_pixel_change -= current_pixel_change; } - // todo!(reserialize workspace) + // todo!(schedule serialize) // workspace.schedule_serialize(cx); cx.notify(); } @@ -851,7 +845,7 @@ mod element { cx.on_mouse_event({ let dragged_handle = dragged_handle.clone(); - move |e: &MouseDownEvent, phase, cx| { + move |e: &MouseDownEvent, phase, _cx| { if phase.bubble() && handle_bounds.contains(&e.position) { dragged_handle.replace(Some(ix)); } @@ -859,7 +853,7 @@ mod element { }); cx.on_mouse_event(move |e: &MouseMoveEvent, phase, cx| { let dragged_handle = dragged_handle.borrow(); - if *dragged_handle == Some(ix) { + if phase.bubble() && *dragged_handle == Some(ix) { Self::compute_resize(&flexes, e, ix, axis, axis_bounds, cx) } }); @@ -949,7 +943,7 @@ mod element { cx.with_z_index(1, |cx| { cx.on_mouse_event({ let state = state.clone(); - move |e: &MouseUpEvent, phase, cx| { + move |_: &MouseUpEvent, phase, _cx| { if phase.bubble() { state.replace(None); } @@ -968,402 +962,4 @@ mod element { fn flex_values_in_bounds(flexes: &[f32]) -> bool { (flexes.iter().copied().sum::() - flexes.len() as f32).abs() < 0.001 } - // // use std::{cell::RefCell, iter::from_fn, ops::Range, rc::Rc}; - - // // use gpui::{ - // // geometry::{ - // // rect::Bounds, - // // vector::{vec2f, Vector2F}, - // // }, - // // json::{self, ToJson}, - // // platform::{CursorStyle, MouseButton}, - // // scene::MouseDrag, - // // AnyElement, Axis, CursorRegion, Element, EventContext, MouseRegion, BoundsExt, - // // SizeConstraint, Vector2FExt, ViewContext, - // // }; - - // use crate::{ - // pane_group::{HANDLE_HITBOX_SIZE, HORIZONTAL_MIN_SIZE, VERTICAL_MIN_SIZE}, - // Workspace, WorkspaceSettings, - // }; - - // pub struct PaneAxisElement { - // axis: Axis, - // basis: usize, - // active_pane_ix: Option, - // flexes: Rc>>, - // children: Vec>, - // bounding_boxes: Rc>>>>, - // } - - // impl PaneAxisElement { - // pub fn new( - // axis: Axis, - // basis: usize, - // flexes: Rc>>, - // bounding_boxes: Rc>>>>, - // ) -> Self { - // Self { - // axis, - // basis, - // flexes, - // bounding_boxes, - // active_pane_ix: None, - // children: Default::default(), - // } - // } - - // pub fn set_active_pane(&mut self, active_pane_ix: Option) { - // self.active_pane_ix = active_pane_ix; - // } - - // fn layout_children( - // &mut self, - // active_pane_magnification: f32, - // constraint: SizeConstraint, - // remaining_space: &mut f32, - // remaining_flex: &mut f32, - // cross_axis_max: &mut f32, - // view: &mut Workspace, - // cx: &mut ViewContext, - // ) { - // let flexes = self.flexes.borrow(); - // let cross_axis = self.axis.invert(); - // for (ix, child) in self.children.iter_mut().enumerate() { - // let flex = if active_pane_magnification != 1. { - // if let Some(active_pane_ix) = self.active_pane_ix { - // if ix == active_pane_ix { - // active_pane_magnification - // } else { - // 1. - // } - // } else { - // 1. - // } - // } else { - // flexes[ix] - // }; - - // let child_size = if *remaining_flex == 0.0 { - // *remaining_space - // } else { - // let space_per_flex = *remaining_space / *remaining_flex; - // space_per_flex * flex - // }; - - // let child_constraint = match self.axis { - // Axis::Horizontal => SizeConstraint::new( - // vec2f(child_size, constraint.min.y()), - // vec2f(child_size, constraint.max.y()), - // ), - // Axis::Vertical => SizeConstraint::new( - // vec2f(constraint.min.x(), child_size), - // vec2f(constraint.max.x(), child_size), - // ), - // }; - // let child_size = child.layout(child_constraint, view, cx); - // *remaining_space -= child_size.along(self.axis); - // *remaining_flex -= flex; - // *cross_axis_max = cross_axis_max.max(child_size.along(cross_axis)); - // } - // } - - // fn handle_resize( - // flexes: Rc>>, - // axis: Axis, - // preceding_ix: usize, - // child_start: Vector2F, - // drag_bounds: Bounds, - // ) -> impl Fn(MouseDrag, &mut Workspace, &mut EventContext) { - // let size = move |ix, flexes: &[f32]| { - // drag_bounds.length_along(axis) * (flexes[ix] / flexes.len() as f32) - // }; - - // move |drag, workspace: &mut Workspace, cx| { - // if drag.end { - // // TODO: Clear cascading resize state - // return; - // } - // let min_size = match axis { - // Axis::Horizontal => HORIZONTAL_MIN_SIZE, - // Axis::Vertical => VERTICAL_MIN_SIZE, - // }; - // let mut flexes = flexes.borrow_mut(); - - // // Don't allow resizing to less than the minimum size, if elements are already too small - // if min_size - 1. > size(preceding_ix, flexes.as_slice()) { - // return; - // } - - // let mut proposed_current_pixel_change = (drag.position - child_start).along(axis) - // - size(preceding_ix, flexes.as_slice()); - - // let flex_changes = |pixel_dx, target_ix, next: isize, flexes: &[f32]| { - // let flex_change = pixel_dx / drag_bounds.length_along(axis); - // let current_target_flex = flexes[target_ix] + flex_change; - // let next_target_flex = - // flexes[(target_ix as isize + next) as usize] - flex_change; - // (current_target_flex, next_target_flex) - // }; - - // let mut successors = from_fn({ - // let forward = proposed_current_pixel_change > 0.; - // let mut ix_offset = 0; - // let len = flexes.len(); - // move || { - // let result = if forward { - // (preceding_ix + 1 + ix_offset < len).then(|| preceding_ix + ix_offset) - // } else { - // (preceding_ix as isize - ix_offset as isize >= 0) - // .then(|| preceding_ix - ix_offset) - // }; - - // ix_offset += 1; - - // result - // } - // }); - - // while proposed_current_pixel_change.abs() > 0. { - // let Some(current_ix) = successors.next() else { - // break; - // }; - - // let next_target_size = f32::max( - // size(current_ix + 1, flexes.as_slice()) - proposed_current_pixel_change, - // min_size, - // ); - - // let current_target_size = f32::max( - // size(current_ix, flexes.as_slice()) - // + size(current_ix + 1, flexes.as_slice()) - // - next_target_size, - // min_size, - // ); - - // let current_pixel_change = - // current_target_size - size(current_ix, flexes.as_slice()); - - // let (current_target_flex, next_target_flex) = - // flex_changes(current_pixel_change, current_ix, 1, flexes.as_slice()); - - // flexes[current_ix] = current_target_flex; - // flexes[current_ix + 1] = next_target_flex; - - // proposed_current_pixel_change -= current_pixel_change; - // } - - // workspace.schedule_serialize(cx); - // cx.notify(); - // } - // } - // } - - // impl Extend> for PaneAxisElement { - // fn extend>>(&mut self, children: T) { - // self.children.extend(children); - // } - // } - - // impl Element for PaneAxisElement { - // type LayoutState = f32; - // type PaintState = (); - - // fn layout( - // &mut self, - // constraint: SizeConstraint, - // view: &mut Workspace, - // cx: &mut ViewContext, - // ) -> (Vector2F, Self::LayoutState) { - // debug_assert!(self.children.len() == self.flexes.borrow().len()); - - // let active_pane_magnification = - // settings::get::(cx).active_pane_magnification; - - // let mut remaining_flex = 0.; - - // if active_pane_magnification != 1. { - // let active_pane_flex = self - // .active_pane_ix - // .map(|_| active_pane_magnification) - // .unwrap_or(1.); - // remaining_flex += self.children.len() as f32 - 1. + active_pane_flex; - // } else { - // for flex in self.flexes.borrow().iter() { - // remaining_flex += flex; - // } - // } - - // let mut cross_axis_max: f32 = 0.0; - // let mut remaining_space = constraint.max_along(self.axis); - - // if remaining_space.is_infinite() { - // panic!("flex contains flexible children but has an infinite constraint along the flex axis"); - // } - - // self.layout_children( - // active_pane_magnification, - // constraint, - // &mut remaining_space, - // &mut remaining_flex, - // &mut cross_axis_max, - // view, - // cx, - // ); - - // let mut size = match self.axis { - // Axis::Horizontal => vec2f(constraint.max.x() - remaining_space, cross_axis_max), - // Axis::Vertical => vec2f(cross_axis_max, constraint.max.y() - remaining_space), - // }; - - // if constraint.min.x().is_finite() { - // size.set_x(size.x().max(constraint.min.x())); - // } - // if constraint.min.y().is_finite() { - // size.set_y(size.y().max(constraint.min.y())); - // } - - // if size.x() > constraint.max.x() { - // size.set_x(constraint.max.x()); - // } - // if size.y() > constraint.max.y() { - // size.set_y(constraint.max.y()); - // } - - // (size, remaining_space) - // } - - // fn paint( - // &mut self, - // bounds: Bounds, - // visible_bounds: Bounds, - // remaining_space: &mut Self::LayoutState, - // view: &mut Workspace, - // cx: &mut ViewContext, - // ) -> Self::PaintState { - // let can_resize = settings::get::(cx).active_pane_magnification == 1.; - // let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); - - // let overflowing = *remaining_space < 0.; - // if overflowing { - // cx.scene().push_layer(Some(visible_bounds)); - // } - - // let mut child_origin = bounds.origin(); - - // let mut bounding_boxes = self.bounding_boxes.borrow_mut(); - // bounding_boxes.clear(); - - // let mut children_iter = self.children.iter_mut().enumerate().peekable(); - // while let Some((ix, child)) = children_iter.next() { - // let child_start = child_origin.clone(); - // child.paint(child_origin, visible_bounds, view, cx); - - // bounding_boxes.push(Some(Bounds::new(child_origin, child.size()))); - - // match self.axis { - // Axis::Horizontal => child_origin += vec2f(child.size().x(), 0.0), - // Axis::Vertical => child_origin += vec2f(0.0, child.size().y()), - // } - - // if can_resize && children_iter.peek().is_some() { - // cx.scene().push_stacking_context(None, None); - - // let handle_origin = match self.axis { - // Axis::Horizontal => child_origin - vec2f(HANDLE_HITBOX_SIZE / 2., 0.0), - // Axis::Vertical => child_origin - vec2f(0.0, HANDLE_HITBOX_SIZE / 2.), - // }; - - // let handle_bounds = match self.axis { - // Axis::Horizontal => Bounds::new( - // handle_origin, - // vec2f(HANDLE_HITBOX_SIZE, visible_bounds.height()), - // ), - // Axis::Vertical => Bounds::new( - // handle_origin, - // vec2f(visible_bounds.width(), HANDLE_HITBOX_SIZE), - // ), - // }; - - // let style = match self.axis { - // Axis::Horizontal => CursorStyle::ResizeLeftRight, - // Axis::Vertical => CursorStyle::ResizeUpDown, - // }; - - // cx.scene().push_cursor_region(CursorRegion { - // bounds: handle_bounds, - // style, - // }); - - // enum ResizeHandle {} - // let mut mouse_region = MouseRegion::new::( - // cx.view_id(), - // self.basis + ix, - // handle_bounds, - // ); - // mouse_region = mouse_region - // .on_drag( - // MouseButton::Left, - // Self::handle_resize( - // self.flexes.clone(), - // self.axis, - // ix, - // child_start, - // visible_bounds.clone(), - // ), - // ) - // .on_click(MouseButton::Left, { - // let flexes = self.flexes.clone(); - // move |e, v: &mut Workspace, cx| { - // if e.click_count >= 2 { - // let mut borrow = flexes.borrow_mut(); - // *borrow = vec![1.; borrow.len()]; - // v.schedule_serialize(cx); - // cx.notify(); - // } - // } - // }); - // cx.scene().push_mouse_region(mouse_region); - - // cx.scene().pop_stacking_context(); - // } - // } - - // if overflowing { - // cx.scene().pop_layer(); - // } - // } - - // fn rect_for_text_range( - // &self, - // range_utf16: Range, - // _: Bounds, - // _: Bounds, - // _: &Self::LayoutState, - // _: &Self::PaintState, - // view: &Workspace, - // cx: &ViewContext, - // ) -> Option> { - // self.children - // .iter() - // .find_map(|child| child.rect_for_text_range(range_utf16.clone(), view, cx)) - // } - - // fn debug( - // &self, - // bounds: Bounds, - // _: &Self::LayoutState, - // _: &Self::PaintState, - // view: &Workspace, - // cx: &ViewContext, - // ) -> json::Value { - // serde_json::json!({ - // "type": "PaneAxis", - // "bounds": bounds.to_json(), - // "axis": self.axis.to_json(), - // "flexes": *self.flexes.borrow(), - // "children": self.children.iter().map(|child| child.debug(view, cx)).collect::>() - // }) - // } - // } } diff --git a/crates/workspace2/src/searchable.rs b/crates/workspace2/src/searchable.rs index eadd602c84..59202cbbaf 100644 --- a/crates/workspace2/src/searchable.rs +++ b/crates/workspace2/src/searchable.rs @@ -193,7 +193,7 @@ impl SearchableItemHandle for View { cx: &mut WindowContext, ) -> Task>> { let matches = self.update(cx, |this, cx| this.find_matches(query, cx)); - cx.spawn(|cx| async { + cx.spawn(|_| async { let matches = matches.await; matches .into_iter() @@ -253,7 +253,7 @@ pub trait WeakSearchableItemHandle: WeakItemHandle { } impl WeakSearchableItemHandle for WeakView { - fn upgrade(&self, cx: &AppContext) -> Option> { + fn upgrade(&self, _cx: &AppContext) -> Option> { Some(Box::new(self.upgrade()?)) } diff --git a/crates/workspace2/src/status_bar.rs b/crates/workspace2/src/status_bar.rs index c0cbd127ac..ba571d6e0a 100644 --- a/crates/workspace2/src/status_bar.rs +++ b/crates/workspace2/src/status_bar.rs @@ -51,14 +51,14 @@ impl Render for StatusBar { } impl StatusBar { - fn render_left_tools(&self, cx: &mut ViewContext) -> impl IntoElement { + fn render_left_tools(&self, _: &mut ViewContext) -> impl IntoElement { h_stack() .items_center() .gap_2() .children(self.left_items.iter().map(|item| item.to_any())) } - fn render_right_tools(&self, cx: &mut ViewContext) -> impl IntoElement { + fn render_right_tools(&self, _: &mut ViewContext) -> impl IntoElement { h_stack() .items_center() .gap_2() diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 87083b0929..8318ba3f0f 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -1,15 +1,11 @@ -#![allow(unused_variables, dead_code, unused_mut)] -// todo!() this is to make transition easier. - pub mod dock; pub mod item; +mod modal_layer; pub mod notifications; pub mod pane; pub mod pane_group; mod persistence; pub mod searchable; -// todo!() -mod modal_layer; pub mod shared_screen; mod status_bar; mod toolbar; @@ -236,14 +232,14 @@ pub fn init(app_state: Arc, cx: &mut AppContext) { cx.on_action({ let app_state = Arc::downgrade(&app_state); move |_: &Open, cx: &mut AppContext| { - let mut paths = cx.prompt_for_paths(PathPromptOptions { + let paths = cx.prompt_for_paths(PathPromptOptions { files: true, directories: true, multiple: true, }); if let Some(app_state) = app_state.upgrade() { - cx.spawn(move |mut cx| async move { + cx.spawn(move |cx| async move { if let Some(paths) = paths.await.log_err().flatten() { cx.update(|cx| { open_paths(&paths, &app_state, None, cx).detach_and_log_err(cx) @@ -458,7 +454,7 @@ pub struct Workspace { leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>, database_id: WorkspaceId, app_state: Arc, - subscriptions: Vec, + _subscriptions: Vec, _apply_leader_updates: Task>, _observe_current_user: Task>, _schedule_serialize: Option>, @@ -590,12 +586,9 @@ impl Workspace { let left_dock = cx.build_view(|cx| Dock::new(DockPosition::Left, cx)); let bottom_dock = cx.build_view(|cx| Dock::new(DockPosition::Bottom, cx)); let right_dock = cx.build_view(|cx| Dock::new(DockPosition::Right, cx)); - let left_dock_buttons = - cx.build_view(|cx| PanelButtons::new(left_dock.clone(), weak_handle.clone(), cx)); - let bottom_dock_buttons = - cx.build_view(|cx| PanelButtons::new(bottom_dock.clone(), weak_handle.clone(), cx)); - let right_dock_buttons = - cx.build_view(|cx| PanelButtons::new(right_dock.clone(), weak_handle.clone(), cx)); + let left_dock_buttons = cx.build_view(|cx| PanelButtons::new(left_dock.clone(), cx)); + let bottom_dock_buttons = cx.build_view(|cx| PanelButtons::new(bottom_dock.clone(), cx)); + let right_dock_buttons = cx.build_view(|cx| PanelButtons::new(right_dock.clone(), cx)); let status_bar = cx.build_view(|cx| { let mut status_bar = StatusBar::new(¢er_pane.clone(), cx); status_bar.add_left_item(left_dock_buttons, cx); @@ -604,8 +597,7 @@ impl Workspace { status_bar }); - let workspace_handle = cx.view().downgrade(); - let modal_layer = cx.build_view(|cx| ModalLayer::new()); + let modal_layer = cx.build_view(|_| ModalLayer::new()); // todo!() // cx.update_default_global::, _, _>(|drag_and_drop, _| { @@ -703,7 +695,7 @@ impl Workspace { _apply_leader_updates, _schedule_serialize: None, leader_updates_tx, - subscriptions, + _subscriptions: subscriptions, pane_history_timestamp, workspace_actions: Default::default(), // This data will be incorrect, but it will be overwritten by the time it needs to be used. @@ -763,7 +755,7 @@ impl Workspace { }; let window = if let Some(window) = requesting_window { - cx.update_window(window.into(), |old_workspace, cx| { + cx.update_window(window.into(), |_, cx| { cx.replace_root_view(|cx| { Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx) }); @@ -1185,8 +1177,7 @@ impl Workspace { } fn save_all(&mut self, action: &SaveAll, cx: &mut ViewContext) { - let save_all = self - .save_all_internal(action.save_intent.unwrap_or(SaveIntent::SaveAll), cx) + self.save_all_internal(action.save_intent.unwrap_or(SaveIntent::SaveAll), cx) .detach_and_log_err(cx); } @@ -1216,7 +1207,7 @@ impl Workspace { cx.spawn(|workspace, mut cx| async move { // Override save mode and display "Save all files" prompt if save_intent == SaveIntent::Close && dirty_items.len() > 1 { - let mut answer = workspace.update(&mut cx, |_, cx| { + let answer = workspace.update(&mut cx, |_, cx| { let prompt = Pane::file_names_for_prompt( &mut dirty_items.iter().map(|(_, handle)| handle), dirty_items.len(), @@ -1261,7 +1252,7 @@ impl Workspace { } pub fn open(&mut self, _: &Open, cx: &mut ViewContext) { - let mut paths = cx.prompt_for_paths(PathPromptOptions { + let paths = cx.prompt_for_paths(PathPromptOptions { files: true, directories: true, multiple: true, @@ -1390,7 +1381,7 @@ impl Workspace { } fn add_folder_to_project(&mut self, _: &AddFolderToProject, cx: &mut ViewContext) { - let mut paths = cx.prompt_for_paths(PathPromptOptions { + let paths = cx.prompt_for_paths(PathPromptOptions { files: false, directories: true, multiple: true, @@ -1670,6 +1661,8 @@ impl Workspace { None } + // todo!("implement zoom") + #[allow(unused)] fn zoom_out(&mut self, cx: &mut ViewContext) { for pane in &self.panes { pane.update(cx, |pane, cx| pane.set_zoomed(false, cx)); @@ -2574,7 +2567,7 @@ impl Workspace { // } // } - fn render_notifications(&self, cx: &ViewContext) -> Option
{ + fn render_notifications(&self, _cx: &ViewContext) -> Option
{ if self.notifications.is_empty() { None } else { @@ -3005,6 +2998,7 @@ impl Workspace { cx.notify(); } + #[allow(unused)] fn schedule_serialize(&mut self, cx: &mut ViewContext) { self._schedule_serialize = Some(cx.spawn(|this, mut cx| async move { cx.background_executor() @@ -3143,12 +3137,7 @@ impl Workspace { cx: &mut ViewContext, ) -> Task>>>> { cx.spawn(|workspace, mut cx| async move { - let (project, old_center_pane) = workspace.update(&mut cx, |workspace, _| { - ( - workspace.project().clone(), - workspace.last_active_center_pane.clone(), - ) - })?; + let project = workspace.update(&mut cx, |workspace, _| workspace.project().clone())?; let mut center_group = None; let mut center_items = None; @@ -3293,7 +3282,7 @@ impl Workspace { .on_action(cx.listener(|workspace, action: &SwapPaneInDirection, cx| { workspace.swap_pane_in_direction(action.0, cx) })) - .on_action(cx.listener(|this, e: &ToggleLeftDock, cx| { + .on_action(cx.listener(|this, _: &ToggleLeftDock, cx| { this.toggle_dock(DockPosition::Left, cx); })) .on_action( @@ -3418,7 +3407,7 @@ impl Workspace { self } - fn add_workspace_actions_listeners(&self, mut div: Div, cx: &mut ViewContext) -> Div { + fn add_workspace_actions_listeners(&self, div: Div, cx: &mut ViewContext) -> Div { let mut div = div .on_action(cx.listener(Self::close_inactive_items_and_panes)) .on_action(cx.listener(Self::close_all_items_and_panes)) @@ -3578,8 +3567,6 @@ impl FocusableView for Workspace { } } -struct WorkspaceBounds(Bounds); - #[derive(Clone, Render)] struct DraggedDock(DockPosition); @@ -3628,7 +3615,7 @@ impl Render for Workspace { .border_b() .border_color(cx.theme().colors().border) .child( - canvas(cx.listener(|workspace, bounds, cx| { + canvas(cx.listener(|workspace, bounds, _| { workspace.bounds = *bounds; })) .absolute() @@ -4056,7 +4043,7 @@ async fn join_channel_internal( active_call: &Model, cx: &mut AsyncAppContext, ) -> Result { - let (should_prompt, open_room) = active_call.read_with(cx, |active_call, cx| { + let (should_prompt, open_room) = active_call.update(cx, |active_call, cx| { let Some(room) = active_call.room().map(|room| room.read(cx)) else { return (false, None); }; @@ -4421,7 +4408,7 @@ pub fn restart(_: &Restart, cx: &mut AppContext) { } cx.spawn(|mut cx| async move { - if let Some(mut prompt) = prompt { + if let Some(prompt) = prompt { let answer = prompt.await?; if answer != 0 { return Ok(()); @@ -4460,6 +4447,8 @@ fn parse_pixel_size_env_var(value: &str) -> Option> { #[cfg(test)] mod tests { + use std::{cell::RefCell, rc::Rc}; + use super::*; use crate::item::{ test::{TestItem, TestProjectItem}, @@ -4470,7 +4459,6 @@ mod tests { use project::{Project, ProjectEntryId}; use serde_json::json; use settings::SettingsStore; - use std::{cell::RefCell, rc::Rc}; #[gpui::test] async fn test_tab_disambiguation(cx: &mut TestAppContext) { @@ -4544,7 +4532,7 @@ mod tests { let project = Project::test(fs, ["root1".as_ref()], cx).await; let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx)); let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); - let worktree_id = project.read_with(cx, |project, cx| { + let worktree_id = project.update(cx, |project, cx| { project.worktrees().next().unwrap().read(cx).id() }); @@ -4557,7 +4545,7 @@ mod tests { // Add an item to an empty pane workspace.update(cx, |workspace, cx| workspace.add_item(Box::new(item1), cx)); - project.read_with(cx, |project, cx| { + project.update(cx, |project, cx| { assert_eq!( project.active_entry(), project @@ -4570,7 +4558,7 @@ mod tests { // Add a second item to a non-empty pane workspace.update(cx, |workspace, cx| workspace.add_item(Box::new(item2), cx)); assert_eq!(cx.window_title().as_deref(), Some("two.txt — root1")); - project.read_with(cx, |project, cx| { + project.update(cx, |project, cx| { assert_eq!( project.active_entry(), project @@ -4586,7 +4574,7 @@ mod tests { .await .unwrap(); assert_eq!(cx.window_title().as_deref(), Some("one.txt — root1")); - project.read_with(cx, |project, cx| { + project.update(cx, |project, cx| { assert_eq!( project.active_entry(), project @@ -4970,14 +4958,14 @@ mod tests { item.is_dirty = true; cx.blur(); }); - cx.executor().run_until_parked(); + cx.run_until_parked(); item.update(cx, |item, _| assert_eq!(item.save_count, 5)); // Ensure autosave is prevented for deleted files also when closing the buffer. let _close_items = pane.update(cx, |pane, cx| { pane.close_items(cx, SaveIntent::Close, move |id| id == item_id) }); - cx.executor().run_until_parked(); + cx.run_until_parked(); assert!(cx.has_pending_prompt()); item.update(cx, |item, _| assert_eq!(item.save_count, 5)); } @@ -5036,363 +5024,362 @@ mod tests { }); } - // #[gpui::test] - // async fn test_toggle_docks_and_panels(cx: &mut gpui::TestAppContext) { - // init_test(cx); - // let fs = FakeFs::new(cx.executor()); + // #[gpui::test] + // async fn test_toggle_docks_and_panels(cx: &mut gpui::TestAppContext) { + // init_test(cx); + // let fs = FakeFs::new(cx.executor()); - // let project = Project::test(fs, [], cx).await; - // let window = cx.add_window(|cx| Workspace::test_new(project, cx)); - // let workspace = window.root(cx); + // let project = Project::test(fs, [], cx).await; + // let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx)); - // let panel = workspace.update(cx, |workspace, cx| { - // let panel = cx.build_view(|_| TestPanel::new(DockPosition::Right)); - // workspace.add_panel(panel.clone(), cx); + // let panel = workspace.update(cx, |workspace, cx| { + // let panel = cx.build_view(|cx| TestPanel::new(DockPosition::Right, cx)); + // workspace.add_panel(panel.clone(), cx); + // workspace + // .right_dock() + // .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); + + // panel + // }); + + // let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); + // pane.update(cx, |pane, cx| { + // let item = cx.build_view(|cx| TestItem::new(cx)); + // pane.add_item(Box::new(item), true, true, None, cx); + // }); + + // // Transfer focus from center to panel + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_panel_focus::(cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + // assert!(panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Transfer focus from panel to center + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_panel_focus::(cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + // assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Close the dock + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(!workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + // assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Open the dock + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(!panel.is_zoomed(cx)); + // assert!(panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Focus and zoom panel + // panel.update(cx, |panel, cx| { + // cx.focus_self(); + // panel.set_zoomed(true, cx) + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(panel.is_zoomed(cx)); + // assert!(panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Transfer focus to the center closes the dock + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_panel_focus::(cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(!workspace.right_dock().read(cx).is_open()); + // assert!(panel.is_zoomed(cx)); + // assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Transferring focus back to the panel keeps it zoomed + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_panel_focus::(cx); + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(panel.is_zoomed(cx)); + // assert!(panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Close the dock while it is zoomed + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx) + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(!workspace.right_dock().read(cx).is_open()); + // assert!(panel.is_zoomed(cx)); + // assert!(workspace.zoomed.is_none()); + // assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Opening the dock, when it's zoomed, retains focus + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx) + // }); + + // workspace.update(cx, |workspace, cx| { + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(panel.is_zoomed(cx)); + // assert!(workspace.zoomed.is_some()); + // assert!(panel.read(cx).focus_handle(cx).contains_focused(cx)); + // }); + + // // Unzoom and close the panel, zoom the active pane. + // panel.update(cx, |panel, cx| panel.set_zoomed(false, cx)); + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx) + // }); + // pane.update(cx, |pane, cx| pane.toggle_zoom(&Default::default(), cx)); + + // // Opening a dock unzooms the pane. + // workspace.update(cx, |workspace, cx| { + // workspace.toggle_dock(DockPosition::Right, cx) + // }); + // workspace.update(cx, |workspace, cx| { + // let pane = pane.read(cx); + // assert!(!pane.is_zoomed()); + // assert!(!pane.focus_handle(cx).is_focused(cx)); + // assert!(workspace.right_dock().read(cx).is_open()); + // assert!(workspace.zoomed.is_none()); + // }); + // } + + // #[gpui::test] + // async fn test_panels(cx: &mut gpui::TestAppContext) { + // init_test(cx); + // let fs = FakeFs::new(cx.executor()); + + // let project = Project::test(fs, [], cx).await; + // let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx)); + + // let (panel_1, panel_2) = workspace.update(cx, |workspace, cx| { + // // Add panel_1 on the left, panel_2 on the right. + // let panel_1 = cx.build_view(|cx| TestPanel::new(DockPosition::Left, cx)); + // workspace.add_panel(panel_1.clone(), cx); + // workspace + // .left_dock() + // .update(cx, |left_dock, cx| left_dock.set_open(true, cx)); + // let panel_2 = cx.build_view(|cx| TestPanel::new(DockPosition::Right, cx)); + // workspace.add_panel(panel_2.clone(), cx); + // workspace + // .right_dock() + // .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); + + // let left_dock = workspace.left_dock(); + // assert_eq!( + // left_dock.read(cx).visible_panel().unwrap().panel_id(), + // panel_1.panel_id() + // ); + // assert_eq!( + // left_dock.read(cx).active_panel_size(cx).unwrap(), + // panel_1.size(cx) + // ); + + // left_dock.update(cx, |left_dock, cx| { + // left_dock.resize_active_panel(Some(1337.), cx) + // }); + // assert_eq!( // workspace // .right_dock() - // .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); + // .read(cx) + // .visible_panel() + // .unwrap() + // .panel_id(), + // panel_2.panel_id(), + // ); - // panel - // }); + // (panel_1, panel_2) + // }); - // let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone()); - // pane.update(cx, |pane, cx| { - // let item = cx.build_view(|_| TestItem::new(cx)); - // pane.add_item(Box::new(item), true, true, None, cx); - // }); + // // Move panel_1 to the right + // panel_1.update(cx, |panel_1, cx| { + // panel_1.set_position(DockPosition::Right, cx) + // }); - // // Transfer focus from center to panel - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); + // workspace.update(cx, |workspace, cx| { + // // Since panel_1 was visible on the left, it should now be visible now that it's been moved to the right. + // // Since it was the only panel on the left, the left dock should now be closed. + // assert!(!workspace.left_dock().read(cx).is_open()); + // assert!(workspace.left_dock().read(cx).visible_panel().is_none()); + // let right_dock = workspace.right_dock(); + // assert_eq!( + // right_dock.read(cx).visible_panel().unwrap().panel_id(), + // panel_1.panel_id() + // ); + // assert_eq!(right_dock.read(cx).active_panel_size(cx).unwrap(), 1337.); - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); + // // Now we move panel_2 to the left + // panel_2.set_position(DockPosition::Left, cx); + // }); - // // Transfer focus from panel to center - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(!panel.has_focus(cx)); - // }); - - // // Close the dock - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(!workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(!panel.has_focus(cx)); - // }); - - // // Open the dock - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(!panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); - - // // Focus and zoom panel - // panel.update(cx, |panel, cx| { - // cx.focus_self(); - // panel.set_zoomed(true, cx) - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); - - // // Transfer focus to the center closes the dock - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(!workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(!panel.has_focus(cx)); - // }); - - // // Transferring focus back to the panel keeps it zoomed - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_panel_focus::(cx); - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(panel.has_focus(cx)); - // }); - - // // Close the dock while it is zoomed - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(!workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(workspace.zoomed.is_none()); - // assert!(!panel.has_focus(cx)); - // }); - - // // Opening the dock, when it's zoomed, retains focus - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); - - // workspace.update(cx, |workspace, cx| { - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(panel.is_zoomed(cx)); - // assert!(workspace.zoomed.is_some()); - // assert!(panel.has_focus(cx)); - // }); - - // // Unzoom and close the panel, zoom the active pane. - // panel.update(cx, |panel, cx| panel.set_zoomed(false, cx)); - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); - // pane.update(cx, |pane, cx| pane.toggle_zoom(&Default::default(), cx)); - - // // Opening a dock unzooms the pane. - // workspace.update(cx, |workspace, cx| { - // workspace.toggle_dock(DockPosition::Right, cx) - // }); - // workspace.update(cx, |workspace, cx| { - // let pane = pane.read(cx); - // assert!(!pane.is_zoomed()); - // assert!(!pane.has_focus()); - // assert!(workspace.right_dock().read(cx).is_open()); - // assert!(workspace.zoomed.is_none()); - // }); - // } - - // #[gpui::test] - // async fn test_panels(cx: &mut gpui::TestAppContext) { - // init_test(cx); - // let fs = FakeFs::new(cx.executor()); - - // let project = Project::test(fs, [], cx).await; - // let window = cx.add_window(|cx| Workspace::test_new(project, cx)); - // let workspace = window.root(cx); - - // let (panel_1, panel_2) = workspace.update(cx, |workspace, cx| { - // // Add panel_1 on the left, panel_2 on the right. - // let panel_1 = cx.build_view(|_| TestPanel::new(DockPosition::Left)); - // workspace.add_panel(panel_1.clone(), cx); - // workspace - // .left_dock() - // .update(cx, |left_dock, cx| left_dock.set_open(true, cx)); - // let panel_2 = cx.build_view(|_| TestPanel::new(DockPosition::Right)); - // workspace.add_panel(panel_2.clone(), cx); + // workspace.update(cx, |workspace, cx| { + // // Since panel_2 was not visible on the right, we don't open the left dock. + // assert!(!workspace.left_dock().read(cx).is_open()); + // // And the right dock is unaffected in it's displaying of panel_1 + // assert!(workspace.right_dock().read(cx).is_open()); + // assert_eq!( // workspace // .right_dock() - // .update(cx, |right_dock, cx| right_dock.set_open(true, cx)); + // .read(cx) + // .visible_panel() + // .unwrap() + // .panel_id(), + // panel_1.panel_id(), + // ); + // }); - // let left_dock = workspace.left_dock(); - // assert_eq!( - // left_dock.read(cx).visible_panel().unwrap().id(), - // panel_1.id() - // ); - // assert_eq!( - // left_dock.read(cx).active_panel_size(cx).unwrap(), - // panel_1.size(cx) - // ); + // // Move panel_1 back to the left + // panel_1.update(cx, |panel_1, cx| { + // panel_1.set_position(DockPosition::Left, cx) + // }); - // left_dock.update(cx, |left_dock, cx| { - // left_dock.resize_active_panel(Some(1337.), cx) - // }); - // assert_eq!( - // workspace - // .right_dock() - // .read(cx) - // .visible_panel() - // .unwrap() - // .id(), - // panel_2.id() - // ); + // workspace.update(cx, |workspace, cx| { + // // Since panel_1 was visible on the right, we open the left dock and make panel_1 active. + // let left_dock = workspace.left_dock(); + // assert!(left_dock.read(cx).is_open()); + // assert_eq!( + // left_dock.read(cx).visible_panel().unwrap().panel_id(), + // panel_1.panel_id() + // ); + // assert_eq!(left_dock.read(cx).active_panel_size(cx).unwrap(), 1337.); + // // And right the dock should be closed as it no longer has any panels. + // assert!(!workspace.right_dock().read(cx).is_open()); - // (panel_1, panel_2) - // }); + // // Now we move panel_1 to the bottom + // panel_1.set_position(DockPosition::Bottom, cx); + // }); - // // Move panel_1 to the right - // panel_1.update(cx, |panel_1, cx| { - // panel_1.set_position(DockPosition::Right, cx) - // }); + // workspace.update(cx, |workspace, cx| { + // // Since panel_1 was visible on the left, we close the left dock. + // assert!(!workspace.left_dock().read(cx).is_open()); + // // The bottom dock is sized based on the panel's default size, + // // since the panel orientation changed from vertical to horizontal. + // let bottom_dock = workspace.bottom_dock(); + // assert_eq!( + // bottom_dock.read(cx).active_panel_size(cx).unwrap(), + // panel_1.size(cx), + // ); + // // Close bottom dock and move panel_1 back to the left. + // bottom_dock.update(cx, |bottom_dock, cx| bottom_dock.set_open(false, cx)); + // panel_1.set_position(DockPosition::Left, cx); + // }); - // workspace.update(cx, |workspace, cx| { - // // Since panel_1 was visible on the left, it should now be visible now that it's been moved to the right. - // // Since it was the only panel on the left, the left dock should now be closed. - // assert!(!workspace.left_dock().read(cx).is_open()); - // assert!(workspace.left_dock().read(cx).visible_panel().is_none()); - // let right_dock = workspace.right_dock(); - // assert_eq!( - // right_dock.read(cx).visible_panel().unwrap().id(), - // panel_1.id() - // ); - // assert_eq!(right_dock.read(cx).active_panel_size(cx).unwrap(), 1337.); + // // Emit activated event on panel 1 + // panel_1.update(cx, |_, cx| cx.emit(PanelEvent::Activate)); - // // Now we move panel_2 to the left - // panel_2.set_position(DockPosition::Left, cx); - // }); + // // Now the left dock is open and panel_1 is active and focused. + // workspace.update(cx, |workspace, cx| { + // let left_dock = workspace.left_dock(); + // assert!(left_dock.read(cx).is_open()); + // assert_eq!( + // left_dock.read(cx).visible_panel().unwrap().panel_id(), + // panel_1.panel_id(), + // ); + // assert!(panel_1.focus_handle(cx).is_focused(cx)); + // }); - // workspace.update(cx, |workspace, cx| { - // // Since panel_2 was not visible on the right, we don't open the left dock. - // assert!(!workspace.left_dock().read(cx).is_open()); - // // And the right dock is unaffected in it's displaying of panel_1 - // assert!(workspace.right_dock().read(cx).is_open()); - // assert_eq!( - // workspace - // .right_dock() - // .read(cx) - // .visible_panel() - // .unwrap() - // .id(), - // panel_1.id() - // ); - // }); + // // Emit closed event on panel 2, which is not active + // panel_2.update(cx, |_, cx| cx.emit(PanelEvent::Close)); - // // Move panel_1 back to the left - // panel_1.update(cx, |panel_1, cx| { - // panel_1.set_position(DockPosition::Left, cx) - // }); + // // Wo don't close the left dock, because panel_2 wasn't the active panel + // workspace.update(cx, |workspace, cx| { + // let left_dock = workspace.left_dock(); + // assert!(left_dock.read(cx).is_open()); + // assert_eq!( + // left_dock.read(cx).visible_panel().unwrap().panel_id(), + // panel_1.panel_id(), + // ); + // }); - // workspace.update(cx, |workspace, cx| { - // // Since panel_1 was visible on the right, we open the left dock and make panel_1 active. - // let left_dock = workspace.left_dock(); - // assert!(left_dock.read(cx).is_open()); - // assert_eq!( - // left_dock.read(cx).visible_panel().unwrap().id(), - // panel_1.id() - // ); - // assert_eq!(left_dock.read(cx).active_panel_size(cx).unwrap(), 1337.); - // // And right the dock should be closed as it no longer has any panels. - // assert!(!workspace.right_dock().read(cx).is_open()); + // // Emitting a ZoomIn event shows the panel as zoomed. + // panel_1.update(cx, |_, cx| cx.emit(PanelEvent::ZoomIn)); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade())); + // assert_eq!(workspace.zoomed_position, Some(DockPosition::Left)); + // }); - // // Now we move panel_1 to the bottom - // panel_1.set_position(DockPosition::Bottom, cx); - // }); + // // Move panel to another dock while it is zoomed + // panel_1.update(cx, |panel, cx| panel.set_position(DockPosition::Right, cx)); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade())); - // workspace.update(cx, |workspace, cx| { - // // Since panel_1 was visible on the left, we close the left dock. - // assert!(!workspace.left_dock().read(cx).is_open()); - // // The bottom dock is sized based on the panel's default size, - // // since the panel orientation changed from vertical to horizontal. - // let bottom_dock = workspace.bottom_dock(); - // assert_eq!( - // bottom_dock.read(cx).active_panel_size(cx).unwrap(), - // panel_1.size(cx), - // ); - // // Close bottom dock and move panel_1 back to the left. - // bottom_dock.update(cx, |bottom_dock, cx| bottom_dock.set_open(false, cx)); - // panel_1.set_position(DockPosition::Left, cx); - // }); + // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); + // }); - // // Emit activated event on panel 1 - // panel_1.update(cx, |_, cx| cx.emit(TestPanelEvent::Activated)); + // // If focus is transferred to another view that's not a panel or another pane, we still show + // // the panel as zoomed. + // let other_focus_handle = cx.update(|cx| cx.focus_handle()); + // cx.update(|cx| cx.focus(&other_focus_handle)); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade())); + // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); + // }); - // // Now the left dock is open and panel_1 is active and focused. - // workspace.update(cx, |workspace, cx| { - // let left_dock = workspace.left_dock(); - // assert!(left_dock.read(cx).is_open()); - // assert_eq!( - // left_dock.read(cx).visible_panel().unwrap().id(), - // panel_1.id() - // ); - // assert!(panel_1.is_focused(cx)); - // }); + // // If focus is transferred elsewhere in the workspace, the panel is no longer zoomed. + // workspace.update(cx, |_, cx| cx.focus_self()); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, None); + // assert_eq!(workspace.zoomed_position, None); + // }); - // // Emit closed event on panel 2, which is not active - // panel_2.update(cx, |_, cx| cx.emit(TestPanelEvent::Closed)); + // // If focus is transferred again to another view that's not a panel or a pane, we won't + // // show the panel as zoomed because it wasn't zoomed before. + // cx.update(|cx| cx.focus(&other_focus_handle)); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, None); + // assert_eq!(workspace.zoomed_position, None); + // }); - // // Wo don't close the left dock, because panel_2 wasn't the active panel - // workspace.update(cx, |workspace, cx| { - // let left_dock = workspace.left_dock(); - // assert!(left_dock.read(cx).is_open()); - // assert_eq!( - // left_dock.read(cx).visible_panel().unwrap().id(), - // panel_1.id() - // ); - // }); + // // When focus is transferred back to the panel, it is zoomed again. + // panel_1.update(cx, |_, cx| cx.focus_self()); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade())); + // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); + // }); - // // Emitting a ZoomIn event shows the panel as zoomed. - // panel_1.update(cx, |_, cx| cx.emit(TestPanelEvent::ZoomIn)); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any())); - // assert_eq!(workspace.zoomed_position, Some(DockPosition::Left)); - // }); + // // Emitting a ZoomOut event unzooms the panel. + // panel_1.update(cx, |_, cx| cx.emit(PanelEvent::ZoomOut)); + // workspace.update(cx, |workspace, _| { + // assert_eq!(workspace.zoomed, None); + // assert_eq!(workspace.zoomed_position, None); + // }); - // // Move panel to another dock while it is zoomed - // panel_1.update(cx, |panel, cx| panel.set_position(DockPosition::Right, cx)); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any())); - // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); - // }); + // // Emit closed event on panel 1, which is active + // panel_1.update(cx, |_, cx| cx.emit(PanelEvent::Close)); - // // If focus is transferred to another view that's not a panel or another pane, we still show - // // the panel as zoomed. - // let focus_receiver = cx.build_view(|_| EmptyView); - // focus_receiver.update(cx, |_, cx| cx.focus_self()); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any())); - // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); - // }); - - // // If focus is transferred elsewhere in the workspace, the panel is no longer zoomed. - // workspace.update(cx, |_, cx| cx.focus_self()); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, None); - // assert_eq!(workspace.zoomed_position, None); - // }); - - // // If focus is transferred again to another view that's not a panel or a pane, we won't - // // show the panel as zoomed because it wasn't zoomed before. - // focus_receiver.update(cx, |_, cx| cx.focus_self()); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, None); - // assert_eq!(workspace.zoomed_position, None); - // }); - - // // When focus is transferred back to the panel, it is zoomed again. - // panel_1.update(cx, |_, cx| cx.focus_self()); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, Some(panel_1.downgrade().into_any())); - // assert_eq!(workspace.zoomed_position, Some(DockPosition::Right)); - // }); - - // // Emitting a ZoomOut event unzooms the panel. - // panel_1.update(cx, |_, cx| cx.emit(TestPanelEvent::ZoomOut)); - // workspace.update(cx, |workspace, _| { - // assert_eq!(workspace.zoomed, None); - // assert_eq!(workspace.zoomed_position, None); - // }); - - // // Emit closed event on panel 1, which is active - // panel_1.update(cx, |_, cx| cx.emit(TestPanelEvent::Closed)); - - // // Now the left dock is closed, because panel_1 was the active panel - // workspace.update(cx, |workspace, cx| { - // let right_dock = workspace.right_dock(); - // assert!(!right_dock.read(cx).is_open()); - // }); - // } + // // Now the left dock is closed, because panel_1 was the active panel + // workspace.update(cx, |workspace, cx| { + // let right_dock = workspace.right_dock(); + // assert!(!right_dock.read(cx).is_open()); + // }); + // } pub fn init_test(cx: &mut TestAppContext) { cx.update(|cx| {