@@ -15,12 +15,12 @@ use crate::{
use anyhow::Result;
use collections::{BTreeMap, HashMap};
use gpui::{
- black, hsla, point, px, relative, size, transparent_black, Action, ActionListener, AnyElement,
- AvailableSpace, BorrowAppContext, BorrowWindow, Bounds, ContentMask, Corners, DispatchPhase,
- Edges, Element, ElementId, ElementInputHandler, Entity, FocusHandle, GlobalElementId, Hsla,
- InputHandler, KeyContext, KeyDownEvent, KeyMatch, Line, LineLayout, Modifiers, MouseButton,
- MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, ScrollWheelEvent, ShapedGlyph, Size,
- Style, TextRun, TextStyle, TextSystem, ViewContext, WindowContext, WrappedLineLayout,
+ black, hsla, point, px, relative, size, transparent_black, Action, AnyElement, AvailableSpace,
+ BorrowAppContext, BorrowWindow, Bounds, ContentMask, Corners, DispatchPhase, Edges, Element,
+ ElementId, ElementInputHandler, Entity, FocusHandle, GlobalElementId, Hsla, InputHandler,
+ KeyContext, KeyDownEvent, KeyMatch, Line, LineLayout, Modifiers, MouseButton, MouseDownEvent,
+ MouseMoveEvent, MouseUpEvent, Pixels, ScrollWheelEvent, ShapedGlyph, Size, Style, TextRun,
+ TextStyle, TextSystem, ViewContext, WindowContext, WrappedLineLayout,
};
use itertools::Itertools;
use language::language_settings::ShowWhitespaceSetting;
@@ -1,6 +1,6 @@
use crate::{
build_action_from_type, Action, Bounds, DispatchPhase, Element, FocusEvent, FocusHandle,
- FocusId, KeyContext, KeyDownEvent, KeyMatch, Keymap, KeystrokeMatcher, MouseDownEvent, Pixels,
+ FocusId, KeyContext, KeyMatch, Keymap, Keystroke, KeystrokeMatcher, MouseDownEvent, Pixels,
Style, StyleRefinement, ViewContext, WindowContext,
};
use collections::HashMap;
@@ -9,11 +9,11 @@ use refineable::Refineable;
use smallvec::SmallVec;
use std::{
any::{Any, TypeId},
+ rc::Rc,
sync::Arc,
};
use util::ResultExt;
-type KeyListener = Box<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>;
pub type FocusListeners<V> = SmallVec<[FocusListener<V>; 2]>;
pub type FocusListener<V> =
Box<dyn Fn(&mut V, &FocusHandle, &FocusEvent, &mut ViewContext<V>) + 'static>;
@@ -21,7 +21,7 @@ pub type FocusListener<V> =
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct DispatchNodeId(usize);
-pub struct KeyDispatcher {
+pub(crate) struct DispatchTree {
node_stack: Vec<DispatchNodeId>,
context_stack: Vec<KeyContext>,
nodes: Vec<DispatchNode>,
@@ -31,19 +31,22 @@ pub struct KeyDispatcher {
}
#[derive(Default)]
-pub struct DispatchNode {
- key_listeners: SmallVec<[KeyListener; 2]>,
- action_listeners: SmallVec<[ActionListener; 16]>,
- context: KeyContext,
+pub(crate) struct DispatchNode {
+ pub key_listeners: SmallVec<[KeyListener; 2]>,
+ pub action_listeners: SmallVec<[ActionListener; 16]>,
+ pub context: KeyContext,
parent: Option<DispatchNodeId>,
}
-struct ActionListener {
- action_type: TypeId,
- listener: Box<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
+type KeyListener = Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>;
+
+#[derive(Clone)]
+pub(crate) struct ActionListener {
+ pub(crate) action_type: TypeId,
+ pub(crate) listener: Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
}
-impl KeyDispatcher {
+impl DispatchTree {
pub fn new(keymap: Arc<Mutex<Keymap>>) -> Self {
Self {
node_stack: Vec::new(),
@@ -97,7 +100,7 @@ impl KeyDispatcher {
pub fn on_action(
&mut self,
action_type: TypeId,
- listener: Box<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
+ listener: Rc<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
) {
self.active_node().action_listeners.push(ActionListener {
action_type,
@@ -140,143 +143,40 @@ impl KeyDispatcher {
actions
}
- pub fn dispatch_key(&mut self, target: FocusId, event: &dyn Any, cx: &mut WindowContext) {
- if let Some(target_node_id) = self.focusable_node_ids.get(&target).copied() {
- self.dispatch_key_on_node(target_node_id, event, cx);
- }
- }
-
- fn dispatch_key_on_node(
+ pub fn dispatch_key(
&mut self,
- node_id: DispatchNodeId,
- event: &dyn Any,
- cx: &mut WindowContext,
- ) {
- let dispatch_path = self.dispatch_path(node_id);
-
- // Capture phase
- self.context_stack.clear();
- cx.propagate_event = true;
-
- for node_id in &dispatch_path {
- let node = &self.nodes[node_id.0];
- if !node.context.is_empty() {
- self.context_stack.push(node.context.clone());
- }
-
- for key_listener in &node.key_listeners {
- key_listener(event, DispatchPhase::Capture, cx);
- if !cx.propagate_event {
- return;
- }
- }
+ 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();
+ self.keystroke_matchers.insert(
+ keystroke_contexts,
+ KeystrokeMatcher::new(self.keymap.clone()),
+ );
}
- // Bubble phase
- for node_id in dispatch_path.iter().rev() {
- let node = &self.nodes[node_id.0];
-
- // Handle low level key events
- for key_listener in &node.key_listeners {
- key_listener(event, DispatchPhase::Bubble, cx);
- if !cx.propagate_event {
- return;
- }
- }
-
- // Match keystrokes
- if !node.context.is_empty() {
- if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
- if !self
- .keystroke_matchers
- .contains_key(self.context_stack.as_slice())
- {
- let keystroke_contexts = self.context_stack.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();
- if let KeyMatch::Some(action) = keystroke_matcher
- .match_keystroke(&key_down_event.keystroke, self.context_stack.as_slice())
- {
- // Clear all pending keystrokes when an action has been found.
- for keystroke_matcher in self.keystroke_matchers.values_mut() {
- keystroke_matcher.clear_pending();
- }
-
- self.dispatch_action_on_node(*node_id, action, cx);
- if !cx.propagate_event {
- return;
- }
- }
- }
-
- self.context_stack.pop();
+ let keystroke_matcher = self
+ .keystroke_matchers
+ .get_mut(self.context_stack.as_slice())
+ .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() {
+ keystroke_matcher.clear_pending();
}
- }
- }
- pub fn dispatch_action(
- &self,
- target: FocusId,
- action: Box<dyn Action>,
- cx: &mut WindowContext,
- ) {
- if let Some(target_node_id) = self.focusable_node_ids.get(&target).copied() {
- self.dispatch_action_on_node(target_node_id, action, cx);
+ Some(action)
+ } else {
+ None
}
}
- fn dispatch_action_on_node(
- &self,
- node_id: DispatchNodeId,
- action: Box<dyn Action>,
- cx: &mut WindowContext,
- ) {
- let dispatch_path = self.dispatch_path(node_id);
-
- // Capture phase
- for node_id in &dispatch_path {
- let node = &self.nodes[node_id.0];
- for ActionListener {
- action_type,
- listener,
- } in &node.action_listeners
- {
- let any_action = action.as_any();
- if *action_type == any_action.type_id() {
- listener(any_action, DispatchPhase::Capture, cx);
- if !cx.propagate_event {
- return;
- }
- }
- }
- }
-
- // Bubble phase
- for node_id in dispatch_path.iter().rev() {
- let node = &self.nodes[node_id.0];
- for ActionListener {
- action_type,
- listener,
- } in &node.action_listeners
- {
- let any_action = action.as_any();
- if *action_type == any_action.type_id() {
- cx.propagate_event = false; // Actions stop propagation by default during the bubble phase
- listener(any_action, DispatchPhase::Bubble, cx);
- if !cx.propagate_event {
- return;
- }
- }
- }
- }
+ pub fn node(&self, node_id: DispatchNodeId) -> &DispatchNode {
+ &self.nodes[node_id.0]
}
fn active_node(&mut self) -> &mut DispatchNode {
@@ -288,8 +188,7 @@ impl KeyDispatcher {
*self.node_stack.last().unwrap()
}
- /// Returns the DispatchNodeIds from the root of the tree to the given target node id.
- fn dispatch_path(&self, target: DispatchNodeId) -> SmallVec<[DispatchNodeId; 32]> {
+ pub fn dispatch_path(&self, target: DispatchNodeId) -> SmallVec<[DispatchNodeId; 32]> {
let mut dispatch_path: SmallVec<[DispatchNodeId; 32]> = SmallVec::new();
let mut current_node_id = Some(target);
while let Some(node_id) = current_node_id {
@@ -299,6 +198,10 @@ impl KeyDispatcher {
dispatch_path.reverse(); // Reverse the path so it goes from the root to the focused node.
dispatch_path
}
+
+ pub fn focusable_node_id(&self, target: FocusId) -> Option<DispatchNodeId> {
+ self.focusable_node_ids.get(&target).copied()
+ }
}
pub trait KeyDispatch<V: 'static>: 'static {
@@ -1,14 +1,15 @@
use crate::{
- px, size, Action, AnyBox, AnyDrag, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
- Bounds, BoxShadow, Context, Corners, CursorStyle, DevicePixels, DisplayId, Edges, Effect,
- Entity, EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId,
- Hsla, ImageData, InputEvent, IsZero, KeyContext, KeyDispatcher, LayoutId, Model, ModelContext,
- Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path,
- Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
- PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
- RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet,
- Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext,
- WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
+ key_dispatch::ActionListener, 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,
+ InputEvent, IsZero, KeyContext, KeyDownEvent, LayoutId, Model, ModelContext, Modifiers,
+ MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels,
+ PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, PolychromeSprite,
+ PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels,
+ SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet, Subscription,
+ TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext, WeakView,
+ WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
};
use anyhow::{anyhow, Result};
use collections::HashMap;
@@ -89,9 +90,7 @@ impl FocusId {
pub(crate) fn contains(&self, other: Self, cx: &WindowContext) -> bool {
cx.window
.current_frame
- .key_dispatcher
- .as_ref()
- .unwrap()
+ .dispatch_tree
.focus_contains(*self, other)
}
}
@@ -213,7 +212,7 @@ pub struct Window {
pub(crate) struct Frame {
element_states: HashMap<GlobalElementId, AnyBox>,
mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, AnyMouseListener)>>,
- pub(crate) key_dispatcher: Option<KeyDispatcher>,
+ pub(crate) dispatch_tree: DispatchTree,
pub(crate) focus_listeners: Vec<AnyFocusListener>,
pub(crate) scene_builder: SceneBuilder,
z_index_stack: StackingOrder,
@@ -222,11 +221,11 @@ pub(crate) struct Frame {
}
impl Frame {
- pub fn new(key_dispatcher: KeyDispatcher) -> Self {
+ pub fn new(dispatch_tree: DispatchTree) -> Self {
Frame {
element_states: HashMap::default(),
mouse_listeners: HashMap::default(),
- key_dispatcher: Some(key_dispatcher),
+ dispatch_tree,
focus_listeners: Vec::new(),
scene_builder: SceneBuilder::default(),
z_index_stack: StackingOrder::default(),
@@ -302,8 +301,8 @@ impl Window {
layout_engine: TaffyLayoutEngine::new(),
root_view: None,
element_id_stack: GlobalElementId::default(),
- previous_frame: Frame::new(KeyDispatcher::new(cx.keymap.clone())),
- current_frame: Frame::new(KeyDispatcher::new(cx.keymap.clone())),
+ previous_frame: Frame::new(DispatchTree::new(cx.keymap.clone())),
+ current_frame: Frame::new(DispatchTree::new(cx.keymap.clone())),
focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
focus_listeners: SubscriberSet::new(),
default_prevented: true,
@@ -423,9 +422,14 @@ impl<'a> WindowContext<'a> {
pub fn dispatch_action(&mut self, action: Box<dyn Action>) {
if let Some(focus_handle) = self.focused() {
self.defer(move |cx| {
- let dispatcher = cx.window.current_frame.key_dispatcher.take().unwrap();
- dispatcher.dispatch_action(focus_handle.id, action, cx);
- cx.window.current_frame.key_dispatcher = Some(dispatcher);
+ if let Some(node_id) = cx
+ .window
+ .current_frame
+ .dispatch_tree
+ .focusable_node_id(focus_handle.id)
+ {
+ cx.dispatch_action_on_node(node_id, action);
+ }
})
}
}
@@ -723,12 +727,14 @@ impl<'a> WindowContext<'a> {
&mut self,
handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static,
) {
- let key_dispatcher = self.window.current_frame.key_dispatcher.as_mut().unwrap();
- key_dispatcher.on_key_event(Box::new(move |event, phase, cx| {
- if let Some(event) = event.downcast_ref::<Event>() {
- handler(event, phase, cx)
- }
- }));
+ self.window
+ .current_frame
+ .dispatch_tree
+ .on_key_event(Rc::new(move |event, phase, cx| {
+ if let Some(event) = event.downcast_ref::<Event>() {
+ handler(event, phase, cx)
+ }
+ }));
}
/// Register an action listener on the window for the current frame. The type of action
@@ -742,10 +748,9 @@ impl<'a> WindowContext<'a> {
action_type: TypeId,
handler: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static,
) {
- let key_dispatcher = self.window.current_frame.key_dispatcher.as_mut().unwrap();
- key_dispatcher.on_action(
+ self.window.current_frame.dispatch_tree.on_action(
action_type,
- Box::new(move |action, phase, cx| handler(action, phase, cx)),
+ Rc::new(move |action, phase, cx| handler(action, phase, cx)),
);
}
@@ -1110,7 +1115,7 @@ impl<'a> WindowContext<'a> {
frame.element_states.clear();
frame.mouse_listeners.values_mut().for_each(Vec::clear);
frame.focus_listeners.clear();
- frame.key_dispatcher.as_mut().map(KeyDispatcher::clear);
+ frame.dispatch_tree.clear();
}
/// Dispatch a mouse or keyboard event on the window.
@@ -1172,63 +1177,172 @@ impl<'a> WindowContext<'a> {
};
if let Some(any_mouse_event) = event.mouse_event() {
- if let Some(mut handlers) = self
- .window
- .current_frame
- .mouse_listeners
- .remove(&any_mouse_event.type_id())
- {
- // Because handlers may add other handlers, we sort every time.
- handlers.sort_by(|(a, _), (b, _)| a.cmp(b));
+ self.dispatch_mouse_event(any_mouse_event);
+ } else if let Some(any_key_event) = event.keyboard_event() {
+ self.dispatch_key_event(any_key_event);
+ }
- // Capture phase, events bubble from back to front. Handlers for this phase are used for
- // special purposes, such as detecting events outside of a given Bounds.
- for (_, handler) in &mut handlers {
- handler(any_mouse_event, DispatchPhase::Capture, self);
+ !self.app.propagate_event
+ }
+
+ fn dispatch_mouse_event(&mut self, event: &dyn Any) {
+ if let Some(mut handlers) = self
+ .window
+ .current_frame
+ .mouse_listeners
+ .remove(&event.type_id())
+ {
+ // Because handlers may add other handlers, we sort every time.
+ handlers.sort_by(|(a, _), (b, _)| a.cmp(b));
+
+ // Capture phase, events bubble from back to front. Handlers for this phase are used for
+ // special purposes, such as detecting events outside of a given Bounds.
+ for (_, handler) in &mut handlers {
+ handler(event, DispatchPhase::Capture, self);
+ if !self.app.propagate_event {
+ break;
+ }
+ }
+
+ // Bubble phase, where most normal handlers do their work.
+ if self.app.propagate_event {
+ for (_, handler) in handlers.iter_mut().rev() {
+ handler(event, DispatchPhase::Bubble, self);
if !self.app.propagate_event {
break;
}
}
+ }
- // Bubble phase, where most normal handlers do their work.
- if self.app.propagate_event {
- for (_, handler) in handlers.iter_mut().rev() {
- handler(any_mouse_event, DispatchPhase::Bubble, self);
- if !self.app.propagate_event {
- break;
- }
+ if self.app.propagate_event && event.downcast_ref::<MouseUpEvent>().is_some() {
+ self.active_drag = None;
+ }
+
+ // Just in case any handlers added new handlers, which is weird, but possible.
+ handlers.extend(
+ self.window
+ .current_frame
+ .mouse_listeners
+ .get_mut(&event.type_id())
+ .into_iter()
+ .flat_map(|handlers| handlers.drain(..)),
+ );
+ self.window
+ .current_frame
+ .mouse_listeners
+ .insert(event.type_id(), handlers);
+ }
+ }
+
+ fn dispatch_key_event(&mut self, event: &dyn Any) {
+ if let Some(node_id) = self.window.focus.and_then(|focus_id| {
+ self.window
+ .current_frame
+ .dispatch_tree
+ .focusable_node_id(focus_id)
+ }) {
+ let dispatch_path = self
+ .window
+ .current_frame
+ .dispatch_tree
+ .dispatch_path(node_id);
+
+ // Capture phase
+ let mut context_stack: SmallVec<[KeyContext; 16]> = SmallVec::new();
+ self.propagate_event = true;
+
+ for node_id in &dispatch_path {
+ let node = self.window.current_frame.dispatch_tree.node(*node_id);
+
+ if !node.context.is_empty() {
+ context_stack.push(node.context.clone());
+ }
+
+ for key_listener in node.key_listeners.clone() {
+ key_listener(event, DispatchPhase::Capture, self);
+ if !self.propagate_event {
+ return;
}
}
+ }
- if self.app.propagate_event
- && any_mouse_event.downcast_ref::<MouseUpEvent>().is_some()
- {
- self.active_drag = None;
+ // Bubble phase
+ for node_id in dispatch_path.iter().rev() {
+ // Handle low level key events
+ let node = self.window.current_frame.dispatch_tree.node(*node_id);
+ for key_listener in node.key_listeners.clone() {
+ key_listener(event, DispatchPhase::Bubble, self);
+ if !self.propagate_event {
+ return;
+ }
}
- // Just in case any handlers added new handlers, which is weird, but possible.
- handlers.extend(
- self.window
- .current_frame
- .mouse_listeners
- .get_mut(&any_mouse_event.type_id())
- .into_iter()
- .flat_map(|handlers| handlers.drain(..)),
- );
- self.window
- .current_frame
- .mouse_listeners
- .insert(any_mouse_event.type_id(), handlers);
+ // Match keystrokes
+ let node = self.window.current_frame.dispatch_tree.node(*node_id);
+ if !node.context.is_empty() {
+ if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
+ if let Some(action) = self
+ .window
+ .current_frame
+ .dispatch_tree
+ .dispatch_key(&key_down_event.keystroke, &context_stack)
+ {
+ self.dispatch_action_on_node(*node_id, action);
+ if !self.propagate_event {
+ return;
+ }
+ }
+ }
+
+ context_stack.pop();
+ }
}
- } else if let Some(any_key_event) = event.keyboard_event() {
- if let Some(focus_id) = self.window.focus {
- let mut dispatcher = self.window.current_frame.key_dispatcher.take().unwrap();
- dispatcher.dispatch_key(focus_id, any_key_event, self);
- self.window.current_frame.key_dispatcher = Some(dispatcher);
+ }
+ }
+
+ fn dispatch_action_on_node(&mut self, node_id: DispatchNodeId, action: Box<dyn Action>) {
+ let dispatch_path = self
+ .window
+ .current_frame
+ .dispatch_tree
+ .dispatch_path(node_id);
+
+ // Capture phase
+ for node_id in &dispatch_path {
+ let node = self.window.current_frame.dispatch_tree.node(*node_id);
+ for ActionListener {
+ action_type,
+ listener,
+ } in node.action_listeners.clone()
+ {
+ let any_action = action.as_any();
+ if action_type == any_action.type_id() {
+ listener(any_action, DispatchPhase::Capture, self);
+ if !self.propagate_event {
+ return;
+ }
+ }
}
}
- !self.app.propagate_event
+ // Bubble phase
+ for node_id in dispatch_path.iter().rev() {
+ let node = self.window.current_frame.dispatch_tree.node(*node_id);
+ for ActionListener {
+ action_type,
+ listener,
+ } in node.action_listeners.clone()
+ {
+ let any_action = action.as_any();
+ if action_type == any_action.type_id() {
+ self.propagate_event = false; // Actions stop propagation by default during the bubble phase
+ listener(any_action, DispatchPhase::Bubble, self);
+ if !self.propagate_event {
+ return;
+ }
+ }
+ }
+ }
}
/// Register the given handler to be invoked whenever the global of the given type
@@ -1261,9 +1375,7 @@ impl<'a> WindowContext<'a> {
if let Some(focus_id) = self.window.focus {
self.window
.current_frame
- .key_dispatcher
- .as_ref()
- .unwrap()
+ .dispatch_tree
.available_actions(focus_id)
} else {
Vec::new()
@@ -1926,17 +2038,20 @@ impl<'a, V: 'static> ViewContext<'a, V> {
f: impl FnOnce(Option<FocusHandle>, &mut Self) -> R,
) -> R {
let window = &mut self.window;
- let old_dispatcher = window.previous_frame.key_dispatcher.as_mut().unwrap();
- let current_dispatcher = window.current_frame.key_dispatcher.as_mut().unwrap();
- current_dispatcher.push_node(context, old_dispatcher);
+ window
+ .current_frame
+ .dispatch_tree
+ .push_node(context, &mut window.previous_frame.dispatch_tree);
if let Some(focus_handle) = focus_handle.as_ref() {
- current_dispatcher.make_focusable(focus_handle.id);
+ window
+ .current_frame
+ .dispatch_tree
+ .make_focusable(focus_handle.id);
}
let result = f(focus_handle, self);
- let current_dispatcher = self.window.current_frame.key_dispatcher.as_mut().unwrap();
- current_dispatcher.pop_node();
+ self.window.current_frame.dispatch_tree.pop_node();
result
}