Store AnyWindowHandles instead of usizes

This commit is contained in:
Nathan Sobo 2023-08-08 16:06:53 -06:00
parent 1e8a9ccdb5
commit afd89b256a
9 changed files with 117 additions and 134 deletions

View file

@ -444,9 +444,9 @@ type WindowShouldCloseSubscriptionCallback = Box<dyn FnMut(&mut AppContext) -> b
pub struct AppContext { pub struct AppContext {
models: HashMap<usize, Box<dyn AnyModel>>, models: HashMap<usize, Box<dyn AnyModel>>,
views: HashMap<(usize, usize), Box<dyn AnyView>>, views: HashMap<(AnyWindowHandle, usize), Box<dyn AnyView>>,
views_metadata: HashMap<(usize, usize), ViewMetadata>, views_metadata: HashMap<(AnyWindowHandle, usize), ViewMetadata>,
windows: HashMap<usize, Window>, windows: HashMap<AnyWindowHandle, 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>,
@ -727,12 +727,12 @@ impl AppContext {
} }
pub fn view_ui_name(&self, window: AnyWindowHandle, view_id: usize) -> Option<&'static str> { pub fn view_ui_name(&self, window: AnyWindowHandle, view_id: usize) -> Option<&'static str> {
Some(self.views.get(&(window.id(), view_id))?.ui_name()) Some(self.views.get(&(window, view_id))?.ui_name())
} }
pub fn view_type_id(&self, window: AnyWindowHandle, view_id: usize) -> Option<TypeId> { pub fn view_type_id(&self, window: AnyWindowHandle, view_id: usize) -> Option<TypeId> {
self.views_metadata self.views_metadata
.get(&(window.id(), view_id)) .get(&(window, view_id))
.map(|metadata| metadata.type_id) .map(|metadata| metadata.type_id)
} }
@ -758,7 +758,7 @@ impl AppContext {
handle: AnyWindowHandle, handle: AnyWindowHandle,
callback: F, callback: F,
) -> Option<T> { ) -> Option<T> {
let window = self.windows.get(&handle.id())?; let window = self.windows.get(&handle)?;
let window_context = WindowContext::immutable(self, &window, handle); let window_context = WindowContext::immutable(self, &window, handle);
Some(callback(&window_context)) Some(callback(&window_context))
} }
@ -1033,7 +1033,7 @@ impl AppContext {
if let Some(focused_view_id) = cx.focused_view_id() { if let Some(focused_view_id) = cx.focused_view_id() {
for view_id in cx.ancestors(focused_view_id) { for view_id in cx.ancestors(focused_view_id) {
if let Some(view_metadata) = if let Some(view_metadata) =
cx.views_metadata.get(&(cx.window_handle.id(), view_id)) cx.views_metadata.get(&(cx.window_handle, view_id))
{ {
if let Some(actions) = cx.actions.get(&view_metadata.type_id) { if let Some(actions) = cx.actions.get(&view_metadata.type_id) {
if actions.contains_key(&action_id) { if actions.contains_key(&action_id) {
@ -1259,13 +1259,12 @@ impl AppContext {
F: FnOnce(&mut ViewContext<V>) -> V, F: FnOnce(&mut ViewContext<V>) -> V,
{ {
self.update(|this| { self.update(|this| {
let window_id = post_inc(&mut this.next_id); let handle = WindowHandle::<V>::new(post_inc(&mut this.next_id));
let platform_window = let platform_window =
this.platform this.platform
.open_window(window_id, window_options, this.foreground.clone()); .open_window(handle.into(), window_options, this.foreground.clone());
let handle = WindowHandle::<V>::new(window_id); let window = this.build_window(handle.into(), platform_window, build_root_view);
let window = this.build_window(handle, platform_window, build_root_view); this.windows.insert(handle.into(), window);
this.windows.insert(window_id, window);
handle handle
}) })
} }
@ -1276,29 +1275,25 @@ impl AppContext {
F: FnOnce(&mut ViewContext<V>) -> V, F: FnOnce(&mut ViewContext<V>) -> V,
{ {
self.update(|this| { self.update(|this| {
let window_id = post_inc(&mut this.next_id); let handle = WindowHandle::<V>::new(post_inc(&mut this.next_id));
let platform_window = this.platform.add_status_item(window_id); let platform_window = this.platform.add_status_item(handle.into());
let handle = WindowHandle::<V>::new(window_id); let window = this.build_window(handle.into(), platform_window, build_root_view);
let window = this.build_window(handle, platform_window, build_root_view); this.windows.insert(handle.into(), window);
this.windows.insert(window_id, window);
handle.update_root(this, |view, cx| view.focus_in(cx.handle().into_any(), cx)); handle.update_root(this, |view, cx| view.focus_in(cx.handle().into_any(), cx));
handle handle
}) })
} }
pub fn build_window<H, V, F>( pub fn build_window<V, F>(
&mut self, &mut self,
handle: H, handle: AnyWindowHandle,
mut platform_window: Box<dyn platform::Window>, mut platform_window: Box<dyn platform::Window>,
build_root_view: F, build_root_view: F,
) -> Window ) -> Window
where where
H: Into<AnyWindowHandle>,
V: View, V: View,
F: FnOnce(&mut ViewContext<V>) -> V, F: FnOnce(&mut ViewContext<V>) -> V,
{ {
let handle: AnyWindowHandle = handle.into();
{ {
let mut app = self.upgrade(); let mut app = self.upgrade();
@ -1371,21 +1366,15 @@ impl AppContext {
} }
pub fn active_window(&self) -> Option<AnyWindowHandle> { pub fn active_window(&self) -> Option<AnyWindowHandle> {
self.platform.main_window_id().and_then(|main_window_id| { self.platform.main_window()
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> { pub fn windows(&self) -> impl '_ + Iterator<Item = AnyWindowHandle> {
self.windows.iter().map(|(window_id, window)| { self.windows.keys().copied()
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 {
if let Some(view) = self.views.get(&(handle.window.id(), handle.view_id)) { if let Some(view) = self.views.get(&(handle.window, handle.view_id)) {
view.as_any().downcast_ref().expect("downcast is type safe") view.as_any().downcast_ref().expect("downcast is type safe")
} else { } else {
panic!("circular view reference for type {}", type_name::<T>()); panic!("circular view reference for type {}", type_name::<T>());
@ -1437,13 +1426,13 @@ impl AppContext {
.push_back(Effect::ModelRelease { model_id, model }); .push_back(Effect::ModelRelease { model_id, model });
} }
for (window_id, view_id) in dropped_views { for (window, view_id) in dropped_views {
self.subscriptions.remove(view_id); self.subscriptions.remove(view_id);
self.observations.remove(view_id); self.observations.remove(view_id);
self.views_metadata.remove(&(window_id, view_id)); self.views_metadata.remove(&(window, view_id));
let mut view = self.views.remove(&(window_id, view_id)).unwrap(); let mut view = self.views.remove(&(window, view_id)).unwrap();
view.release(self); view.release(self);
if let Some(window) = self.windows.get_mut(&window_id) { if let Some(window) = self.windows.get_mut(&window) {
window.parents.remove(&view_id); window.parents.remove(&view_id);
window window
.invalidation .invalidation
@ -1571,7 +1560,7 @@ impl AppContext {
} }
Effect::ResizeWindow { window } => { Effect::ResizeWindow { window } => {
if let Some(window) = self.windows.get_mut(&window.id()) { if let Some(window) = self.windows.get_mut(&window) {
window window
.invalidation .invalidation
.get_or_insert(WindowInvalidation::default()); .get_or_insert(WindowInvalidation::default());
@ -1696,15 +1685,14 @@ impl AppContext {
for old_ancestor in old_ancestors.iter().copied() { for old_ancestor in old_ancestors.iter().copied() {
if !new_ancestors.contains(&old_ancestor) { if !new_ancestors.contains(&old_ancestor) {
if let Some(mut view) = if let Some(mut view) =
cx.views.remove(&(window.id(), old_ancestor)) cx.views.remove(&(window, old_ancestor))
{ {
view.focus_out( view.focus_out(
focused_view_id, focused_view_id,
cx, cx,
old_ancestor, old_ancestor,
); );
cx.views cx.views.insert((window, old_ancestor), view);
.insert((window.id(), old_ancestor), view);
} }
} }
} }
@ -1713,15 +1701,14 @@ impl AppContext {
for new_ancestor in new_ancestors.iter().copied() { for new_ancestor in new_ancestors.iter().copied() {
if !old_ancestors.contains(&new_ancestor) { if !old_ancestors.contains(&new_ancestor) {
if let Some(mut view) = if let Some(mut view) =
cx.views.remove(&(window.id(), new_ancestor)) cx.views.remove(&(window, new_ancestor))
{ {
view.focus_in( view.focus_in(
focused_view_id, focused_view_id,
cx, cx,
new_ancestor, new_ancestor,
); );
cx.views cx.views.insert((window, new_ancestor), view);
.insert((window.id(), new_ancestor), view);
} }
} }
} }
@ -1730,9 +1717,7 @@ impl AppContext {
// there isn't any pending focus, focus the root view. // there isn't any pending focus, focus the root view.
let root_view_id = cx.window.root_view().id(); let root_view_id = cx.window.root_view().id();
if focused_view_id != root_view_id if focused_view_id != root_view_id
&& !cx && !cx.views.contains_key(&(window, focused_view_id))
.views
.contains_key(&(window.id(), focused_view_id))
&& !focus_effects.contains_key(&window.id()) && !focus_effects.contains_key(&window.id())
{ {
focus_effects.insert( focus_effects.insert(
@ -1837,13 +1822,13 @@ impl AppContext {
observed_window: AnyWindowHandle, observed_window: AnyWindowHandle,
observed_view_id: usize, observed_view_id: usize,
) { ) {
let view_key = (observed_window.id(), observed_view_id); let view_key = (observed_window, observed_view_id);
if let Some((view, mut view_metadata)) = self if let Some((view, mut view_metadata)) = self
.views .views
.remove(&view_key) .remove(&view_key)
.zip(self.views_metadata.remove(&view_key)) .zip(self.views_metadata.remove(&view_key))
{ {
if let Some(window) = self.windows.get_mut(&observed_window.id()) { if let Some(window) = self.windows.get_mut(&observed_window) {
window window
.invalidation .invalidation
.get_or_insert_with(Default::default) .get_or_insert_with(Default::default)
@ -1924,7 +1909,7 @@ impl AppContext {
let focused_id = match effect { let focused_id = match effect {
FocusEffect::View { view_id, .. } => { FocusEffect::View { view_id, .. } => {
if let Some(view_id) = view_id { if let Some(view_id) = view_id {
if cx.views.contains_key(&(window.id(), view_id)) { if cx.views.contains_key(&(window, view_id)) {
Some(view_id) Some(view_id)
} else { } else {
Some(cx.root_view().id()) Some(cx.root_view().id())
@ -1949,9 +1934,9 @@ impl AppContext {
if focus_changed { if focus_changed {
if let Some(blurred_id) = blurred_id { if let Some(blurred_id) = blurred_id {
for view_id in cx.ancestors(blurred_id).collect::<Vec<_>>() { for view_id in cx.ancestors(blurred_id).collect::<Vec<_>>() {
if let Some(mut view) = cx.views.remove(&(window.id(), view_id)) { if let Some(mut view) = cx.views.remove(&(window, view_id)) {
view.focus_out(blurred_id, cx, view_id); view.focus_out(blurred_id, cx, view_id);
cx.views.insert((window.id(), view_id), view); cx.views.insert((window, view_id), view);
} }
} }
@ -1963,9 +1948,9 @@ impl AppContext {
if focus_changed || effect.is_forced() { if focus_changed || effect.is_forced() {
if let Some(focused_id) = focused_id { if let Some(focused_id) = focused_id {
for view_id in cx.ancestors(focused_id).collect::<Vec<_>>() { for view_id in cx.ancestors(focused_id).collect::<Vec<_>>() {
if let Some(mut view) = cx.views.remove(&(window.id(), view_id)) { if let Some(mut view) = cx.views.remove(&(window, view_id)) {
view.focus_in(focused_id, cx, view_id); view.focus_in(focused_id, cx, view_id);
cx.views.insert((window.id(), view_id), view); cx.views.insert((window, view_id), view);
} }
} }
@ -1991,7 +1976,7 @@ impl AppContext {
mut callback: WindowShouldCloseSubscriptionCallback, mut callback: WindowShouldCloseSubscriptionCallback,
) { ) {
let mut app = self.upgrade(); let mut app = self.upgrade();
if let Some(window) = self.windows.get_mut(&window.id()) { if let Some(window) = self.windows.get_mut(&window) {
window window
.platform_window .platform_window
.on_should_close(Box::new(move || app.update(|cx| callback(cx)))) .on_should_close(Box::new(move || app.update(|cx| callback(cx))))
@ -2127,15 +2112,13 @@ impl BorrowWindowContext for AppContext {
where where
F: FnOnce(&mut WindowContext) -> T, F: FnOnce(&mut WindowContext) -> T,
{ {
self.update(|app_context| { let mut window = self.windows.remove(&handle)?;
let mut window = app_context.windows.remove(&handle.id())?; let mut window_context = WindowContext::mutable(self, &mut window, handle);
let mut window_context = WindowContext::mutable(app_context, &mut window, handle); let result = f(&mut window_context);
let result = f(&mut window_context); if !window_context.removed {
if !window_context.removed { self.windows.insert(handle, window);
app_context.windows.insert(handle.id(), window); }
} Some(result)
Some(result)
})
} }
fn update_window_optional<T, F>(&mut self, handle: AnyWindowHandle, f: F) -> Option<T> fn update_window_optional<T, F>(&mut self, handle: AnyWindowHandle, f: F) -> Option<T>
@ -2590,7 +2573,7 @@ where
} else { } else {
let focused_type = cx let focused_type = cx
.views_metadata .views_metadata
.get(&(cx.window_handle.id(), focused_id)) .get(&(cx.window_handle, focused_id))
.unwrap() .unwrap()
.type_id; .type_id;
AnyViewHandle::new( AnyViewHandle::new(
@ -2610,7 +2593,7 @@ where
} else { } else {
let blurred_type = cx let blurred_type = cx
.views_metadata .views_metadata
.get(&(cx.window_handle.id(), blurred_id)) .get(&(cx.window_handle, blurred_id))
.unwrap() .unwrap()
.type_id; .type_id;
AnyViewHandle::new( AnyViewHandle::new(
@ -3413,7 +3396,7 @@ impl<'a, 'b, 'c, V: View> LayoutContext<'a, 'b, 'c, V> {
let mut contexts = Vec::new(); let mut contexts = Vec::new();
let mut handler_depth = None; let mut handler_depth = None;
for (i, view_id) in self.ancestors(view_id).enumerate() { for (i, view_id) in self.ancestors(view_id).enumerate() {
if let Some(view_metadata) = self.views_metadata.get(&(window.id(), view_id)) { if let Some(view_metadata) = self.views_metadata.get(&(window, view_id)) {
if let Some(actions) = self.actions.get(&view_metadata.type_id) { if let Some(actions) = self.actions.get(&view_metadata.type_id) {
if actions.contains_key(&action.id()) { if actions.contains_key(&action.id()) {
handler_depth = Some(i); handler_depth = Some(i);
@ -3873,10 +3856,7 @@ impl<V> Copy for WindowHandle<V> {}
impl<V: View> WindowHandle<V> { impl<V: View> WindowHandle<V> {
fn new(window_id: usize) -> Self { fn new(window_id: usize) -> Self {
WindowHandle { WindowHandle {
any_handle: AnyWindowHandle { any_handle: AnyWindowHandle::new(window_id, TypeId::of::<V>()),
window_id,
root_view_type: TypeId::of::<V>(),
},
root_view_type: PhantomData, root_view_type: PhantomData,
} }
} }
@ -4240,7 +4220,7 @@ impl AnyViewHandle {
view_type: TypeId, view_type: TypeId,
ref_counts: Arc<Mutex<RefCounts>>, ref_counts: Arc<Mutex<RefCounts>>,
) -> Self { ) -> Self {
ref_counts.lock().inc_view(window.id(), view_id); ref_counts.lock().inc_view(window, view_id);
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
let handle_id = ref_counts let handle_id = ref_counts
@ -4308,7 +4288,7 @@ impl AnyViewHandle {
pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a>) -> serde_json::Value { pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a>) -> serde_json::Value {
cx.views cx.views
.get(&(self.window.id(), self.view_id)) .get(&(self.window, self.view_id))
.map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx)) .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
} }
} }
@ -4338,9 +4318,7 @@ impl<T> PartialEq<ViewHandle<T>> for AnyViewHandle {
impl Drop for AnyViewHandle { impl Drop for AnyViewHandle {
fn drop(&mut self) { fn drop(&mut self) {
self.ref_counts self.ref_counts.lock().dec_view(self.window, self.view_id);
.lock()
.dec_view(self.window.id(), self.view_id);
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
self.ref_counts self.ref_counts
.lock() .lock()

View file

@ -9,7 +9,7 @@ use collections::{hash_map::Entry, HashMap, HashSet};
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
use crate::util::post_inc; use crate::util::post_inc;
use crate::ElementStateId; use crate::{AnyWindowHandle, ElementStateId};
lazy_static! { lazy_static! {
static ref LEAK_BACKTRACE: bool = static ref LEAK_BACKTRACE: bool =
@ -26,7 +26,7 @@ pub struct RefCounts {
entity_counts: HashMap<usize, usize>, entity_counts: HashMap<usize, usize>,
element_state_counts: HashMap<ElementStateId, ElementStateRefCount>, element_state_counts: HashMap<ElementStateId, ElementStateRefCount>,
dropped_models: HashSet<usize>, dropped_models: HashSet<usize>,
dropped_views: HashSet<(usize, usize)>, dropped_views: HashSet<(AnyWindowHandle, usize)>,
dropped_element_states: HashSet<ElementStateId>, dropped_element_states: HashSet<ElementStateId>,
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
@ -55,12 +55,12 @@ impl RefCounts {
} }
} }
pub fn inc_view(&mut self, window_id: usize, view_id: usize) { pub fn inc_view(&mut self, window: AnyWindowHandle, view_id: usize) {
match self.entity_counts.entry(view_id) { match self.entity_counts.entry(view_id) {
Entry::Occupied(mut entry) => *entry.get_mut() += 1, Entry::Occupied(mut entry) => *entry.get_mut() += 1,
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
entry.insert(1); entry.insert(1);
self.dropped_views.remove(&(window_id, view_id)); self.dropped_views.remove(&(window, view_id));
} }
} }
} }
@ -94,12 +94,12 @@ impl RefCounts {
} }
} }
pub fn dec_view(&mut self, window_id: usize, view_id: usize) { pub fn dec_view(&mut self, window: AnyWindowHandle, view_id: usize) {
let count = self.entity_counts.get_mut(&view_id).unwrap(); let count = self.entity_counts.get_mut(&view_id).unwrap();
*count -= 1; *count -= 1;
if *count == 0 { if *count == 0 {
self.entity_counts.remove(&view_id); self.entity_counts.remove(&view_id);
self.dropped_views.insert((window_id, view_id)); self.dropped_views.insert((window, view_id));
} }
} }
@ -120,7 +120,7 @@ impl RefCounts {
&mut self, &mut self,
) -> ( ) -> (
HashSet<usize>, HashSet<usize>,
HashSet<(usize, usize)>, HashSet<(AnyWindowHandle, usize)>,
HashSet<ElementStateId>, HashSet<ElementStateId>,
) { ) {
( (

View file

@ -159,7 +159,7 @@ impl TestAppContext {
.borrow_mut() .borrow_mut()
.add_window(Default::default(), build_root_view); .add_window(Default::default(), build_root_view);
window.simulate_activation(self); window.simulate_activation(self);
WindowHandle::new(window.id()) window
} }
pub fn observe_global<E, F>(&mut self, callback: F) -> Subscription pub fn observe_global<E, F>(&mut self, callback: F) -> Subscription
@ -516,7 +516,7 @@ impl AnyWindowHandle {
cx: &'a mut TestAppContext, cx: &'a mut TestAppContext,
) -> std::cell::RefMut<'a, platform::test::Window> { ) -> std::cell::RefMut<'a, platform::test::Window> {
std::cell::RefMut::map(cx.cx.borrow_mut(), |state| { std::cell::RefMut::map(cx.cx.borrow_mut(), |state| {
let window = state.windows.get_mut(&self.window_id).unwrap(); let window = state.windows.get_mut(&self).unwrap();
let test_window = window let test_window = window
.platform_window .platform_window
.as_any_mut() .as_any_mut()

View file

@ -235,9 +235,9 @@ impl<'a> WindowContext<'a> {
F: FnOnce(&mut dyn AnyView, &mut Self) -> T, F: FnOnce(&mut dyn AnyView, &mut Self) -> T,
{ {
let handle = self.window_handle; let handle = self.window_handle;
let mut view = self.views.remove(&(handle.id(), view_id))?; let mut view = self.views.remove(&(handle, view_id))?;
let result = f(view.as_mut(), self); let result = f(view.as_mut(), self);
self.views.insert((handle.id(), view_id), view); self.views.insert((handle, view_id), view);
Some(result) Some(result)
} }
@ -389,7 +389,7 @@ impl<'a> WindowContext<'a> {
let mut contexts = Vec::new(); let mut contexts = Vec::new();
let mut handler_depths_by_action_id = HashMap::<TypeId, usize>::default(); let mut handler_depths_by_action_id = HashMap::<TypeId, usize>::default();
for (depth, view_id) in self.ancestors(view_id).enumerate() { for (depth, view_id) in self.ancestors(view_id).enumerate() {
if let Some(view_metadata) = self.views_metadata.get(&(handle.id(), view_id)) { if let Some(view_metadata) = self.views_metadata.get(&(handle, view_id)) {
contexts.push(view_metadata.keymap_context.clone()); contexts.push(view_metadata.keymap_context.clone());
if let Some(actions) = self.actions.get(&view_metadata.type_id) { if let Some(actions) = self.actions.get(&view_metadata.type_id) {
handler_depths_by_action_id handler_depths_by_action_id
@ -440,7 +440,7 @@ impl<'a> WindowContext<'a> {
.ancestors(focused_view_id) .ancestors(focused_view_id)
.filter_map(|view_id| { .filter_map(|view_id| {
self.views_metadata self.views_metadata
.get(&(handle.id(), view_id)) .get(&(handle, view_id))
.map(|view| (view_id, view.keymap_context.clone())) .map(|view| (view_id, view.keymap_context.clone()))
}) })
.collect(); .collect();
@ -850,9 +850,9 @@ impl<'a> WindowContext<'a> {
let handle = self.window_handle; let handle = self.window_handle;
if let Some(focused_view_id) = self.window.focused_view_id { if let Some(focused_view_id) = self.window.focused_view_id {
for view_id in self.ancestors(focused_view_id).collect::<Vec<_>>() { for view_id in self.ancestors(focused_view_id).collect::<Vec<_>>() {
if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { if let Some(mut view) = self.views.remove(&(handle, view_id)) {
let handled = view.key_down(event, self, view_id); let handled = view.key_down(event, self, view_id);
self.views.insert((handle.id(), view_id), view); self.views.insert((handle, view_id), view);
if handled { if handled {
return true; return true;
} }
@ -869,9 +869,9 @@ impl<'a> WindowContext<'a> {
let handle = self.window_handle; let handle = self.window_handle;
if let Some(focused_view_id) = self.window.focused_view_id { if let Some(focused_view_id) = self.window.focused_view_id {
for view_id in self.ancestors(focused_view_id).collect::<Vec<_>>() { for view_id in self.ancestors(focused_view_id).collect::<Vec<_>>() {
if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { if let Some(mut view) = self.views.remove(&(handle, view_id)) {
let handled = view.key_up(event, self, view_id); let handled = view.key_up(event, self, view_id);
self.views.insert((handle.id(), view_id), view); self.views.insert((handle, view_id), view);
if handled { if handled {
return true; return true;
} }
@ -888,9 +888,9 @@ impl<'a> WindowContext<'a> {
let handle = self.window_handle; let handle = self.window_handle;
if let Some(focused_view_id) = self.window.focused_view_id { if let Some(focused_view_id) = self.window.focused_view_id {
for view_id in self.ancestors(focused_view_id).collect::<Vec<_>>() { for view_id in self.ancestors(focused_view_id).collect::<Vec<_>>() {
if let Some(mut view) = self.views.remove(&(handle.id(), view_id)) { if let Some(mut view) = self.views.remove(&(handle, view_id)) {
let handled = view.modifiers_changed(event, self, view_id); let handled = view.modifiers_changed(event, self, view_id);
self.views.insert((handle.id(), view_id), view); self.views.insert((handle, view_id), view);
if handled { if handled {
return true; return true;
} }
@ -929,10 +929,10 @@ impl<'a> WindowContext<'a> {
let view_id = params.view_id; let view_id = params.view_id;
let mut view = self let mut view = self
.views .views
.remove(&(handle.id(), view_id)) .remove(&(handle, view_id))
.ok_or_else(|| anyhow!("view not found"))?; .ok_or_else(|| anyhow!("view not found"))?;
let element = view.render(self, view_id); let element = view.render(self, view_id);
self.views.insert((handle.id(), view_id), view); self.views.insert((handle, view_id), view);
Ok(element) Ok(element)
} }
@ -1190,13 +1190,13 @@ impl<'a> WindowContext<'a> {
let mut keymap_context = KeymapContext::default(); let mut keymap_context = KeymapContext::default();
view.update_keymap_context(&mut keymap_context, cx.app_context()); view.update_keymap_context(&mut keymap_context, cx.app_context());
self.views_metadata.insert( self.views_metadata.insert(
(handle.id(), view_id), (handle, view_id),
ViewMetadata { ViewMetadata {
type_id: TypeId::of::<T>(), type_id: TypeId::of::<T>(),
keymap_context, keymap_context,
}, },
); );
self.views.insert((handle.id(), view_id), Box::new(view)); self.views.insert((handle, view_id), Box::new(view));
self.window self.window
.invalidation .invalidation
.get_or_insert_with(Default::default) .get_or_insert_with(Default::default)

View file

@ -23,7 +23,7 @@ impl WindowInputHandler {
let mut app = self.app.try_borrow_mut().ok()?; let mut app = self.app.try_borrow_mut().ok()?;
self.window.update_optional(&mut *app, |cx| { self.window.update_optional(&mut *app, |cx| {
let view_id = cx.window.focused_view_id?; let view_id = cx.window.focused_view_id?;
let view = cx.views.get(&(self.window.id(), view_id))?; let view = cx.views.get(&(self.window, view_id))?;
let result = f(view.as_ref(), &cx); let result = f(view.as_ref(), &cx);
Some(result) Some(result)
}) })

View file

@ -19,7 +19,7 @@ use crate::{
}, },
keymap_matcher::KeymapMatcher, keymap_matcher::KeymapMatcher,
text_layout::{LineLayout, RunStyle}, text_layout::{LineLayout, RunStyle},
Action, ClipboardItem, Menu, Scene, Action, AnyWindowHandle, ClipboardItem, Menu, Scene,
}; };
use anyhow::{anyhow, bail, Result}; use anyhow::{anyhow, bail, Result};
use async_task::Runnable; use async_task::Runnable;
@ -58,13 +58,13 @@ pub trait Platform: Send + Sync {
fn open_window( fn open_window(
&self, &self,
id: usize, handle: AnyWindowHandle,
options: WindowOptions, options: WindowOptions,
executor: Rc<executor::Foreground>, executor: Rc<executor::Foreground>,
) -> Box<dyn Window>; ) -> Box<dyn Window>;
fn main_window_id(&self) -> Option<usize>; fn main_window(&self) -> Option<AnyWindowHandle>;
fn add_status_item(&self, id: usize) -> Box<dyn Window>; fn add_status_item(&self, handle: AnyWindowHandle) -> Box<dyn Window>;
fn write_to_clipboard(&self, item: ClipboardItem); fn write_to_clipboard(&self, item: ClipboardItem);
fn read_from_clipboard(&self) -> Option<ClipboardItem>; fn read_from_clipboard(&self) -> Option<ClipboardItem>;

View file

@ -6,7 +6,7 @@ use crate::{
executor, executor,
keymap_matcher::KeymapMatcher, keymap_matcher::KeymapMatcher,
platform::{self, AppVersion, CursorStyle, Event}, platform::{self, AppVersion, CursorStyle, Event},
Action, ClipboardItem, Menu, MenuItem, Action, AnyWindowHandle, ClipboardItem, Menu, MenuItem,
}; };
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use block::ConcreteBlock; use block::ConcreteBlock;
@ -590,18 +590,18 @@ impl platform::Platform for MacPlatform {
fn open_window( fn open_window(
&self, &self,
id: usize, handle: AnyWindowHandle,
options: platform::WindowOptions, options: platform::WindowOptions,
executor: Rc<executor::Foreground>, executor: Rc<executor::Foreground>,
) -> Box<dyn platform::Window> { ) -> Box<dyn platform::Window> {
Box::new(Window::open(id, options, executor, self.fonts())) Box::new(Window::open(handle, options, executor, self.fonts()))
} }
fn main_window_id(&self) -> Option<usize> { fn main_window(&self) -> Option<AnyWindowHandle> {
Window::main_window_id() Window::main_window()
} }
fn add_status_item(&self, _id: usize) -> Box<dyn platform::Window> { fn add_status_item(&self, _handle: AnyWindowHandle) -> Box<dyn platform::Window> {
Box::new(StatusItem::add(self.fonts())) Box::new(StatusItem::add(self.fonts()))
} }

View file

@ -13,6 +13,7 @@ use crate::{
Event, InputHandler, KeyDownEvent, Modifiers, ModifiersChangedEvent, MouseButton, Event, InputHandler, KeyDownEvent, Modifiers, ModifiersChangedEvent, MouseButton,
MouseButtonEvent, MouseMovedEvent, Scene, WindowBounds, WindowKind, MouseButtonEvent, MouseMovedEvent, Scene, WindowBounds, WindowKind,
}, },
AnyWindowHandle,
}; };
use block::ConcreteBlock; use block::ConcreteBlock;
use cocoa::{ use cocoa::{
@ -282,7 +283,7 @@ struct InsertText {
} }
struct WindowState { struct WindowState {
id: usize, handle: AnyWindowHandle,
native_window: id, native_window: id,
kind: WindowKind, kind: WindowKind,
event_callback: Option<Box<dyn FnMut(Event) -> bool>>, event_callback: Option<Box<dyn FnMut(Event) -> bool>>,
@ -426,7 +427,7 @@ pub struct Window(Rc<RefCell<WindowState>>);
impl Window { impl Window {
pub fn open( pub fn open(
id: usize, handle: AnyWindowHandle,
options: platform::WindowOptions, options: platform::WindowOptions,
executor: Rc<executor::Foreground>, executor: Rc<executor::Foreground>,
fonts: Arc<dyn platform::FontSystem>, fonts: Arc<dyn platform::FontSystem>,
@ -504,7 +505,7 @@ impl Window {
assert!(!native_view.is_null()); assert!(!native_view.is_null());
let window = Self(Rc::new(RefCell::new(WindowState { let window = Self(Rc::new(RefCell::new(WindowState {
id, handle,
native_window, native_window,
kind: options.kind, kind: options.kind,
event_callback: None, event_callback: None,
@ -621,13 +622,13 @@ impl Window {
} }
} }
pub fn main_window_id() -> Option<usize> { pub fn main_window() -> Option<AnyWindowHandle> {
unsafe { unsafe {
let app = NSApplication::sharedApplication(nil); let app = NSApplication::sharedApplication(nil);
let main_window: id = msg_send![app, mainWindow]; let main_window: id = msg_send![app, mainWindow];
if msg_send![main_window, isKindOfClass: WINDOW_CLASS] { if msg_send![main_window, isKindOfClass: WINDOW_CLASS] {
let id = get_window_state(&*main_window).borrow().id; let handle = get_window_state(&*main_window).borrow().handle;
Some(id) Some(handle)
} else { } else {
None None
} }
@ -881,7 +882,7 @@ impl platform::Window for Window {
fn is_topmost_for_position(&self, position: Vector2F) -> bool { fn is_topmost_for_position(&self, position: Vector2F) -> bool {
let self_borrow = self.0.borrow(); let self_borrow = self.0.borrow();
let self_id = self_borrow.id; let self_id = self_borrow.handle;
unsafe { unsafe {
let app = NSApplication::sharedApplication(nil); let app = NSApplication::sharedApplication(nil);
@ -898,7 +899,7 @@ impl platform::Window for Window {
let is_panel: BOOL = msg_send![top_most_window, isKindOfClass: PANEL_CLASS]; let is_panel: BOOL = msg_send![top_most_window, isKindOfClass: PANEL_CLASS];
let is_window: BOOL = msg_send![top_most_window, isKindOfClass: WINDOW_CLASS]; let is_window: BOOL = msg_send![top_most_window, isKindOfClass: WINDOW_CLASS];
if is_panel == YES || is_window == YES { if is_panel == YES || is_window == YES {
let topmost_window_id = get_window_state(&*top_most_window).borrow().id; let topmost_window_id = get_window_state(&*top_most_window).borrow().handle;
topmost_window_id == self_id topmost_window_id == self_id
} else { } else {
// Someone else's window is on top // Someone else's window is on top

View file

@ -5,7 +5,7 @@ use crate::{
vector::{vec2f, Vector2F}, vector::{vec2f, Vector2F},
}, },
keymap_matcher::KeymapMatcher, keymap_matcher::KeymapMatcher,
Action, ClipboardItem, Menu, Action, AnyWindowHandle, ClipboardItem, Menu,
}; };
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use collections::VecDeque; use collections::VecDeque;
@ -102,7 +102,7 @@ pub struct Platform {
fonts: Arc<dyn super::FontSystem>, fonts: Arc<dyn super::FontSystem>,
current_clipboard_item: Mutex<Option<ClipboardItem>>, current_clipboard_item: Mutex<Option<ClipboardItem>>,
cursor: Mutex<CursorStyle>, cursor: Mutex<CursorStyle>,
active_window_id: Arc<Mutex<Option<usize>>>, active_window: Arc<Mutex<Option<AnyWindowHandle>>>,
} }
impl Platform { impl Platform {
@ -112,7 +112,7 @@ impl Platform {
fonts: Arc::new(super::current::FontSystem::new()), fonts: Arc::new(super::current::FontSystem::new()),
current_clipboard_item: Default::default(), current_clipboard_item: Default::default(),
cursor: Mutex::new(CursorStyle::Arrow), cursor: Mutex::new(CursorStyle::Arrow),
active_window_id: Default::default(), active_window: Default::default(),
} }
} }
} }
@ -146,30 +146,30 @@ impl super::Platform for Platform {
fn open_window( fn open_window(
&self, &self,
id: usize, handle: AnyWindowHandle,
options: super::WindowOptions, options: super::WindowOptions,
_executor: Rc<super::executor::Foreground>, _executor: Rc<super::executor::Foreground>,
) -> Box<dyn super::Window> { ) -> Box<dyn super::Window> {
*self.active_window_id.lock() = Some(id); *self.active_window.lock() = Some(handle);
Box::new(Window::new( Box::new(Window::new(
id, handle,
match options.bounds { match options.bounds {
WindowBounds::Maximized | WindowBounds::Fullscreen => vec2f(1024., 768.), WindowBounds::Maximized | WindowBounds::Fullscreen => vec2f(1024., 768.),
WindowBounds::Fixed(rect) => rect.size(), WindowBounds::Fixed(rect) => rect.size(),
}, },
self.active_window_id.clone(), self.active_window.clone(),
)) ))
} }
fn main_window_id(&self) -> Option<usize> { fn main_window(&self) -> Option<AnyWindowHandle> {
self.active_window_id.lock().clone() self.active_window.lock().clone()
} }
fn add_status_item(&self, id: usize) -> Box<dyn crate::platform::Window> { fn add_status_item(&self, handle: AnyWindowHandle) -> Box<dyn crate::platform::Window> {
Box::new(Window::new( Box::new(Window::new(
id, handle,
vec2f(24., 24.), vec2f(24., 24.),
self.active_window_id.clone(), self.active_window.clone(),
)) ))
} }
@ -256,7 +256,7 @@ impl super::Screen for Screen {
} }
pub struct Window { pub struct Window {
id: usize, handle: AnyWindowHandle,
pub(crate) size: Vector2F, pub(crate) size: Vector2F,
scale_factor: f32, scale_factor: f32,
current_scene: Option<crate::Scene>, current_scene: Option<crate::Scene>,
@ -270,13 +270,17 @@ pub struct Window {
pub(crate) title: Option<String>, pub(crate) title: Option<String>,
pub(crate) edited: bool, pub(crate) edited: bool,
pub(crate) pending_prompts: RefCell<VecDeque<oneshot::Sender<usize>>>, pub(crate) pending_prompts: RefCell<VecDeque<oneshot::Sender<usize>>>,
active_window_id: Arc<Mutex<Option<usize>>>, active_window: Arc<Mutex<Option<AnyWindowHandle>>>,
} }
impl Window { impl Window {
pub fn new(id: usize, size: Vector2F, active_window_id: Arc<Mutex<Option<usize>>>) -> Self { pub fn new(
handle: AnyWindowHandle,
size: Vector2F,
active_window: Arc<Mutex<Option<AnyWindowHandle>>>,
) -> Self {
Self { Self {
id, handle,
size, size,
event_handlers: Default::default(), event_handlers: Default::default(),
resize_handlers: Default::default(), resize_handlers: Default::default(),
@ -290,7 +294,7 @@ impl Window {
title: None, title: None,
edited: false, edited: false,
pending_prompts: Default::default(), pending_prompts: Default::default(),
active_window_id, active_window,
} }
} }
@ -342,7 +346,7 @@ impl super::Window for Window {
} }
fn activate(&self) { fn activate(&self) {
*self.active_window_id.lock() = Some(self.id); *self.active_window.lock() = Some(self.handle);
} }
fn set_title(&mut self, title: &str) { fn set_title(&mut self, title: &str) {