diff --git a/crates/gpui3/src/elements/div.rs b/crates/gpui3/src/elements/div.rs index 13af47d088365f57cda7bdf8d75a561d34835310..76561f742b8f3a3ce12318fee4cea366c6d7d5e6 100644 --- a/crates/gpui3/src/elements/div.rs +++ b/crates/gpui3/src/elements/div.rs @@ -428,15 +428,19 @@ where } let key_listeners = mem::take(&mut self.listeners.key); - cx.with_focus( - self.focusability.focus_handle().cloned(), - &key_listeners, - |cx| { + cx.with_key_listeners(&key_listeners, |cx| { + if let Some(focus_handle) = self.focusability.focus_handle().cloned() { + cx.with_focus(focus_handle, |cx| { + for child in &mut self.children { + child.initialize(view_state, cx); + } + }) + } else { for child in &mut self.children { child.initialize(view_state, cx); } - }, - ); + } + }); self.listeners.key = key_listeners; element_state.unwrap_or_default() diff --git a/crates/gpui3/src/window.rs b/crates/gpui3/src/window.rs index cd90c1dab064d5a2f079e00952584d6567b242b8..d16539a369ab3ea748c83fa7ea3b1ad8fcd0ab4d 100644 --- a/crates/gpui3/src/window.rs +++ b/crates/gpui3/src/window.rs @@ -147,7 +147,7 @@ pub struct Window { content_mask_stack: Vec>, mouse_listeners: HashMap>, key_listeners: HashMap>, - push_key_listeners: bool, + key_events_enabled: bool, focus_stack: Vec, focus_parents_by_child: HashMap, pub(crate) focus_listeners: Vec, @@ -220,7 +220,7 @@ impl Window { content_mask_stack: Vec::new(), mouse_listeners: HashMap::default(), key_listeners: HashMap::default(), - push_key_listeners: true, + key_events_enabled: true, focus_stack: Vec::new(), focus_parents_by_child: HashMap::default(), focus_listeners: Vec::new(), @@ -823,7 +823,7 @@ impl<'a, 'w> WindowContext<'a, 'w> { window.focus_listeners.clear(); window.key_listeners.values_mut().for_each(Vec::clear); window.focus_parents_by_child.clear(); - window.push_key_listeners = true; + window.key_events_enabled = true; } fn end_frame(&mut self) { @@ -1219,31 +1219,17 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> { })); } - pub fn with_focus( + pub fn with_key_listeners( &mut self, - focus_handle: Option, key_listeners: &[(TypeId, KeyListener)], f: impl FnOnce(&mut Self) -> R, ) -> R { - let Some(focus_handle) = focus_handle else { - return f(self); - }; - - let handle = self.handle(); - let window = &mut *self.window; - - if let Some(parent_focus_id) = window.focus_stack.last() { - window - .focus_parents_by_child - .insert(focus_handle.id, *parent_focus_id); - } - window.focus_stack.push(focus_handle.id); - - if window.push_key_listeners { + if self.window.key_events_enabled { + let handle = self.handle(); for (type_id, listener) in key_listeners { let handle = handle.clone(); let listener = listener.clone(); - window + self.window .key_listeners .entry(*type_id) .or_default() @@ -1255,17 +1241,35 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> { } } - if Some(focus_handle.id) == window.focus { - window.push_key_listeners = false; - } - let result = f(self); - if self.window.push_key_listeners { + if self.window.key_events_enabled { for (type_id, _) in key_listeners { self.window.key_listeners.get_mut(type_id).unwrap().pop(); } } + + result + } + + pub fn with_focus( + &mut self, + focus_handle: FocusHandle, + f: impl FnOnce(&mut Self) -> R, + ) -> R { + if let Some(parent_focus_id) = self.window.focus_stack.last().copied() { + self.window + .focus_parents_by_child + .insert(focus_handle.id, parent_focus_id); + } + self.window.focus_stack.push(focus_handle.id); + + if Some(focus_handle.id) == self.window.focus { + self.window.key_events_enabled = false; + } + + let result = f(self); + self.window.focus_stack.pop(); result }