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 editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Editor};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, AppContext, Div, EventEmitter, ParentElement, Render, SharedString,
|
actions, div, AppContext, Div, EventEmitter, ParentElement, Render, SharedString,
|
||||||
StatefulInteractivity, StatelessInteractive, Styled, Subscription, View, ViewContext,
|
StatelessInteractive, Styled, Subscription, View, ViewContext, VisualContext, WindowContext,
|
||||||
VisualContext, WindowContext,
|
|
||||||
};
|
};
|
||||||
use text::{Bias, Point};
|
use text::{Bias, Point};
|
||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
|
@ -146,11 +145,11 @@ impl GoToLine {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for 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 {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
modal(cx)
|
modal(cx)
|
||||||
.id("go to line")
|
.context("GoToLine")
|
||||||
.on_action(Self::cancel)
|
.on_action(Self::cancel)
|
||||||
.on_action(Self::confirm)
|
.on_action(Self::confirm)
|
||||||
.w_96()
|
.w_96()
|
||||||
|
|
|
@ -128,7 +128,7 @@ impl<V: 'static> Div<V, StatefulInteractivity<V>, NonFocusableKeyDispatch> {
|
||||||
pub fn focusable(self) -> Div<V, StatefulInteractivity<V>, FocusableKeyDispatch<V>> {
|
pub fn focusable(self) -> Div<V, StatefulInteractivity<V>, FocusableKeyDispatch<V>> {
|
||||||
Div {
|
Div {
|
||||||
interactivity: self.interactivity,
|
interactivity: self.interactivity,
|
||||||
key_dispatch: FocusableKeyDispatch::new(),
|
key_dispatch: FocusableKeyDispatch::new(self.key_dispatch),
|
||||||
children: self.children,
|
children: self.children,
|
||||||
group: self.group,
|
group: self.group,
|
||||||
base_style: self.base_style,
|
base_style: self.base_style,
|
||||||
|
@ -141,7 +141,7 @@ impl<V: 'static> Div<V, StatefulInteractivity<V>, NonFocusableKeyDispatch> {
|
||||||
) -> Div<V, StatefulInteractivity<V>, FocusableKeyDispatch<V>> {
|
) -> Div<V, StatefulInteractivity<V>, FocusableKeyDispatch<V>> {
|
||||||
Div {
|
Div {
|
||||||
interactivity: self.interactivity,
|
interactivity: self.interactivity,
|
||||||
key_dispatch: FocusableKeyDispatch::tracked(handle),
|
key_dispatch: FocusableKeyDispatch::tracked(self.key_dispatch, handle),
|
||||||
children: self.children,
|
children: self.children,
|
||||||
group: self.group,
|
group: self.group,
|
||||||
base_style: self.base_style,
|
base_style: self.base_style,
|
||||||
|
@ -172,7 +172,7 @@ impl<V: 'static> Div<V, StatelessInteractivity<V>, NonFocusableKeyDispatch> {
|
||||||
) -> Div<V, StatefulInteractivity<V>, FocusableKeyDispatch<V>> {
|
) -> Div<V, StatefulInteractivity<V>, FocusableKeyDispatch<V>> {
|
||||||
Div {
|
Div {
|
||||||
interactivity: self.interactivity.into_stateful(handle),
|
interactivity: self.interactivity.into_stateful(handle),
|
||||||
key_dispatch: handle.clone().into(),
|
key_dispatch: FocusableKeyDispatch::tracked(self.key_dispatch, handle),
|
||||||
children: self.children,
|
children: self.children,
|
||||||
group: self.group,
|
group: self.group,
|
||||||
base_style: self.base_style,
|
base_style: self.base_style,
|
||||||
|
|
|
@ -1247,9 +1247,10 @@ mod test {
|
||||||
fn render(&mut self, _: &mut gpui::ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, _: &mut gpui::ViewContext<Self>) -> Self::Element {
|
||||||
div().id("testview").child(
|
div().id("testview").child(
|
||||||
div()
|
div()
|
||||||
|
.context("test")
|
||||||
|
.track_focus(&self.focus_handle)
|
||||||
.on_key_down(|this: &mut TestView, _, _, _| this.saw_key_down = true)
|
.on_key_down(|this: &mut TestView, _, _, _| this.saw_key_down = true)
|
||||||
.on_action(|this: &mut TestView, _: &TestAction, _| this.saw_action = true)
|
.on_action(|this: &mut TestView, _: &TestAction, _| this.saw_action = true),
|
||||||
.track_focus(&self.focus_handle),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub(crate) struct DispatchTree {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(crate) struct DispatchNode {
|
pub(crate) struct DispatchNode {
|
||||||
pub key_listeners: SmallVec<[KeyListener; 2]>,
|
pub key_listeners: SmallVec<[KeyListener; 2]>,
|
||||||
pub action_listeners: SmallVec<[ActionListener; 16]>,
|
pub action_listeners: SmallVec<[DispatchActionListener; 16]>,
|
||||||
pub context: KeyContext,
|
pub context: KeyContext,
|
||||||
parent: Option<DispatchNodeId>,
|
parent: Option<DispatchNodeId>,
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ pub(crate) struct DispatchNode {
|
||||||
type KeyListener = Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>;
|
type KeyListener = Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct ActionListener {
|
pub(crate) struct DispatchActionListener {
|
||||||
pub(crate) action_type: TypeId,
|
pub(crate) action_type: TypeId,
|
||||||
pub(crate) listener: Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
|
pub(crate) listener: Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,9 @@ impl DispatchTree {
|
||||||
action_type: TypeId,
|
action_type: TypeId,
|
||||||
listener: Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
|
listener: Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
|
||||||
) {
|
) {
|
||||||
self.active_node().action_listeners.push(ActionListener {
|
self.active_node()
|
||||||
|
.action_listeners
|
||||||
|
.push(DispatchActionListener {
|
||||||
action_type,
|
action_type,
|
||||||
listener,
|
listener,
|
||||||
});
|
});
|
||||||
|
@ -135,7 +137,7 @@ impl DispatchTree {
|
||||||
if let Some(node) = self.focusable_node_ids.get(&target) {
|
if let Some(node) = self.focusable_node_ids.get(&target) {
|
||||||
for node_id in self.dispatch_path(*node) {
|
for node_id in self.dispatch_path(*node) {
|
||||||
let node = &self.nodes[node_id.0];
|
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());
|
actions.extend(build_action_from_type(action_type).log_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,21 +150,15 @@ impl DispatchTree {
|
||||||
keystroke: &Keystroke,
|
keystroke: &Keystroke,
|
||||||
context: &[KeyContext],
|
context: &[KeyContext],
|
||||||
) -> Option<Box<dyn Action>> {
|
) -> Option<Box<dyn Action>> {
|
||||||
if !self
|
if !self.keystroke_matchers.contains_key(context) {
|
||||||
.keystroke_matchers
|
let keystroke_contexts = context.iter().cloned().collect();
|
||||||
.contains_key(self.context_stack.as_slice())
|
|
||||||
{
|
|
||||||
let keystroke_contexts = self.context_stack.iter().cloned().collect();
|
|
||||||
self.keystroke_matchers.insert(
|
self.keystroke_matchers.insert(
|
||||||
keystroke_contexts,
|
keystroke_contexts,
|
||||||
KeystrokeMatcher::new(self.keymap.clone()),
|
KeystrokeMatcher::new(self.keymap.clone()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let keystroke_matcher = self
|
let keystroke_matcher = self.keystroke_matchers.get_mut(context).unwrap();
|
||||||
.keystroke_matchers
|
|
||||||
.get_mut(self.context_stack.as_slice())
|
|
||||||
.unwrap();
|
|
||||||
if let KeyMatch::Some(action) = keystroke_matcher.match_keystroke(keystroke, context) {
|
if let KeyMatch::Some(action) = keystroke_matcher.match_keystroke(keystroke, context) {
|
||||||
// Clear all pending keystrokes when an action has been found.
|
// Clear all pending keystrokes when an action has been found.
|
||||||
for keystroke_matcher in self.keystroke_matchers.values_mut() {
|
for keystroke_matcher in self.keystroke_matchers.values_mut() {
|
||||||
|
@ -274,7 +270,7 @@ pub trait KeyDispatch<V: 'static>: 'static {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FocusableKeyDispatch<V> {
|
pub struct FocusableKeyDispatch<V> {
|
||||||
pub key_context: KeyContext,
|
pub non_focusable: NonFocusableKeyDispatch,
|
||||||
pub focus_handle: Option<FocusHandle>,
|
pub focus_handle: Option<FocusHandle>,
|
||||||
pub focus_listeners: FocusListeners<V>,
|
pub focus_listeners: FocusListeners<V>,
|
||||||
pub focus_style: StyleRefinement,
|
pub focus_style: StyleRefinement,
|
||||||
|
@ -283,9 +279,9 @@ pub struct FocusableKeyDispatch<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V> FocusableKeyDispatch<V> {
|
impl<V> FocusableKeyDispatch<V> {
|
||||||
pub fn new() -> Self {
|
pub fn new(non_focusable: NonFocusableKeyDispatch) -> Self {
|
||||||
Self {
|
Self {
|
||||||
key_context: KeyContext::default(),
|
non_focusable,
|
||||||
focus_handle: None,
|
focus_handle: None,
|
||||||
focus_listeners: FocusListeners::default(),
|
focus_listeners: FocusListeners::default(),
|
||||||
focus_style: StyleRefinement::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 {
|
Self {
|
||||||
key_context: KeyContext::default(),
|
non_focusable,
|
||||||
focus_handle: Some(handle.clone()),
|
focus_handle: Some(handle.clone()),
|
||||||
focus_listeners: FocusListeners::default(),
|
focus_listeners: FocusListeners::default(),
|
||||||
focus_style: StyleRefinement::default(),
|
focus_style: StyleRefinement::default(),
|
||||||
|
@ -316,24 +312,11 @@ impl<V: 'static> KeyDispatch<V> for FocusableKeyDispatch<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_context(&self) -> &KeyContext {
|
fn key_context(&self) -> &KeyContext {
|
||||||
&self.key_context
|
&self.non_focusable.key_context
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_context_mut(&mut self) -> &mut KeyContext {
|
fn key_context_mut(&mut self) -> &mut KeyContext {
|
||||||
&mut self.key_context
|
&mut self.non_focusable.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(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
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,
|
AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle,
|
||||||
DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
|
DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
|
||||||
EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla, ImageData,
|
EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla, ImageData,
|
||||||
|
@ -1306,7 +1306,7 @@ impl<'a> WindowContext<'a> {
|
||||||
// Capture phase
|
// Capture phase
|
||||||
for node_id in &dispatch_path {
|
for node_id in &dispatch_path {
|
||||||
let node = self.window.current_frame.dispatch_tree.node(*node_id);
|
let node = self.window.current_frame.dispatch_tree.node(*node_id);
|
||||||
for ActionListener {
|
for DispatchActionListener {
|
||||||
action_type,
|
action_type,
|
||||||
listener,
|
listener,
|
||||||
} in node.action_listeners.clone()
|
} in node.action_listeners.clone()
|
||||||
|
@ -1324,7 +1324,7 @@ impl<'a> WindowContext<'a> {
|
||||||
// Bubble phase
|
// Bubble phase
|
||||||
for node_id in dispatch_path.iter().rev() {
|
for node_id in dispatch_path.iter().rev() {
|
||||||
let node = self.window.current_frame.dispatch_tree.node(*node_id);
|
let node = self.window.current_frame.dispatch_tree.node(*node_id);
|
||||||
for ActionListener {
|
for DispatchActionListener {
|
||||||
action_type,
|
action_type,
|
||||||
listener,
|
listener,
|
||||||
} in node.action_listeners.clone()
|
} in node.action_listeners.clone()
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, uniform_list, Component, Div, FocusableKeyDispatch, ParentElement, Render,
|
div, uniform_list, Component, Div, ParentElement, Render, StatelessInteractive, Styled, Task,
|
||||||
StatefulInteractivity, StatelessInteractive, Styled, Task, UniformListScrollHandle, View,
|
UniformListScrollHandle, View, ViewContext, VisualContext, WindowContext,
|
||||||
ViewContext, VisualContext, WindowContext,
|
|
||||||
};
|
};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
|
@ -137,13 +136,11 @@ impl<D: PickerDelegate> Picker<D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: PickerDelegate> Render for 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 {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
div()
|
div()
|
||||||
.context("picker")
|
.context("picker")
|
||||||
.id("picker-container")
|
|
||||||
.focusable()
|
|
||||||
.size_full()
|
.size_full()
|
||||||
.on_action(Self::select_next)
|
.on_action(Self::select_next)
|
||||||
.on_action(Self::select_prev)
|
.on_action(Self::select_prev)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue