diff --git a/crates/gpui2/src/app/async_context.rs b/crates/gpui2/src/app/async_context.rs index c5c03c4e9a..3a9a68a033 100644 --- a/crates/gpui2/src/app/async_context.rs +++ b/crates/gpui2/src/app/async_context.rs @@ -259,7 +259,7 @@ impl Context for AsyncWindowContext { } impl VisualContext for AsyncWindowContext { - type ViewContext<'a, 'w, V> = ViewContext<'a, 'w, V>; + type ViewContext<'a, 'w, V: 'static> = ViewContext<'a, 'w, V>; fn build_view( &mut self, diff --git a/crates/gpui2/src/gpui2.rs b/crates/gpui2/src/gpui2.rs index 8625866a44..74d87449b9 100644 --- a/crates/gpui2/src/gpui2.rs +++ b/crates/gpui2/src/gpui2.rs @@ -95,7 +95,7 @@ pub trait Context { } pub trait VisualContext: Context { - type ViewContext<'a, 'w, V>; + type ViewContext<'a, 'w, V: 'static>; fn build_view( &mut self, @@ -184,7 +184,7 @@ impl Context for MainThread { } impl VisualContext for MainThread { - type ViewContext<'a, 'w, V> = MainThread>; + type ViewContext<'a, 'w, V: 'static> = MainThread>; fn build_view( &mut self, diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 2cdd933ae5..bd62ff44f7 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -7,7 +7,7 @@ use crate::{ MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, Subscription, - TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext, WeakModel, WeakView, + TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext, WeakView, WindowOptions, SUBPIXEL_VARIANTS, }; use anyhow::Result; @@ -1305,7 +1305,7 @@ impl Context for WindowContext<'_, '_> { } impl VisualContext for WindowContext<'_, '_> { - type ViewContext<'a, 'w, V> = ViewContext<'a, 'w, V>; + type ViewContext<'a, 'w, V: 'static> = ViewContext<'a, 'w, V>; fn build_view( &mut self, @@ -1318,7 +1318,7 @@ impl VisualContext for WindowContext<'_, '_> { let view = View { model: slot.clone(), }; - let mut cx = ViewContext::mutable(&mut *self.app, &mut *self.window, view.downgrade()); + let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view); let entity = build_view_state(&mut cx); self.entities.insert(slot, entity); view @@ -1331,7 +1331,7 @@ impl VisualContext for WindowContext<'_, '_> { update: impl FnOnce(&mut T, &mut Self::ViewContext<'_, '_, T>) -> R, ) -> Self::Result { let mut lease = self.app.entities.lease(&view.model); - let mut cx = ViewContext::mutable(&mut *self.app, &mut *self.window, view.downgrade()); + let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view); let result = update(&mut *lease, &mut cx); cx.app.entities.end_lease(lease); result @@ -1542,7 +1542,7 @@ impl BorrowWindow for T where T: BorrowMut + BorrowMut {} pub struct ViewContext<'a, 'w, V> { window_cx: WindowContext<'a, 'w>, - view: WeakView, + view: &'w View, } impl Borrow for ViewContext<'_, '_, V> { @@ -1570,22 +1570,18 @@ impl BorrowMut for ViewContext<'_, '_, V> { } impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { - pub(crate) fn mutable( - app: &'a mut AppContext, - window: &'w mut Window, - view: WeakView, - ) -> Self { + pub(crate) fn new(app: &'a mut AppContext, window: &'w mut Window, view: &'w View) -> Self { Self { window_cx: WindowContext::mutable(app, window), view, } } - pub fn view(&self) -> WeakView { + pub fn view(&self) -> View { self.view.clone() } - pub fn model(&self) -> WeakModel { + pub fn model(&self) -> Model { self.view.model.clone() } @@ -1600,14 +1596,14 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { where V: Any + Send, { - let view = self.view().upgrade().unwrap(); + let view = self.view(); self.window_cx.on_next_frame(move |cx| view.update(cx, f)); } /// Schedules the given function to be run at the end of the current effect cycle, allowing entities /// that are currently on the stack to be returned to the app. pub fn defer(&mut self, f: impl FnOnce(&mut V, &mut ViewContext) + 'static + Send) { - let view = self.view(); + let view = self.view().downgrade(); self.window_cx.defer(move |cx| { view.update(cx, f).ok(); }); @@ -1623,7 +1619,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { V: 'static + Send, E: Entity, { - let view = self.view(); + let view = self.view().downgrade(); let entity_id = entity.entity_id(); let entity = entity.downgrade(); let window_handle = self.window.handle; @@ -1652,7 +1648,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { V2: EventEmitter, E: Entity, { - let view = self.view(); + let view = self.view().downgrade(); let entity_id = entity.entity_id(); let handle = entity.downgrade(); let window_handle = self.window.handle; @@ -1698,7 +1694,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { V2: 'static, E: Entity, { - let view = self.view(); + let view = self.view().downgrade(); let entity_id = entity.entity_id(); let window_handle = self.window.handle; self.app.release_listeners.insert( @@ -1723,7 +1719,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { &mut self, listener: impl Fn(&mut V, &FocusEvent, &mut ViewContext) + Send + 'static, ) { - let handle = self.view(); + let handle = self.view().downgrade(); self.window.focus_listeners.push(Box::new(move |event, cx| { handle .update(cx, |view, cx| listener(view, event, cx)) @@ -1739,7 +1735,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { let old_stack_len = self.window.key_dispatch_stack.len(); if !self.window.freeze_key_dispatch_stack { for (event_type, listener) in key_listeners { - let handle = self.view(); + let handle = self.view().downgrade(); let listener = Box::new( move |event: &dyn Any, context_stack: &[&DispatchContext], @@ -1829,7 +1825,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { let cx = unsafe { mem::transmute::<&mut Self, &mut MainThread>(self) }; Task::ready(Ok(f(view, cx))) } else { - let view = self.view().upgrade().unwrap(); + let view = self.view(); self.window_cx.run_on_main(move |cx| view.update(cx, f)) } } @@ -1842,7 +1838,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { R: Send + 'static, Fut: Future + Send + 'static, { - let view = self.view(); + let view = self.view().downgrade(); self.window_cx.spawn(move |_, cx| { let result = f(view, cx); async move { result.await } @@ -1864,12 +1860,12 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { f: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) + Send + 'static, ) -> Subscription { let window_handle = self.window.handle; - let handle = self.view(); + let view = self.view().downgrade(); self.global_observers.insert( TypeId::of::(), Box::new(move |cx| { cx.update_window(window_handle, |cx| { - handle.update(cx, |view, cx| f(view, cx)).is_ok() + view.update(cx, |view, cx| f(view, cx)).is_ok() }) .unwrap_or(false) }), @@ -1880,7 +1876,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> { &mut self, handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext) + Send + 'static, ) { - let handle = self.view().upgrade().unwrap(); + let handle = self.view(); self.window_cx.on_mouse_event(move |event, phase, cx| { handle.update(cx, |view, cx| { handler(view, event, phase, cx); @@ -1937,7 +1933,7 @@ impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> { } impl VisualContext for ViewContext<'_, '_, V> { - type ViewContext<'a, 'w, V2> = ViewContext<'a, 'w, V2>; + type ViewContext<'a, 'w, V2: 'static> = ViewContext<'a, 'w, V2>; fn build_view( &mut self, diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index fc74139238..22c3833719 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -323,7 +323,7 @@ impl Pane { // menu.set_position_mode(OverlayPositionMode::Local) // }); - let handle = cx.view(); + let handle = cx.view().downgrade(); Self { items: Vec::new(), activation_history: Vec::new(), diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index e7745dc763..3b009f4233 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -416,8 +416,12 @@ pub struct AppState { pub fs: Arc, pub build_window_options: fn(Option, Option, MainThread) -> WindowOptions, - pub initialize_workspace: - fn(WeakModel, bool, Arc, AsyncAppContext) -> Task>, + pub initialize_workspace: fn( + WeakView, + bool, + Arc, + AsyncWindowContext, + ) -> Task>, pub node_runtime: Arc, } diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index 8b1d087687..c982a735c5 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -46,7 +46,7 @@ use util::{ }; use uuid::Uuid; use workspace2::{AppState, WorkspaceStore}; -use zed2::{build_window_options, languages}; +use zed2::{build_window_options, initialize_workspace, languages}; use zed2::{ensure_only_instance, Assets, IsOnlyInstance}; mod open_listener; @@ -172,7 +172,7 @@ fn main() { fs, build_window_options, initialize_workspace, - background_actions, + // background_actions: todo!("ask Mikayla"), workspace_store, node_runtime, }); diff --git a/crates/zed2/src/zed2.rs b/crates/zed2/src/zed2.rs index 478e3a20d2..194dbb9b25 100644 --- a/crates/zed2/src/zed2.rs +++ b/crates/zed2/src/zed2.rs @@ -6,8 +6,8 @@ mod open_listener; pub use assets::*; use collections::HashMap; use gpui2::{ - point, px, AppContext, AsyncAppContext, MainThread, Point, TitlebarOptions, WindowBounds, - WindowKind, WindowOptions, + point, px, AppContext, AsyncAppContext, AsyncWindowContext, MainThread, Point, Task, + TitlebarOptions, WeakView, WindowBounds, WindowKind, WindowOptions, }; pub use only_instance::*; pub use open_listener::*; @@ -24,7 +24,7 @@ use futures::{ use std::{path::Path, sync::Arc, thread, time::Duration}; use util::{paths::PathLikeWithPosition, ResultExt}; use uuid::Uuid; -use workspace2::AppState; +use workspace2::{AppState, Workspace}; pub fn connect_to_cli( server_name: &str, @@ -239,3 +239,162 @@ pub fn build_window_options( display_id: display.map(|display| display.id()), } } + +pub fn initialize_workspace( + workspace_handle: WeakView, + was_deserialized: bool, + app_state: Arc, + cx: AsyncWindowContext, +) -> Task> { + cx.spawn(|mut cx| async move { + workspace_handle.update(&mut cx, |workspace, cx| { + let workspace_handle = cx.view(); + cx.subscribe(&workspace_handle, { + move |workspace, _, event, cx| { + if let workspace2::Event::PaneAdded(pane) = event { + pane.update(cx, |pane, cx| { + // todo!() + // pane.toolbar().update(cx, |toolbar, cx| { + // let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(workspace)); + // toolbar.add_item(breadcrumbs, cx); + // let buffer_search_bar = cx.add_view(BufferSearchBar::new); + // toolbar.add_item(buffer_search_bar.clone(), cx); + // let quick_action_bar = cx.add_view(|_| { + // QuickActionBar::new(buffer_search_bar, workspace) + // }); + // toolbar.add_item(quick_action_bar, cx); + // let diagnostic_editor_controls = + // cx.add_view(|_| diagnostics2::ToolbarControls::new()); + // toolbar.add_item(diagnostic_editor_controls, cx); + // let project_search_bar = cx.add_view(|_| ProjectSearchBar::new()); + // toolbar.add_item(project_search_bar, cx); + // let submit_feedback_button = + // cx.add_view(|_| SubmitFeedbackButton::new()); + // toolbar.add_item(submit_feedback_button, cx); + // let feedback_info_text = cx.add_view(|_| FeedbackInfoText::new()); + // toolbar.add_item(feedback_info_text, cx); + // let lsp_log_item = + // cx.add_view(|_| language_tools::LspLogToolbarItemView::new()); + // toolbar.add_item(lsp_log_item, cx); + // let syntax_tree_item = cx + // .add_view(|_| language_tools::SyntaxTreeToolbarItemView::new()); + // toolbar.add_item(syntax_tree_item, cx); + // }) + }); + } + } + }) + .detach(); + + // cx.emit(workspace2::Event::PaneAdded( + // workspace.active_pane().clone(), + // )); + + // let collab_titlebar_item = + // cx.add_view(|cx| CollabTitlebarItem::new(workspace, &workspace_handle, cx)); + // workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx); + + // let copilot = + // cx.add_view(|cx| copilot_button::CopilotButton::new(app_state.fs.clone(), cx)); + // let diagnostic_summary = + // cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx)); + // let activity_indicator = activity_indicator::ActivityIndicator::new( + // workspace, + // app_state.languages.clone(), + // cx, + // ); + // let active_buffer_language = + // cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace)); + // let vim_mode_indicator = cx.add_view(|cx| vim::ModeIndicator::new(cx)); + // let feedback_button = cx.add_view(|_| { + // feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace) + // }); + // let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new()); + // workspace.status_bar().update(cx, |status_bar, cx| { + // status_bar.add_left_item(diagnostic_summary, cx); + // status_bar.add_left_item(activity_indicator, cx); + + // status_bar.add_right_item(feedback_button, cx); + // status_bar.add_right_item(copilot, cx); + // status_bar.add_right_item(active_buffer_language, cx); + // status_bar.add_right_item(vim_mode_indicator, cx); + // status_bar.add_right_item(cursor_position, cx); + // }); + + // auto_update::notify_of_any_new_update(cx.weak_handle(), cx); + + // vim::observe_keystrokes(cx); + + // cx.on_window_should_close(|workspace, cx| { + // if let Some(task) = workspace.close(&Default::default(), cx) { + // task.detach_and_log_err(cx); + // } + // false + // }); + // })?; + + // let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone()); + // let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone()); + // let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone()); + // let channels_panel = + // collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone()); + // let chat_panel = + // collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone()); + // let notification_panel = collab_ui::notification_panel::NotificationPanel::load( + // workspace_handle.clone(), + // cx.clone(), + // ); + // let ( + // project_panel, + // terminal_panel, + // assistant_panel, + // channels_panel, + // chat_panel, + // notification_panel, + // ) = futures::try_join!( + // project_panel, + // terminal_panel, + // assistant_panel, + // channels_panel, + // chat_panel, + // notification_panel, + // )?; + // workspace_handle.update(&mut cx, |workspace, cx| { + // let project_panel_position = project_panel.position(cx); + // workspace.add_panel_with_extra_event_handler( + // project_panel, + // cx, + // |workspace, _, event, cx| match event { + // project_panel::Event::NewSearchInDirectory { dir_entry } => { + // search::ProjectSearchView::new_search_in_directory(workspace, dir_entry, cx) + // } + // project_panel::Event::ActivatePanel => { + // workspace.focus_panel::(cx); + // } + // _ => {} + // }, + // ); + // workspace.add_panel(terminal_panel, cx); + // workspace.add_panel(assistant_panel, cx); + // workspace.add_panel(channels_panel, cx); + // workspace.add_panel(chat_panel, cx); + // workspace.add_panel(notification_panel, cx); + + // if !was_deserialized + // && workspace + // .project() + // .read(cx) + // .visible_worktrees(cx) + // .any(|tree| { + // tree.read(cx) + // .root_entry() + // .map_or(false, |entry| entry.is_dir()) + // }) + // { + // workspace.toggle_dock(project_panel_position, cx); + // } + // cx.focus_self(); + })?; + Ok(()) + }) +}