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:
parent
c8b5b085f4
commit
d9274416b4
8 changed files with 1331 additions and 1328 deletions
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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,
|
||||
|
|
|
@ -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,37 +546,37 @@
|
|||
// ContactRequestedJoin(u64),
|
||||
// }
|
||||
|
||||
// pub struct Workspace {
|
||||
// weak_self: WeakViewHandle<Self>,
|
||||
// modal: Option<ActiveModal>,
|
||||
// zoomed: Option<AnyWeakViewHandle>,
|
||||
// zoomed_position: Option<DockPosition>,
|
||||
// center: PaneGroup,
|
||||
// left_dock: ViewHandle<Dock>,
|
||||
// bottom_dock: ViewHandle<Dock>,
|
||||
// right_dock: ViewHandle<Dock>,
|
||||
// panes: Vec<ViewHandle<Pane>>,
|
||||
// panes_by_item: HashMap<usize, WeakViewHandle<Pane>>,
|
||||
// active_pane: ViewHandle<Pane>,
|
||||
// last_active_center_pane: Option<WeakViewHandle<Pane>>,
|
||||
// last_active_view_id: Option<proto::ViewId>,
|
||||
// status_bar: ViewHandle<StatusBar>,
|
||||
// titlebar_item: Option<AnyViewHandle>,
|
||||
// notifications: Vec<(TypeId, usize, Box<dyn NotificationHandle>)>,
|
||||
// project: ModelHandle<Project>,
|
||||
// follower_states: HashMap<ViewHandle<Pane>, FollowerState>,
|
||||
// last_leaders_by_pane: HashMap<WeakViewHandle<Pane>, PeerId>,
|
||||
// window_edited: bool,
|
||||
// active_call: Option<(ModelHandle<ActiveCall>, Vec<Subscription>)>,
|
||||
// leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
|
||||
// database_id: WorkspaceId,
|
||||
// app_state: Arc<AppState>,
|
||||
// subscriptions: Vec<Subscription>,
|
||||
// _apply_leader_updates: Task<Result<()>>,
|
||||
// _observe_current_user: Task<Result<()>>,
|
||||
// _schedule_serialize: Option<Task<()>>,
|
||||
// pane_history_timestamp: Arc<AtomicUsize>,
|
||||
// }
|
||||
pub struct Workspace {
|
||||
weak_self: WeakHandle<Self>,
|
||||
// modal: Option<ActiveModal>,
|
||||
// zoomed: Option<AnyWeakViewHandle>,
|
||||
// zoomed_position: Option<DockPosition>,
|
||||
// center: PaneGroup,
|
||||
// left_dock: ViewHandle<Dock>,
|
||||
// bottom_dock: ViewHandle<Dock>,
|
||||
// right_dock: ViewHandle<Dock>,
|
||||
// panes: Vec<ViewHandle<Pane>>,
|
||||
// panes_by_item: HashMap<usize, WeakViewHandle<Pane>>,
|
||||
// active_pane: ViewHandle<Pane>,
|
||||
// last_active_center_pane: Option<WeakViewHandle<Pane>>,
|
||||
// last_active_view_id: Option<proto::ViewId>,
|
||||
// status_bar: ViewHandle<StatusBar>,
|
||||
// titlebar_item: Option<AnyViewHandle>,
|
||||
// notifications: Vec<(TypeId, usize, Box<dyn NotificationHandle>)>,
|
||||
project: Handle<Project>,
|
||||
// follower_states: HashMap<ViewHandle<Pane>, FollowerState>,
|
||||
// last_leaders_by_pane: HashMap<WeakViewHandle<Pane>, PeerId>,
|
||||
// window_edited: bool,
|
||||
// active_call: Option<(ModelHandle<ActiveCall>, Vec<Subscription>)>,
|
||||
// leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
|
||||
// database_id: WorkspaceId,
|
||||
// app_state: Arc<AppState>,
|
||||
// subscriptions: Vec<Subscription>,
|
||||
// _apply_leader_updates: Task<Result<()>>,
|
||||
// _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>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue