From 7e7b06553540594feee9e654571f89a079ea37fe Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Mon, 13 Nov 2023 12:48:36 -0700 Subject: [PATCH] Fix on_action on focusable We were accidentally dropping the key context --- crates/go_to_line2/src/go_to_line.rs | 7 ++-- crates/gpui2/src/elements/div.rs | 6 +-- crates/gpui2/src/interactive.rs | 5 ++- crates/gpui2/src/key_dispatch.rs | 55 ++++++++++------------------ crates/gpui2/src/window.rs | 6 +-- crates/picker2/src/picker2.rs | 9 ++--- 6 files changed, 34 insertions(+), 54 deletions(-) diff --git a/crates/go_to_line2/src/go_to_line.rs b/crates/go_to_line2/src/go_to_line.rs index 9ec770e05cdb73fb3b3ddc172f9949d5217ddabf..50592901b5396ca6cc11aa86b3f3c75820c0a2f1 100644 --- a/crates/go_to_line2/src/go_to_line.rs +++ b/crates/go_to_line2/src/go_to_line.rs @@ -1,8 +1,7 @@ use editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Editor}; use gpui::{ actions, div, AppContext, Div, EventEmitter, ParentElement, Render, SharedString, - StatefulInteractivity, StatelessInteractive, Styled, Subscription, View, ViewContext, - VisualContext, WindowContext, + StatelessInteractive, Styled, Subscription, View, ViewContext, VisualContext, WindowContext, }; use text::{Bias, Point}; use theme::ActiveTheme; @@ -146,11 +145,11 @@ impl GoToLine { } impl Render for GoToLine { - type Element = Div>; + type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { modal(cx) - .id("go to line") + .context("GoToLine") .on_action(Self::cancel) .on_action(Self::confirm) .w_96() diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 7bfd4b244a00bd6211df39d72b81d16f358c422a..95c44038ed115ead27a00d2dcd7a10e1fae429dc 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -128,7 +128,7 @@ impl Div, NonFocusableKeyDispatch> { pub fn focusable(self) -> Div, FocusableKeyDispatch> { Div { interactivity: self.interactivity, - key_dispatch: FocusableKeyDispatch::new(), + key_dispatch: FocusableKeyDispatch::new(self.key_dispatch), children: self.children, group: self.group, base_style: self.base_style, @@ -141,7 +141,7 @@ impl Div, NonFocusableKeyDispatch> { ) -> Div, FocusableKeyDispatch> { Div { interactivity: self.interactivity, - key_dispatch: FocusableKeyDispatch::tracked(handle), + key_dispatch: FocusableKeyDispatch::tracked(self.key_dispatch, handle), children: self.children, group: self.group, base_style: self.base_style, @@ -172,7 +172,7 @@ impl Div, NonFocusableKeyDispatch> { ) -> Div, FocusableKeyDispatch> { Div { interactivity: self.interactivity.into_stateful(handle), - key_dispatch: handle.clone().into(), + key_dispatch: FocusableKeyDispatch::tracked(self.key_dispatch, handle), children: self.children, group: self.group, base_style: self.base_style, diff --git a/crates/gpui2/src/interactive.rs b/crates/gpui2/src/interactive.rs index 4a7633f8dc6299af9b60eeabdb307ba1b036186c..aacaeac01ff0dd60dfc096d04a82fb2029704874 100644 --- a/crates/gpui2/src/interactive.rs +++ b/crates/gpui2/src/interactive.rs @@ -1247,9 +1247,10 @@ mod test { fn render(&mut self, _: &mut gpui::ViewContext) -> Self::Element { div().id("testview").child( div() + .context("test") + .track_focus(&self.focus_handle) .on_key_down(|this: &mut TestView, _, _, _| this.saw_key_down = true) - .on_action(|this: &mut TestView, _: &TestAction, _| this.saw_action = true) - .track_focus(&self.focus_handle), + .on_action(|this: &mut TestView, _: &TestAction, _| this.saw_action = true), ) } } diff --git a/crates/gpui2/src/key_dispatch.rs b/crates/gpui2/src/key_dispatch.rs index e517b8d34b51eda4473923e09ab8d1e4f0af56a1..8ace4188aed99f0594feddbd6e5b963df7005ebe 100644 --- a/crates/gpui2/src/key_dispatch.rs +++ b/crates/gpui2/src/key_dispatch.rs @@ -33,7 +33,7 @@ pub(crate) struct DispatchTree { #[derive(Default)] pub(crate) struct DispatchNode { pub key_listeners: SmallVec<[KeyListener; 2]>, - pub action_listeners: SmallVec<[ActionListener; 16]>, + pub action_listeners: SmallVec<[DispatchActionListener; 16]>, pub context: KeyContext, parent: Option, } @@ -41,7 +41,7 @@ pub(crate) struct DispatchNode { type KeyListener = Rc; #[derive(Clone)] -pub(crate) struct ActionListener { +pub(crate) struct DispatchActionListener { pub(crate) action_type: TypeId, pub(crate) listener: Rc, } @@ -102,10 +102,12 @@ impl DispatchTree { action_type: TypeId, listener: Rc, ) { - self.active_node().action_listeners.push(ActionListener { - action_type, - listener, - }); + self.active_node() + .action_listeners + .push(DispatchActionListener { + action_type, + listener, + }); } pub fn make_focusable(&mut self, focus_id: FocusId) { @@ -135,7 +137,7 @@ impl DispatchTree { if let Some(node) = self.focusable_node_ids.get(&target) { for node_id in self.dispatch_path(*node) { let node = &self.nodes[node_id.0]; - for ActionListener { action_type, .. } in &node.action_listeners { + for DispatchActionListener { action_type, .. } in &node.action_listeners { actions.extend(build_action_from_type(action_type).log_err()); } } @@ -148,21 +150,15 @@ impl DispatchTree { keystroke: &Keystroke, context: &[KeyContext], ) -> Option> { - if !self - .keystroke_matchers - .contains_key(self.context_stack.as_slice()) - { - let keystroke_contexts = self.context_stack.iter().cloned().collect(); + if !self.keystroke_matchers.contains_key(context) { + let keystroke_contexts = context.iter().cloned().collect(); self.keystroke_matchers.insert( keystroke_contexts, KeystrokeMatcher::new(self.keymap.clone()), ); } - let keystroke_matcher = self - .keystroke_matchers - .get_mut(self.context_stack.as_slice()) - .unwrap(); + let keystroke_matcher = self.keystroke_matchers.get_mut(context).unwrap(); if let KeyMatch::Some(action) = keystroke_matcher.match_keystroke(keystroke, context) { // Clear all pending keystrokes when an action has been found. for keystroke_matcher in self.keystroke_matchers.values_mut() { @@ -274,7 +270,7 @@ pub trait KeyDispatch: 'static { } pub struct FocusableKeyDispatch { - pub key_context: KeyContext, + pub non_focusable: NonFocusableKeyDispatch, pub focus_handle: Option, pub focus_listeners: FocusListeners, pub focus_style: StyleRefinement, @@ -283,9 +279,9 @@ pub struct FocusableKeyDispatch { } impl FocusableKeyDispatch { - pub fn new() -> Self { + pub fn new(non_focusable: NonFocusableKeyDispatch) -> Self { Self { - key_context: KeyContext::default(), + non_focusable, focus_handle: None, focus_listeners: FocusListeners::default(), focus_style: StyleRefinement::default(), @@ -294,9 +290,9 @@ impl FocusableKeyDispatch { } } - pub fn tracked(handle: &FocusHandle) -> Self { + pub fn tracked(non_focusable: NonFocusableKeyDispatch, handle: &FocusHandle) -> Self { Self { - key_context: KeyContext::default(), + non_focusable, focus_handle: Some(handle.clone()), focus_listeners: FocusListeners::default(), focus_style: StyleRefinement::default(), @@ -316,24 +312,11 @@ impl KeyDispatch for FocusableKeyDispatch { } fn key_context(&self) -> &KeyContext { - &self.key_context + &self.non_focusable.key_context } fn key_context_mut(&mut self) -> &mut KeyContext { - &mut self.key_context - } -} - -impl From for FocusableKeyDispatch { - fn from(value: FocusHandle) -> Self { - Self { - key_context: KeyContext::default(), - focus_handle: Some(value), - focus_listeners: FocusListeners::default(), - focus_style: StyleRefinement::default(), - focus_in_style: StyleRefinement::default(), - in_focus_style: StyleRefinement::default(), - } + &mut self.non_focusable.key_context } } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 11878c15fa29de5ea38584ad0c739a924d8a25cc..4a7241a5c52f0238f50679b5d25005d35cda35c0 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1,5 +1,5 @@ use crate::{ - key_dispatch::ActionListener, px, size, Action, AnyBox, AnyDrag, AnyView, AppContext, + key_dispatch::DispatchActionListener, px, size, Action, AnyBox, AnyDrag, AnyView, AppContext, AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle, DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla, ImageData, @@ -1306,7 +1306,7 @@ impl<'a> WindowContext<'a> { // Capture phase for node_id in &dispatch_path { let node = self.window.current_frame.dispatch_tree.node(*node_id); - for ActionListener { + for DispatchActionListener { action_type, listener, } in node.action_listeners.clone() @@ -1324,7 +1324,7 @@ impl<'a> WindowContext<'a> { // Bubble phase for node_id in dispatch_path.iter().rev() { let node = self.window.current_frame.dispatch_tree.node(*node_id); - for ActionListener { + for DispatchActionListener { action_type, listener, } in node.action_listeners.clone() diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 62c5308dec845c80ea74599f7666168722358b26..9d75fcb8905e13a5347d4f80136420e881ed2082 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -1,8 +1,7 @@ use editor::Editor; use gpui::{ - div, uniform_list, Component, Div, FocusableKeyDispatch, ParentElement, Render, - StatefulInteractivity, StatelessInteractive, Styled, Task, UniformListScrollHandle, View, - ViewContext, VisualContext, WindowContext, + div, uniform_list, Component, Div, ParentElement, Render, StatelessInteractive, Styled, Task, + UniformListScrollHandle, View, ViewContext, VisualContext, WindowContext, }; use std::cmp; use theme::ActiveTheme; @@ -137,13 +136,11 @@ impl Picker { } impl Render for Picker { - type Element = Div, FocusableKeyDispatch>; + type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { div() .context("picker") - .id("picker-container") - .focusable() .size_full() .on_action(Self::select_next) .on_action(Self::select_prev)