@@ -440,6 +440,7 @@ type WindowShouldCloseSubscriptionCallback = Box<dyn FnMut(&mut AppContext) -> b
pub struct AppContext {
models: HashMap<usize, Box<dyn AnyModel>>,
views: HashMap<(usize, usize), Box<dyn AnyView>>,
+ views_metadata: HashMap<(usize, usize), ViewMetadata>,
pub(crate) parents: HashMap<(usize, usize), ParentId>,
windows: HashMap<usize, Window>,
globals: HashMap<TypeId, Box<dyn Any>>,
@@ -502,6 +503,7 @@ impl AppContext {
Self {
models: Default::default(),
views: Default::default(),
+ views_metadata: Default::default(),
parents: Default::default(),
windows: Default::default(),
globals: Default::default(),
@@ -727,9 +729,9 @@ impl AppContext {
}
pub fn view_type_id(&self, window_id: usize, view_id: usize) -> Option<TypeId> {
- self.views
+ self.views_metadata
.get(&(window_id, view_id))
- .map(|view| view.as_any().type_id())
+ .map(|metadata| metadata.type_id)
}
pub fn active_labeled_tasks<'a>(
@@ -1045,9 +1047,10 @@ impl AppContext {
.read_window(window_id, |cx| {
if let Some(focused_view_id) = cx.focused_view_id() {
for view_id in cx.ancestors(focused_view_id) {
- if let Some(view) = cx.views.get(&(window_id, view_id)) {
- let view_type = view.as_any().type_id();
- if let Some(actions) = cx.actions.get(&view_type) {
+ if let Some(view_metadata) =
+ cx.views_metadata.get(&(window_id, view_id))
+ {
+ if let Some(actions) = cx.actions.get(&view_metadata.type_id) {
if actions.contains_key(&action_type) {
return true;
}
@@ -1448,6 +1451,7 @@ impl AppContext {
for (window_id, view_id) in dropped_views {
self.subscriptions.remove(view_id);
self.observations.remove(view_id);
+ self.views_metadata.remove(&(window_id, view_id));
let mut view = self.views.remove(&(window_id, view_id)).unwrap();
view.release(self);
let change_focus_to = self.windows.get_mut(&window_id).and_then(|window| {
@@ -1779,9 +1783,11 @@ impl AppContext {
observed_window_id: usize,
observed_view_id: usize,
) {
- if self
+ let view_key = (observed_window_id, observed_view_id);
+ if let Some((view, mut view_metadata)) = self
.views
- .contains_key(&(observed_window_id, observed_view_id))
+ .remove(&view_key)
+ .zip(self.views_metadata.remove(&view_key))
{
if let Some(window) = self.windows.get_mut(&observed_window_id) {
window
@@ -1791,6 +1797,10 @@ impl AppContext {
.insert(observed_view_id);
}
+ view_metadata.keymap_context = view.keymap_context(self);
+ self.views.insert(view_key, view);
+ self.views_metadata.insert(view_key, view_metadata);
+
let mut observations = self.observations.clone();
observations.emit(observed_view_id, |callback| callback(self));
}
@@ -2037,6 +2047,11 @@ pub enum ParentId {
Root,
}
+struct ViewMetadata {
+ type_id: TypeId,
+ keymap_context: KeymapContext,
+}
+
#[derive(Default, Clone)]
pub struct WindowInvalidation {
pub updated: HashSet<usize>,
@@ -2437,11 +2452,10 @@ where
cx.handle().into_any()
} else {
let focused_type = cx
- .views
+ .views_metadata
.get(&(cx.window_id, focused_id))
.unwrap()
- .as_any()
- .type_id();
+ .type_id;
AnyViewHandle::new(
cx.window_id,
focused_id,
@@ -2458,11 +2472,10 @@ where
cx.handle().into_any()
} else {
let blurred_type = cx
- .views
+ .views_metadata
.get(&(cx.window_id, blurred_id))
.unwrap()
- .as_any()
- .type_id();
+ .type_id;
AnyViewHandle::new(
cx.window_id,
blurred_id,
@@ -34,7 +34,7 @@ use std::{
use util::ResultExt;
use uuid::Uuid;
-use super::Reference;
+use super::{Reference, ViewMetadata};
pub struct Window {
pub(crate) root_view: Option<AnyViewHandle>,
@@ -369,13 +369,13 @@ impl<'a> WindowContext<'a> {
let mut contexts = Vec::new();
let mut handler_depth = None;
for (i, view_id) in self.ancestors(view_id).enumerate() {
- if let Some(view) = self.views.get(&(window_id, view_id)) {
- if let Some(actions) = self.actions.get(&view.as_any().type_id()) {
+ if let Some(view_metadata) = self.views_metadata.get(&(window_id, view_id)) {
+ if let Some(actions) = self.actions.get(&view_metadata.type_id) {
if actions.contains_key(&action.as_any().type_id()) {
handler_depth = Some(i);
}
}
- contexts.push(view.keymap_context(self));
+ contexts.push(view_metadata.keymap_context.clone());
}
}
@@ -1177,6 +1177,14 @@ impl<'a> WindowContext<'a> {
self.parents.insert((window_id, view_id), parent_id);
let mut cx = ViewContext::mutable(self, view_id);
let handle = if let Some(view) = build_view(&mut cx) {
+ let keymap_context = view.keymap_context(cx.app_context());
+ self.views_metadata.insert(
+ (window_id, view_id),
+ ViewMetadata {
+ type_id: TypeId::of::<T>(),
+ keymap_context,
+ },
+ );
self.views.insert((window_id, view_id), Box::new(view));
self.window
.invalidation