Fix on_action on focusable
We were accidentally dropping the key context
This commit is contained in:
parent
2625051f75
commit
7e7b065535
6 changed files with 34 additions and 54 deletions
|
@ -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<Self, StatefulInteractivity<Self>>;
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
modal(cx)
|
||||
.id("go to line")
|
||||
.context("GoToLine")
|
||||
.on_action(Self::cancel)
|
||||
.on_action(Self::confirm)
|
||||
.w_96()
|
||||
|
|
|
@ -128,7 +128,7 @@ impl<V: 'static> Div<V, StatefulInteractivity<V>, NonFocusableKeyDispatch> {
|
|||
pub fn focusable(self) -> Div<V, StatefulInteractivity<V>, FocusableKeyDispatch<V>> {
|
||||
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<V: 'static> Div<V, StatefulInteractivity<V>, NonFocusableKeyDispatch> {
|
|||
) -> Div<V, StatefulInteractivity<V>, FocusableKeyDispatch<V>> {
|
||||
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<V: 'static> Div<V, StatelessInteractivity<V>, NonFocusableKeyDispatch> {
|
|||
) -> Div<V, StatefulInteractivity<V>, FocusableKeyDispatch<V>> {
|
||||
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,
|
||||
|
|
|
@ -1247,9 +1247,10 @@ mod test {
|
|||
fn render(&mut self, _: &mut gpui::ViewContext<Self>) -> 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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<DispatchNodeId>,
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ pub(crate) struct DispatchNode {
|
|||
type KeyListener = Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ActionListener {
|
||||
pub(crate) struct DispatchActionListener {
|
||||
pub(crate) action_type: TypeId,
|
||||
pub(crate) listener: Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
|
||||
}
|
||||
|
@ -102,10 +102,12 @@ impl DispatchTree {
|
|||
action_type: TypeId,
|
||||
listener: Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
|
||||
) {
|
||||
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<Box<dyn Action>> {
|
||||
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<V: 'static>: 'static {
|
|||
}
|
||||
|
||||
pub struct FocusableKeyDispatch<V> {
|
||||
pub key_context: KeyContext,
|
||||
pub non_focusable: NonFocusableKeyDispatch,
|
||||
pub focus_handle: Option<FocusHandle>,
|
||||
pub focus_listeners: FocusListeners<V>,
|
||||
pub focus_style: StyleRefinement,
|
||||
|
@ -283,9 +279,9 @@ pub struct FocusableKeyDispatch<V> {
|
|||
}
|
||||
|
||||
impl<V> FocusableKeyDispatch<V> {
|
||||
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<V> FocusableKeyDispatch<V> {
|
|||
}
|
||||
}
|
||||
|
||||
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<V: 'static> KeyDispatch<V> for FocusableKeyDispatch<V> {
|
|||
}
|
||||
|
||||
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<V> From<FocusHandle> for FocusableKeyDispatch<V> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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<D: PickerDelegate> Picker<D> {
|
|||
}
|
||||
|
||||
impl<D: PickerDelegate> Render for Picker<D> {
|
||||
type Element = Div<Self, StatefulInteractivity<Self>, FocusableKeyDispatch<Self>>;
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
div()
|
||||
.context("picker")
|
||||
.id("picker-container")
|
||||
.focusable()
|
||||
.size_full()
|
||||
.on_action(Self::select_next)
|
||||
.on_action(Self::select_prev)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue