diff --git a/crates/gpui3/src/elements/div.rs b/crates/gpui3/src/elements/div.rs index 938325ac89406786594638750c06564d8dcec4f6..13af47d088365f57cda7bdf8d75a561d34835310 100644 --- a/crates/gpui3/src/elements/div.rs +++ b/crates/gpui3/src/elements/div.rs @@ -423,12 +423,14 @@ where element_state: Option, cx: &mut ViewContext, ) -> Self::ElementState { + for listener in self.listeners.focus.iter().cloned() { + cx.on_focus_changed(move |view, event, cx| listener(view, event, cx)); + } + let key_listeners = mem::take(&mut self.listeners.key); - let focus_listeners = mem::take(&mut self.listeners.focus); cx.with_focus( self.focusability.focus_handle().cloned(), &key_listeners, - &focus_listeners, |cx| { for child in &mut self.children { child.initialize(view_state, cx); @@ -436,7 +438,7 @@ where }, ); self.listeners.key = key_listeners; - self.listeners.focus = focus_listeners; + element_state.unwrap_or_default() } diff --git a/crates/gpui3/src/window.rs b/crates/gpui3/src/window.rs index ca3acc41ecf5c627f844037c07696be2911d2181..cd90c1dab064d5a2f079e00952584d6567b242b8 100644 --- a/crates/gpui3/src/window.rs +++ b/crates/gpui3/src/window.rs @@ -1,12 +1,12 @@ use crate::{ px, size, AnyBox, AnyView, AppContext, AsyncWindowContext, AvailableSpace, BorrowAppContext, Bounds, BoxShadow, Context, Corners, DevicePixels, DisplayId, Edges, Effect, Element, EntityId, - EventEmitter, FocusEvent, FocusListener, FontId, GlobalElementId, GlyphId, Handle, Hsla, - ImageData, InputEvent, IsZero, KeyListener, LayoutId, MainThread, MainThreadOnly, - MonochromeSprite, MouseMoveEvent, Path, Pixels, Platform, PlatformAtlas, PlatformWindow, Point, - PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderImageParams, RenderSvgParams, - ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, Subscription, TaffyLayoutEngine, - Task, Underline, UnderlineStyle, WeakHandle, WindowOptions, SUBPIXEL_VARIANTS, + EventEmitter, FocusEvent, FontId, GlobalElementId, GlyphId, Handle, Hsla, ImageData, + InputEvent, IsZero, KeyListener, LayoutId, MainThread, MainThreadOnly, MonochromeSprite, + MouseMoveEvent, Path, Pixels, Platform, 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; @@ -1207,11 +1207,22 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> { }); } + pub fn on_focus_changed( + &mut self, + listener: impl Fn(&mut V, &FocusEvent, &mut ViewContext) + Send + Sync + 'static, + ) { + let handle = self.handle(); + self.window.focus_listeners.push(Arc::new(move |event, cx| { + handle + .update(cx, |view, cx| listener(view, event, cx)) + .log_err(); + })); + } + pub fn with_focus( &mut self, focus_handle: Option, key_listeners: &[(TypeId, KeyListener)], - focus_listeners: &[FocusListener], f: impl FnOnce(&mut Self) -> R, ) -> R { let Some(focus_handle) = focus_handle else { @@ -1221,15 +1232,6 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> { let handle = self.handle(); let window = &mut *self.window; - for listener in focus_listeners.iter().cloned() { - let handle = handle.clone(); - window.focus_listeners.push(Arc::new(move |event, cx| { - handle - .update(cx, |view, cx| listener(view, event, cx)) - .log_err(); - })); - } - if let Some(parent_focus_id) = window.focus_stack.last() { window .focus_parents_by_child