Make activate_workspace_for_project compile

Co-authored-by: Mikayla Maki <mikayla@zed.dev>
Co-Authored-By: Kirill Bulatov <kirill@zed.dev>
This commit is contained in:
Antonio Scandurra 2023-10-26 14:36:55 +02:00
parent c8b5b085f4
commit d9274416b4
8 changed files with 1331 additions and 1328 deletions

View file

@ -13,11 +13,12 @@ use smallvec::SmallVec;
pub use test_context::*;
use crate::{
current_platform, image_cache::ImageCache, Action, AnyBox, AnyView, AppMetadata, AssetSource,
ClipboardItem, Context, DispatchPhase, DisplayId, Executor, FocusEvent, FocusHandle, FocusId,
KeyBinding, Keymap, LayoutId, MainThread, MainThreadOnly, Pixels, Platform, Point,
SharedString, SubscriberSet, Subscription, SvgRenderer, Task, TextStyle, TextStyleRefinement,
TextSystem, View, Window, WindowContext, WindowHandle, WindowId,
current_platform, image_cache::ImageCache, Action, AnyBox, AnyView, AnyWindowHandle,
AppMetadata, AssetSource, ClipboardItem, Context, DispatchPhase, DisplayId, Executor,
FocusEvent, FocusHandle, FocusId, KeyBinding, Keymap, LayoutId, MainThread, MainThreadOnly,
Pixels, Platform, Point, SharedString, SubscriberSet, Subscription, SvgRenderer, Task,
TextStyle, TextStyleRefinement, TextSystem, View, Window, WindowContext, WindowHandle,
WindowId,
};
use anyhow::{anyhow, Result};
use collections::{HashMap, HashSet, VecDeque};
@ -249,14 +250,21 @@ impl AppContext {
result
}
pub fn windows(&self) -> Vec<AnyWindowHandle> {
self.windows
.values()
.filter_map(|window| Some(window.as_ref()?.handle.clone()))
.collect()
}
pub(crate) fn read_window<R>(
&mut self,
id: WindowId,
handle: AnyWindowHandle,
read: impl FnOnce(&WindowContext) -> R,
) -> Result<R> {
let window = self
.windows
.get(id)
.get(handle.id)
.ok_or_else(|| anyhow!("window not found"))?
.as_ref()
.unwrap();
@ -265,13 +273,13 @@ impl AppContext {
pub(crate) fn update_window<R>(
&mut self,
id: WindowId,
handle: AnyWindowHandle,
update: impl FnOnce(&mut WindowContext) -> R,
) -> Result<R> {
self.update(|cx| {
let mut window = cx
.windows
.get_mut(id)
.get_mut(handle.id)
.ok_or_else(|| anyhow!("window not found"))?
.take()
.unwrap();
@ -279,7 +287,7 @@ impl AppContext {
let result = update(&mut WindowContext::mutable(cx, &mut window));
cx.windows
.get_mut(id)
.get_mut(handle.id)
.ok_or_else(|| anyhow!("window not found"))?
.replace(window);
@ -315,8 +323,11 @@ impl AppContext {
self.apply_notify_effect(emitter);
}
Effect::Emit { emitter, event } => self.apply_emit_effect(emitter, event),
Effect::FocusChanged { window_id, focused } => {
self.apply_focus_changed_effect(window_id, focused);
Effect::FocusChanged {
window_handle,
focused,
} => {
self.apply_focus_changed_effect(window_handle, focused);
}
Effect::Refresh => {
self.apply_refresh_effect();
@ -336,18 +347,19 @@ impl AppContext {
let dirty_window_ids = self
.windows
.iter()
.filter_map(|(window_id, window)| {
.filter_map(|(_, window)| {
let window = window.as_ref().unwrap();
if window.dirty {
Some(window_id)
Some(window.handle.clone())
} else {
None
}
})
.collect::<SmallVec<[_; 8]>>();
for dirty_window_id in dirty_window_ids {
self.update_window(dirty_window_id, |cx| cx.draw()).unwrap();
for dirty_window_handle in dirty_window_ids {
self.update_window(dirty_window_handle, |cx| cx.draw())
.unwrap();
}
}
@ -369,9 +381,8 @@ impl AppContext {
}
fn release_dropped_focus_handles(&mut self) {
let window_ids = self.windows.keys().collect::<SmallVec<[_; 8]>>();
for window_id in window_ids {
self.update_window(window_id, |cx| {
for window_handle in self.windows() {
self.update_window(window_handle, |cx| {
let mut blur_window = false;
let focus = cx.window.focus;
cx.window.focus_handles.write().retain(|handle_id, count| {
@ -406,8 +417,12 @@ impl AppContext {
.retain(&emitter, |handler| handler(&event, self));
}
fn apply_focus_changed_effect(&mut self, window_id: WindowId, focused: Option<FocusId>) {
self.update_window(window_id, |cx| {
fn apply_focus_changed_effect(
&mut self,
window_handle: AnyWindowHandle,
focused: Option<FocusId>,
) {
self.update_window(window_handle, |cx| {
if cx.window.focus == focused {
let mut listeners = mem::take(&mut cx.window.focus_listeners);
let focused =
@ -752,12 +767,12 @@ impl MainThread<AppContext> {
})
}
pub(crate) fn update_window<R>(
pub fn update_window<R>(
&mut self,
id: WindowId,
handle: AnyWindowHandle,
update: impl FnOnce(&mut MainThread<WindowContext>) -> R,
) -> Result<R> {
self.0.update_window(id, |cx| {
self.0.update_window(handle, |cx| {
update(unsafe {
std::mem::transmute::<&mut WindowContext, &mut MainThread<WindowContext>>(cx)
})
@ -800,7 +815,7 @@ pub(crate) enum Effect {
event: Box<dyn Any + Send + Sync + 'static>,
},
FocusChanged {
window_id: WindowId,
window_handle: AnyWindowHandle,
focused: Option<FocusId>,
},
Refresh,

View file

@ -2,7 +2,7 @@ use crate::{
AnyWindowHandle, AppContext, Context, Executor, Handle, MainThread, ModelContext, Result, Task,
ViewContext, WindowContext,
};
use anyhow::anyhow;
use anyhow::Context as _;
use derive_more::{Deref, DerefMut};
use parking_lot::Mutex;
use std::{any::Any, future::Future, sync::Weak};
@ -24,10 +24,7 @@ impl Context for AsyncAppContext {
where
T: Any + Send + Sync,
{
let app = self
.app
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let app = self.app.upgrade().context("app was released")?;
let mut lock = app.lock(); // Need this to compile
Ok(lock.entity(build_entity))
}
@ -37,10 +34,7 @@ impl Context for AsyncAppContext {
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
) -> Self::Result<R> {
let app = self
.app
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let app = self.app.upgrade().context("app was released")?;
let mut lock = app.lock(); // Need this to compile
Ok(lock.update_entity(handle, update))
}
@ -48,10 +42,7 @@ impl Context for AsyncAppContext {
impl AsyncAppContext {
pub fn refresh(&mut self) -> Result<()> {
let app = self
.app
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let app = self.app.upgrade().context("app was released")?;
let mut lock = app.lock(); // Need this to compile
lock.refresh();
Ok(())
@ -62,10 +53,7 @@ impl AsyncAppContext {
}
pub fn update<R>(&self, f: impl FnOnce(&mut AppContext) -> R) -> Result<R> {
let app = self
.app
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let app = self.app.upgrade().context("app was released")?;
let mut lock = app.lock();
Ok(f(&mut *lock))
}
@ -75,12 +63,9 @@ impl AsyncAppContext {
handle: AnyWindowHandle,
update: impl FnOnce(&WindowContext) -> R,
) -> Result<R> {
let app = self
.app
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let app = self.app.upgrade().context("app was released")?;
let mut app_context = app.lock();
app_context.read_window(handle.id, update)
app_context.read_window(handle, update)
}
pub fn update_window<R>(
@ -88,12 +73,9 @@ impl AsyncAppContext {
handle: AnyWindowHandle,
update: impl FnOnce(&mut WindowContext) -> R,
) -> Result<R> {
let app = self
.app
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let app = self.app.upgrade().context("app was released")?;
let mut app_context = app.lock();
app_context.update_window(handle.id, update)
app_context.update_window(handle, update)
}
pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut + Send + 'static) -> Task<R>
@ -124,28 +106,19 @@ impl AsyncAppContext {
where
R: Send + 'static,
{
let app = self
.app
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let app = self.app.upgrade().context("app was released")?;
let mut app_context = app.lock();
Ok(app_context.run_on_main(f))
}
pub fn has_global<G: 'static>(&self) -> Result<bool> {
let app = self
.app
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let app = self.app.upgrade().context("app was released")?;
let lock = app.lock(); // Need this to compile
Ok(lock.has_global::<G>())
}
pub fn read_global<G: 'static, R>(&self, read: impl FnOnce(&G, &AppContext) -> R) -> Result<R> {
let app = self
.app
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let app = self.app.upgrade().context("app was released")?;
let lock = app.lock(); // Need this to compile
Ok(read(lock.global(), &lock))
}
@ -163,10 +136,7 @@ impl AsyncAppContext {
&mut self,
update: impl FnOnce(&mut G, &mut AppContext) -> R,
) -> Result<R> {
let app = self
.app
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let app = self.app.upgrade().context("app was released")?;
let mut lock = app.lock(); // Need this to compile
Ok(lock.update_global(update))
}

View file

@ -73,7 +73,7 @@ impl TestAppContext {
read: impl FnOnce(&WindowContext) -> R,
) -> R {
let mut app_context = self.app.lock();
app_context.read_window(handle.id, read).unwrap()
app_context.read_window(handle, read).unwrap()
}
pub fn update_window<R>(
@ -82,7 +82,7 @@ impl TestAppContext {
update: impl FnOnce(&mut WindowContext) -> R,
) -> R {
let mut app = self.app.lock();
app.update_window(handle.id, update).unwrap()
app.update_window(handle, update).unwrap()
}
pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut + Send + 'static) -> Task<R>

View file

@ -1,8 +1,8 @@
use parking_lot::Mutex;
use crate::{
AnyBox, AnyElement, BorrowWindow, Bounds, Element, ElementId, EntityId, Handle, IntoAnyElement,
LayoutId, Pixels, ViewContext, WindowContext,
AnyBox, AnyElement, AnyHandle, BorrowWindow, Bounds, Element, ElementId, Handle,
IntoAnyElement, LayoutId, Pixels, ViewContext, WindowContext,
};
use std::{marker::PhantomData, sync::Arc};
@ -54,7 +54,7 @@ impl<V: 'static> Element for View<V> {
type ViewState = ();
type ElementState = AnyElement<V>;
fn id(&self) -> Option<crate::ElementId> {
fn id(&self) -> Option<ElementId> {
Some(ElementId::View(self.state.entity_id))
}
@ -109,7 +109,7 @@ impl<V: 'static, ParentV: 'static> Element for EraseViewState<V, ParentV> {
type ViewState = ParentV;
type ElementState = AnyBox;
fn id(&self) -> Option<crate::ElementId> {
fn id(&self) -> Option<ElementId> {
Element::id(&self.view)
}
@ -143,19 +143,19 @@ impl<V: 'static, ParentV: 'static> Element for EraseViewState<V, ParentV> {
}
trait ViewObject: Send + Sync {
fn entity_id(&self) -> EntityId;
fn entity_handle(&self) -> &AnyHandle;
fn initialize(&mut self, cx: &mut WindowContext) -> AnyBox;
fn layout(&mut self, element: &mut AnyBox, cx: &mut WindowContext) -> LayoutId;
fn paint(&mut self, bounds: Bounds<Pixels>, element: &mut AnyBox, cx: &mut WindowContext);
}
impl<V: 'static> ViewObject for View<V> {
fn entity_id(&self) -> EntityId {
self.state.entity_id
fn entity_handle(&self) -> &AnyHandle {
&self.state
}
fn initialize(&mut self, cx: &mut WindowContext) -> AnyBox {
cx.with_element_id(self.entity_id(), |_global_id, cx| {
cx.with_element_id(self.state.entity_id, |_global_id, cx| {
self.state.update(cx, |state, cx| {
let mut any_element = Box::new((self.render)(state, cx));
any_element.initialize(state, cx);
@ -165,7 +165,7 @@ impl<V: 'static> ViewObject for View<V> {
}
fn layout(&mut self, element: &mut AnyBox, cx: &mut WindowContext) -> LayoutId {
cx.with_element_id(self.entity_id(), |_global_id, cx| {
cx.with_element_id(self.state.entity_id, |_global_id, cx| {
self.state.update(cx, |state, cx| {
let element = element.downcast_mut::<AnyElement<V>>().unwrap();
element.layout(state, cx)
@ -174,7 +174,7 @@ impl<V: 'static> ViewObject for View<V> {
}
fn paint(&mut self, _: Bounds<Pixels>, element: &mut AnyBox, cx: &mut WindowContext) {
cx.with_element_id(self.entity_id(), |_global_id, cx| {
cx.with_element_id(self.state.entity_id, |_global_id, cx| {
self.state.update(cx, |state, cx| {
let element = element.downcast_mut::<AnyElement<V>>().unwrap();
element.paint(state, cx);
@ -187,6 +187,12 @@ pub struct AnyView {
view: Arc<Mutex<dyn ViewObject>>,
}
impl AnyView {
pub fn entity_handle(&self) -> AnyHandle {
self.view.lock().entity_handle().clone()
}
}
impl<ParentV: 'static> IntoAnyElement<ParentV> for AnyView {
fn into_any(self) -> AnyElement<ParentV> {
AnyElement::new(EraseAnyViewState {
@ -200,8 +206,8 @@ impl Element for AnyView {
type ViewState = ();
type ElementState = AnyBox;
fn id(&self) -> Option<crate::ElementId> {
Some(ElementId::View(self.view.lock().entity_id()))
fn id(&self) -> Option<ElementId> {
Some(ElementId::View(self.view.lock().entity_handle().entity_id))
}
fn initialize(
@ -251,7 +257,7 @@ impl<ParentV: 'static> Element for EraseAnyViewState<ParentV> {
type ViewState = ParentV;
type ElementState = AnyBox;
fn id(&self) -> Option<crate::ElementId> {
fn id(&self) -> Option<ElementId> {
Element::id(&self.view)
}

View file

@ -1,14 +1,14 @@
use crate::{
px, size, Action, AnyBox, AnyDrag, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId, Edges, Effect,
Element, EntityId, EventEmitter, ExternalPaths, FileDropEvent, FocusEvent, FontId,
GlobalElementId, GlyphId, Handle, Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch,
KeyMatcher, Keystroke, LayoutId, MainThread, MainThreadOnly, Modifiers, MonochromeSprite,
MouseButton, 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, WeakHandle, WindowOptions,
SUBPIXEL_VARIANTS,
px, size, Action, AnyBox, AnyDrag, AnyHandle, AnyView, AppContext, AsyncWindowContext,
AvailableSpace, Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId,
Edges, Effect, Element, EntityId, EventEmitter, ExternalPaths, FileDropEvent, FocusEvent,
FontId, GlobalElementId, GlyphId, Handle, Hsla, ImageData, InputEvent, IsZero, KeyListener,
KeyMatch, KeyMatcher, Keystroke, LayoutId, MainThread, MainThreadOnly, Modifiers,
MonochromeSprite, MouseButton, 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, WeakHandle,
WindowOptions, SUBPIXEL_VARIANTS,
};
use anyhow::Result;
use collections::HashMap;
@ -145,7 +145,7 @@ impl Drop for FocusHandle {
}
pub struct Window {
handle: AnyWindowHandle,
pub(crate) handle: AnyWindowHandle,
platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
display_id: DisplayId,
sprite_atlas: Arc<dyn PlatformAtlas>,
@ -305,6 +305,10 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.handle
}
pub fn root_view(&self) -> Option<AnyHandle> {
Some(self.window.root_view.as_ref()?.entity_handle())
}
pub fn notify(&mut self) {
self.window.dirty = true;
}
@ -324,10 +328,9 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.last_blur = Some(self.window.focus);
}
let window_id = self.window.handle.id;
self.window.focus = Some(handle.id);
self.app.push_effect(Effect::FocusChanged {
window_id,
window_handle: self.window.handle,
focused: Some(handle.id),
});
self.notify();
@ -338,10 +341,9 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.last_blur = Some(self.window.focus);
}
let window_id = self.window.handle.id;
self.window.focus = None;
self.app.push_effect(Effect::FocusChanged {
window_id,
window_handle: self.window.handle,
focused: None,
});
self.notify();
@ -359,8 +361,8 @@ impl<'a, 'w> WindowContext<'a, 'w> {
mem::transmute::<&mut Self, &mut MainThread<Self>>(self)
})))
} else {
let id = self.window.handle.id;
self.app.run_on_main(move |cx| cx.update_window(id, f))
let handle = self.window.handle;
self.app.run_on_main(move |cx| cx.update_window(handle, f))
}
}
@ -1076,10 +1078,10 @@ impl<'a, 'w> WindowContext<'a, 'w> {
&mut self,
f: impl Fn(&mut WindowContext<'_, '_>) + Send + Sync + 'static,
) -> Subscription {
let window_id = self.window.handle.id;
let window_handle = self.window.handle;
self.global_observers.insert(
TypeId::of::<G>(),
Box::new(move |cx| cx.update_window(window_id, |cx| f(cx)).is_ok()),
Box::new(move |cx| cx.update_window(window_handle, |cx| f(cx)).is_ok()),
)
}
@ -1162,6 +1164,16 @@ impl<'a, 'w> WindowContext<'a, 'w> {
}
}
impl<'a, 'w> MainThread<WindowContext<'a, 'w>> {
fn platform_window(&self) -> &dyn PlatformWindow {
self.window.platform_window.borrow_on_main_thread().as_ref()
}
pub fn activate_window(&self) {
self.platform_window().activate();
}
}
impl Context for WindowContext<'_, '_> {
type EntityContext<'a, 'w, T> = ViewContext<'a, 'w, T>;
type Result<T> = T;
@ -1457,7 +1469,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
self.app.observers.insert(
handle.entity_id,
Box::new(move |cx| {
cx.update_window(window_handle.id, |cx| {
cx.update_window(window_handle, |cx| {
if let Some(handle) = handle.upgrade() {
this.update(cx, |this, cx| on_notify(this, handle, cx))
.is_ok()
@ -1484,7 +1496,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
self.app.event_listeners.insert(
handle.entity_id,
Box::new(move |event, cx| {
cx.update_window(window_handle.id, |cx| {
cx.update_window(window_handle, |cx| {
if let Some(handle) = handle.upgrade() {
let event = event.downcast_ref().expect("invalid event type");
this.update(cx, |this, cx| on_event(this, handle, event, cx))
@ -1508,7 +1520,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
Box::new(move |this, cx| {
let this = this.downcast_mut().expect("invalid entity type");
// todo!("are we okay with silently swallowing the error?")
let _ = cx.update_window(window_handle.id, |cx| on_release(this, cx));
let _ = cx.update_window(window_handle, |cx| on_release(this, cx));
}),
)
}
@ -1521,7 +1533,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
let this = self.handle();
let window_handle = self.window.handle;
self.app.observe_release(handle, move |entity, cx| {
let _ = cx.update_window(window_handle.id, |cx| {
let _ = cx.update_window(window_handle, |cx| {
this.update(cx, |this, cx| on_release(this, entity, cx))
});
})
@ -1678,12 +1690,12 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
&mut self,
f: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static,
) -> Subscription {
let window_id = self.window.handle.id;
let window_handle = self.window.handle;
let handle = self.handle();
self.global_observers.insert(
TypeId::of::<G>(),
Box::new(move |cx| {
cx.update_window(window_id, |cx| {
cx.update_window(window_handle, |cx| {
handle.update(cx, |view, cx| f(view, cx)).is_ok()
})
.unwrap_or(false)

File diff suppressed because it is too large Load diff

View file

@ -120,8 +120,6 @@ impl_actions!(pane, [ActivateItem, CloseActiveItem, CloseAllItems]);
const MAX_NAVIGATION_HISTORY_LEN: usize = 1024;
pub type BackgroundActions = fn() -> &'static [(&'static str, &'static dyn Action)];
pub fn init(cx: &mut AppContext) {
cx.add_action(Pane::toggle_zoom);
cx.add_action(|pane: &mut Pane, action: &ActivateItem, cx| {
@ -172,7 +170,6 @@ pub struct Pane {
toolbar: ViewHandle<Toolbar>,
tab_bar_context_menu: TabBarContextMenu,
tab_context_menu: ViewHandle<ContextMenu>,
_background_actions: BackgroundActions,
workspace: WeakViewHandle<Workspace>,
project: ModelHandle<Project>,
has_focus: bool,
@ -306,7 +303,6 @@ impl Pane {
pub fn new(
workspace: WeakViewHandle<Workspace>,
project: ModelHandle<Project>,
background_actions: BackgroundActions,
next_timestamp: Arc<AtomicUsize>,
cx: &mut ViewContext<Self>,
) -> Self {
@ -339,7 +335,6 @@ impl Pane {
handle: context_menu,
},
tab_context_menu: cx.add_view(|cx| ContextMenu::new(pane_view_id, cx)),
_background_actions: background_actions,
workspace,
project,
has_focus: false,

View file

@ -1,5 +1,5 @@
// pub mod dock;
// pub mod item;
pub mod item;
// pub mod notifications;
// pub mod pane;
// pub mod pane_group;
@ -11,19 +11,18 @@
// mod workspace_settings;
// use anyhow::{anyhow, Context, Result};
// use call::ActiveCall;
// use client::{
// use call2::ActiveCall;
// use client2::{
// proto::{self, PeerId},
// Client, Status, TypedEnvelope, UserStore,
// };
// use collections::{hash_map, HashMap, HashSet};
// use drag_and_drop::DragAndDrop;
// use futures::{
// channel::{mpsc, oneshot},
// future::try_join_all,
// FutureExt, StreamExt,
// };
// use gpui::{
// use gpui2::{
// actions,
// elements::*,
// geometry::{
@ -41,19 +40,8 @@
// };
// use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem};
// use itertools::Itertools;
// use language::{LanguageRegistry, Rope};
// use node_runtime::NodeRuntime;
// use std::{
// any::TypeId,
// borrow::Cow,
// cmp, env,
// future::Future,
// path::{Path, PathBuf},
// rc::Rc,
// str,
// sync::{atomic::AtomicUsize, Arc},
// time::Duration,
// };
// use language2::{LanguageRegistry, Rope};
// use node_runtime::NodeRuntime;// //
// use crate::{
// notifications::{simple_message_notification::MessageNotification, NotificationTracker},
@ -446,32 +434,31 @@
// });
// }
// pub struct AppState {
// pub languages: Arc<LanguageRegistry>,
// pub client: Arc<Client>,
// pub user_store: ModelHandle<UserStore>,
// pub workspace_store: ModelHandle<WorkspaceStore>,
// pub fs: Arc<dyn fs::Fs>,
// pub build_window_options:
// fn(Option<WindowBounds>, Option<uuid::Uuid>, &dyn Platform) -> WindowOptions<'static>,
// pub initialize_workspace:
// fn(WeakViewHandle<Workspace>, bool, Arc<AppState>, AsyncAppContext) -> Task<Result<()>>,
// pub background_actions: BackgroundActions,
// pub node_runtime: Arc<dyn NodeRuntime>,
// }
pub struct AppState {
pub languages: Arc<LanguageRegistry>,
pub client: Arc<Client>,
pub user_store: Handle<UserStore>,
pub workspace_store: Handle<WorkspaceStore>,
pub fs: Arc<dyn fs2::Fs>,
pub build_window_options:
fn(Option<WindowBounds>, Option<DisplayId>, &MainThread<AppContext>) -> WindowOptions,
pub initialize_workspace:
fn(WeakHandle<Workspace>, bool, Arc<AppState>, AsyncAppContext) -> Task<anyhow::Result<()>>,
pub node_runtime: Arc<dyn NodeRuntime>,
}
// pub struct WorkspaceStore {
// workspaces: HashSet<WeakViewHandle<Workspace>>,
// followers: Vec<Follower>,
// client: Arc<Client>,
// _subscriptions: Vec<client::Subscription>,
// }
pub struct WorkspaceStore {
workspaces: HashSet<WeakHandle<Workspace>>,
followers: Vec<Follower>,
client: Arc<Client>,
_subscriptions: Vec<client2::Subscription>,
}
// #[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
// struct Follower {
// project_id: Option<u64>,
// peer_id: PeerId,
// }
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
struct Follower {
project_id: Option<u64>,
peer_id: PeerId,
}
// impl AppState {
// #[cfg(any(test, feature = "test-support"))]
@ -504,7 +491,6 @@
// node_runtime: FakeNodeRuntime::new(),
// initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
// build_window_options: |_, _, _| Default::default(),
// background_actions: || &[],
// })
// }
// }
@ -560,8 +546,8 @@
// ContactRequestedJoin(u64),
// }
// pub struct Workspace {
// weak_self: WeakViewHandle<Self>,
pub struct Workspace {
weak_self: WeakHandle<Self>,
// modal: Option<ActiveModal>,
// zoomed: Option<AnyWeakViewHandle>,
// zoomed_position: Option<DockPosition>,
@ -577,7 +563,7 @@
// status_bar: ViewHandle<StatusBar>,
// titlebar_item: Option<AnyViewHandle>,
// notifications: Vec<(TypeId, usize, Box<dyn NotificationHandle>)>,
// project: ModelHandle<Project>,
project: Handle<Project>,
// follower_states: HashMap<ViewHandle<Pane>, FollowerState>,
// last_leaders_by_pane: HashMap<WeakViewHandle<Pane>, PeerId>,
// window_edited: bool,
@ -590,7 +576,7 @@
// _observe_current_user: Task<Result<()>>,
// _schedule_serialize: Option<Task<()>>,
// pane_history_timestamp: Arc<AtomicUsize>,
// }
}
// struct ActiveModal {
// view: Box<dyn ModalHandle>,
@ -669,7 +655,6 @@
// Pane::new(
// weak_handle.clone(),
// project.clone(),
// app_state.background_actions,
// pane_history_timestamp.clone(),
// cx,
// )
@ -1976,7 +1961,6 @@
// Pane::new(
// self.weak_handle(),
// self.project.clone(),
// self.app_state.background_actions,
// self.pane_history_timestamp.clone(),
// cx,
// )
@ -3536,7 +3520,6 @@
// fs: project.read(cx).fs().clone(),
// build_window_options: |_, _, _| Default::default(),
// initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
// background_actions: || &[],
// node_runtime: FakeNodeRuntime::new(),
// });
// Self::new(0, project, app_state, cx)
@ -4117,30 +4100,36 @@
// pub struct WorkspaceCreated(pub WeakViewHandle<Workspace>);
// pub fn activate_workspace_for_project(
// cx: &mut AsyncAppContext,
// predicate: impl Fn(&mut Project, &mut ModelContext<Project>) -> bool,
// ) -> Option<WeakViewHandle<Workspace>> {
// for window in cx.windows() {
// let handle = window
// .update(cx, |cx| {
// if let Some(workspace_handle) = cx.root_view().clone().downcast::<Workspace>() {
// let project = workspace_handle.read(cx).project.clone();
// if project.update(cx, &predicate) {
// cx.activate_window();
// return Some(workspace_handle.clone());
// }
// }
// None
// })
// .flatten();
pub async fn activate_workspace_for_project(
cx: &mut AsyncAppContext,
predicate: impl Fn(&Project, &AppContext) -> bool + Send + 'static,
) -> Option<WeakHandle<Workspace>> {
cx.run_on_main(move |cx| {
for window in cx.windows() {
let handle = cx
.update_window(window, |cx| {
if let Some(workspace_handle) = cx.root_view()?.downcast::<Workspace>() {
let project = workspace_handle.read(cx).project.clone();
if project.update(cx, |project, cx| predicate(project, cx)) {
cx.activate_window();
return Some(workspace_handle.clone());
}
}
None
})
.log_err()
.flatten();
// if let Some(handle) = handle {
// return Some(handle.downgrade());
// }
// }
// None
// }
if let Some(handle) = handle {
return Some(handle.downgrade());
}
}
None
})
.ok()?
.await
}
// pub async fn last_opened_workspace_paths() -> Option<WorkspaceLocation> {
// DB.last_workspace().await.log_err().flatten()
@ -4328,44 +4317,58 @@
// None
// }
// #[allow(clippy::type_complexity)]
// pub fn open_paths(
// abs_paths: &[PathBuf],
// app_state: &Arc<AppState>,
// requesting_window: Option<WindowHandle<Workspace>>,
// cx: &mut AppContext,
// ) -> Task<
// Result<(
// WeakViewHandle<Workspace>,
// Vec<Option<Result<Box<dyn ItemHandle>, anyhow::Error>>>,
// )>,
// > {
// let app_state = app_state.clone();
// let abs_paths = abs_paths.to_vec();
// cx.spawn(|mut cx| async move {
// // Open paths in existing workspace if possible
// let existing = activate_workspace_for_project(&mut cx, |project, cx| {
// project.contains_paths(&abs_paths, cx)
// });
use client2::{proto::PeerId, Client, UserStore};
use collections::HashSet;
use gpui2::{
AppContext, AsyncAppContext, DisplayId, Handle, MainThread, Task, WeakHandle, WindowBounds,
WindowHandle, WindowOptions,
};
use item::ItemHandle;
use language2::LanguageRegistry;
use node_runtime::NodeRuntime;
use project2::Project;
use std::{path::PathBuf, sync::Arc};
use util::ResultExt;
// if let Some(existing) = existing {
// Ok((
// existing.clone(),
// existing
// .update(&mut cx, |workspace, cx| {
// workspace.open_paths(abs_paths, true, cx)
// })?
// .await,
// ))
// } else {
// Ok(cx
// .update(|cx| {
// Workspace::new_local(abs_paths, app_state.clone(), requesting_window, cx)
// })
// .await)
// }
// })
// }
#[allow(clippy::type_complexity)]
pub fn open_paths(
abs_paths: &[PathBuf],
app_state: &Arc<AppState>,
requesting_window: Option<WindowHandle<Workspace>>,
cx: &mut AppContext,
) -> Task<
anyhow::Result<(
WeakHandle<Workspace>,
Vec<Option<Result<Box<dyn ItemHandle>, anyhow::Error>>>,
)>,
> {
let app_state = app_state.clone();
let abs_paths = abs_paths.to_vec();
cx.spawn(|mut cx| async move {
// Open paths in existing workspace if possible
let existing = activate_workspace_for_project(&mut cx, |project, cx| {
project.contains_paths(&abs_paths, cx)
})
.await;
if let Some(existing) = existing {
Ok((
existing.clone(),
existing
.update(&mut cx, |workspace, cx| {
workspace.open_paths(abs_paths, true, cx)
})?
.await,
))
} else {
Ok(cx
.update(|cx| {
Workspace::new_local(abs_paths, app_state.clone(), requesting_window, cx)
})
.await)
}
})
}
// pub fn open_new(
// app_state: &Arc<AppState>,