Ensure querying keystrokes or actions is safe

This is achieved by moving `available_actions` into `AsyncAppContext` (where
we know no view/window is on the stack) and `keystrokes_for_action` into `LayoutContext`
where we'll fetch the previous frame's ancestors and notify the current view if those
change after we perform a layout.
This commit is contained in:
Antonio Scandurra 2023-05-04 09:34:42 +02:00
parent 040cc4d4c3
commit 92183e0d72
9 changed files with 233 additions and 164 deletions

View file

@ -1,7 +1,7 @@
use crate::{
executor,
geometry::vector::Vector2F,
keymap_matcher::Keystroke,
keymap_matcher::{Binding, Keystroke},
platform,
platform::{Event, InputHandler, KeyDownEvent, Platform},
Action, AppContext, BorrowAppContext, BorrowWindowContext, Entity, FontCache, Handle,
@ -12,6 +12,7 @@ use collections::BTreeMap;
use futures::Future;
use itertools::Itertools;
use parking_lot::{Mutex, RwLock};
use smallvec::SmallVec;
use smol::stream::StreamExt;
use std::{
any::Any,
@ -71,17 +72,24 @@ impl TestAppContext {
cx
}
pub fn dispatch_action<A: Action>(&self, window_id: usize, action: A) {
self.cx
.borrow_mut()
.update_window(window_id, |window| {
window.dispatch_action(window.focused_view_id(), &action);
})
.expect("window not found");
pub fn dispatch_action<A: Action>(&mut self, window_id: usize, action: A) {
self.update_window(window_id, |window| {
window.dispatch_action(window.focused_view_id(), &action);
})
.expect("window not found");
}
pub fn dispatch_global_action<A: Action>(&self, action: A) {
self.cx.borrow_mut().dispatch_global_action_any(&action);
pub fn available_actions(
&self,
window_id: usize,
view_id: usize,
) -> Vec<(&'static str, Box<dyn Action>, SmallVec<[Binding; 1]>)> {
self.read_window(window_id, |cx| cx.available_actions(view_id))
.unwrap_or_default()
}
pub fn dispatch_global_action<A: Action>(&mut self, action: A) {
self.update(|cx| cx.dispatch_global_action_any(&action));
}
pub fn dispatch_keystroke(&mut self, window_id: usize, keystroke: Keystroke, is_held: bool) {