This commit is contained in:
Nathan Sobo 2023-08-06 18:57:02 -06:00
parent adc50469ff
commit d4d32611fe
3 changed files with 44 additions and 32 deletions

View file

@ -133,13 +133,11 @@ pub trait BorrowAppContext {
pub trait BorrowWindowContext { pub trait BorrowWindowContext {
type Result<T>; type Result<T>;
fn read_window_with<H, T, F>(&self, window_handle: H, f: F) -> Self::Result<T> fn read_window_with<T, F>(&self, window_id: usize, f: F) -> Self::Result<T>
where where
H: Into<AnyWindowHandle>,
F: FnOnce(&WindowContext) -> T; F: FnOnce(&WindowContext) -> T;
fn update_window<H, T, F>(&mut self, window_handle: H, f: F) -> Self::Result<T> fn update_window<T, F>(&mut self, window_id: usize, f: F) -> Self::Result<T>
where where
H: Into<AnyWindowHandle>,
F: FnOnce(&mut WindowContext) -> T; F: FnOnce(&mut WindowContext) -> T;
} }
@ -303,13 +301,12 @@ impl App {
result result
} }
fn update_window<H, T, F>(&mut self, handle: H, callback: F) -> Option<T> fn update_window<T, F>(&mut self, window_id: usize, callback: F) -> Option<T>
where where
H: Into<AnyWindowHandle>,
F: FnOnce(&mut WindowContext) -> T, F: FnOnce(&mut WindowContext) -> T,
{ {
let mut state = self.0.borrow_mut(); let mut state = self.0.borrow_mut();
let result = state.update_window(handle, callback); let result = state.update_window(window_id, callback);
state.pending_notifications.clear(); state.pending_notifications.clear();
result result
} }
@ -350,10 +347,10 @@ impl AsyncAppContext {
pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>( pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
&mut self, &mut self,
handle: AnyWindowHandle, window_id: usize,
callback: F, callback: F,
) -> Option<T> { ) -> Option<T> {
self.0.borrow_mut().update_window(handle, callback) self.0.borrow_mut().update_window(window_id, callback)
} }
pub fn debug_elements(&self, window_id: usize) -> Option<json::Value> { pub fn debug_elements(&self, window_id: usize) -> Option<json::Value> {
@ -366,13 +363,13 @@ impl AsyncAppContext {
pub fn dispatch_action( pub fn dispatch_action(
&mut self, &mut self,
window: impl Into<AnyWindowHandle>, window_id: usize,
view_id: usize, view_id: usize,
action: &dyn Action, action: &dyn Action,
) -> Result<()> { ) -> Result<()> {
self.0 self.0
.borrow_mut() .borrow_mut()
.update_window(window, |cx| { .update_window(window_id, |cx| {
cx.dispatch_action(Some(view_id), action); cx.dispatch_action(Some(view_id), action);
}) })
.ok_or_else(|| anyhow!("window not found")) .ok_or_else(|| anyhow!("window not found"))
@ -492,7 +489,7 @@ pub struct AppContext {
models: HashMap<usize, Box<dyn AnyModel>>, models: HashMap<usize, Box<dyn AnyModel>>,
views: HashMap<(usize, usize), Box<dyn AnyView>>, views: HashMap<(usize, usize), Box<dyn AnyView>>,
views_metadata: HashMap<(usize, usize), ViewMetadata>, views_metadata: HashMap<(usize, usize), ViewMetadata>,
windows: HashMap<AnyWindowHandle, Window>, windows: HashMap<usize, Window>,
globals: HashMap<TypeId, Box<dyn Any>>, globals: HashMap<TypeId, Box<dyn Any>>,
element_states: HashMap<ElementStateId, Box<dyn Any>>, element_states: HashMap<ElementStateId, Box<dyn Any>>,
background: Arc<executor::Background>, background: Arc<executor::Background>,
@ -1414,9 +1411,18 @@ impl AppContext {
window window
} }
pub fn windows(&self) -> impl Iterator<Item = AnyWindowHandle> { pub fn main_window(&self) -> Option<AnyWindowHandle> {
todo!(); self.platform.main_window_id().and_then(|main_window_id| {
None.into_iter() self.windows
.get(&main_window_id)
.map(|window| AnyWindowHandle::new(main_window_id, window.root_view().type_id()))
})
}
pub fn windows(&self) -> impl '_ + Iterator<Item = AnyWindowHandle> {
self.windows.iter().map(|(window_id, window)| {
AnyWindowHandle::new(*window_id, window.root_view().type_id())
})
} }
pub fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T { pub fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
@ -2157,17 +2163,16 @@ impl BorrowWindowContext for AppContext {
AppContext::read_window(self, window_id, f) AppContext::read_window(self, window_id, f)
} }
fn update_window<T, F>(&mut self, window: usize, f: F) -> Self::Result<T> fn update_window<T, F>(&mut self, window_id: usize, f: F) -> Self::Result<T>
where where
F: FnOnce(&mut WindowContext) -> T, F: FnOnce(&mut WindowContext) -> T,
{ {
self.update(|app_context| { self.update(|app_context| {
let mut window = app_context.windows.remove(&window_handle)?; let mut window = app_context.windows.remove(&window_id)?;
let mut window_context = let mut window_context = WindowContext::mutable(app_context, &mut window, window_id);
WindowContext::mutable(app_context, &mut window, window_handle); let result = f(&mut window_context);
let result = callback(&mut window_context);
if !window_context.removed { if !window_context.removed {
app_context.windows.insert(window_handle, window); app_context.windows.insert(window_id, window);
} }
Some(result) Some(result)
}) })
@ -3876,7 +3881,7 @@ impl<V: View> WindowHandle<V> {
C: BorrowWindowContext, C: BorrowWindowContext,
F: FnOnce(&mut V, &mut ViewContext<V>) -> R, F: FnOnce(&mut V, &mut ViewContext<V>) -> R,
{ {
cx.update_window(*self, |cx| { cx.update_window(self.id(), |cx| {
cx.root_view() cx.root_view()
.clone() .clone()
.downcast::<V>() .downcast::<V>()
@ -3890,7 +3895,7 @@ impl<V: View> WindowHandle<V> {
C: BorrowWindowContext, C: BorrowWindowContext,
F: FnOnce(&mut ViewContext<V>) -> V, F: FnOnce(&mut ViewContext<V>) -> V,
{ {
cx.update_window(self.into_any(), |cx| { cx.update_window(self.id(), |cx| {
let root_view = self.add_view(cx, |cx| build_root(cx)); let root_view = self.add_view(cx, |cx| build_root(cx));
cx.window.root_view = Some(root_view.clone().into_any()); cx.window.root_view = Some(root_view.clone().into_any());
cx.window.focused_view_id = Some(root_view.id()); cx.window.focused_view_id = Some(root_view.id());
@ -3912,6 +3917,13 @@ pub struct AnyWindowHandle {
} }
impl AnyWindowHandle { impl AnyWindowHandle {
fn new(window_id: usize, root_view_type: TypeId) -> Self {
Self {
window_id,
root_view_type,
}
}
pub fn id(&self) -> usize { pub fn id(&self) -> usize {
self.window_id self.window_id
} }

View file

@ -77,9 +77,9 @@ pub(crate) fn setup_menu_handlers(foreground_platform: &dyn ForegroundPlatform,
let cx = app.0.clone(); let cx = app.0.clone();
move |action| { move |action| {
let mut cx = cx.borrow_mut(); let mut cx = cx.borrow_mut();
if let Some(main_window_id) = cx.platform.main_window_id() { if let Some(main_window) = cx.main_window() {
let dispatched = cx let dispatched = main_window
.update_window(main_window_id, |cx| { .update(&mut *cx, |cx| {
if let Some(view_id) = cx.focused_view_id() { if let Some(view_id) = cx.focused_view_id() {
cx.dispatch_action(Some(view_id), action); cx.dispatch_action(Some(view_id), action);
true true

View file

@ -198,8 +198,8 @@ impl TestAppContext {
self.cx.borrow_mut().subscribe_global(callback) self.cx.borrow_mut().subscribe_global(callback)
} }
pub fn windows(&self) -> impl Iterator<Item = AnyWindowHandle> { pub fn windows(&self) -> Vec<AnyWindowHandle> {
self.cx.borrow().windows() self.cx.borrow().windows().collect()
} }
// pub fn window_ids(&self) -> Vec<usize> { // pub fn window_ids(&self) -> Vec<usize> {
@ -322,15 +322,15 @@ impl TestAppContext {
pub fn simulate_window_activation(&self, to_activate: Option<usize>) { pub fn simulate_window_activation(&self, to_activate: Option<usize>) {
self.cx.borrow_mut().update(|cx| { self.cx.borrow_mut().update(|cx| {
let other_windows = cx let other_window_ids = cx
.windows .windows
.keys() .keys()
.filter(|window| Some(window.id()) != to_activate) .filter(|window_id| Some(**window_id) != to_activate)
.copied() .copied()
.collect::<Vec<_>>(); .collect::<Vec<_>>();
for window in other_windows { for window_id in other_window_ids {
cx.window_changed_active_status(window.id(), false) cx.window_changed_active_status(window_id, false)
} }
if let Some(to_activate) = to_activate { if let Some(to_activate) = to_activate {