Work on tests
This commit is contained in:
@@ -277,7 +277,7 @@ impl DispatchTree {
|
||||
keystroke: &Keystroke,
|
||||
dispatch_path: &SmallVec<[DispatchNodeId; 32]>,
|
||||
) -> KeymatchResult {
|
||||
let mut actions = SmallVec::new();
|
||||
let mut bindings = SmallVec::new();
|
||||
let mut pending = false;
|
||||
|
||||
let mut context_stack: SmallVec<[KeyContext; 4]> = SmallVec::new();
|
||||
@@ -297,11 +297,11 @@ impl DispatchTree {
|
||||
|
||||
let mut result = keystroke_matcher.match_keystroke(keystroke, &context_stack);
|
||||
pending = result.pending || pending;
|
||||
actions.append(&mut result.actions);
|
||||
bindings.append(&mut result.bindings);
|
||||
context_stack.pop();
|
||||
}
|
||||
|
||||
KeymatchResult { actions, pending }
|
||||
KeymatchResult { bindings, pending }
|
||||
}
|
||||
|
||||
pub fn has_pending_keystrokes(&self) -> bool {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{Action, KeyContext, Keymap, KeymapVersion, Keystroke};
|
||||
use crate::{KeyBinding, KeyContext, Keymap, KeymapVersion, Keystroke};
|
||||
use parking_lot::Mutex;
|
||||
use smallvec::SmallVec;
|
||||
use std::sync::Arc;
|
||||
@@ -10,7 +10,7 @@ pub(crate) struct KeystrokeMatcher {
|
||||
}
|
||||
|
||||
pub struct KeymatchResult {
|
||||
pub actions: SmallVec<[Box<dyn Action>; 1]>,
|
||||
pub bindings: SmallVec<[KeyBinding; 1]>,
|
||||
pub pending: bool,
|
||||
}
|
||||
|
||||
@@ -24,10 +24,6 @@ impl KeystrokeMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_pending(&mut self) {
|
||||
self.pending_keystrokes.clear();
|
||||
}
|
||||
|
||||
pub fn has_pending_keystrokes(&self) -> bool {
|
||||
!self.pending_keystrokes.is_empty()
|
||||
}
|
||||
@@ -54,7 +50,7 @@ impl KeystrokeMatcher {
|
||||
}
|
||||
|
||||
let mut pending_key = None;
|
||||
let mut actions = SmallVec::new();
|
||||
let mut bindings = SmallVec::new();
|
||||
|
||||
for binding in keymap.bindings().rev() {
|
||||
if !keymap.binding_enabled(binding, context_stack) {
|
||||
@@ -65,7 +61,7 @@ impl KeystrokeMatcher {
|
||||
self.pending_keystrokes.push(candidate.clone());
|
||||
match binding.match_keystrokes(&self.pending_keystrokes) {
|
||||
KeyMatch::Matched => {
|
||||
actions.push(binding.action.boxed_clone());
|
||||
bindings.push(binding.clone());
|
||||
}
|
||||
KeyMatch::Pending => {
|
||||
pending_key.get_or_insert(candidate);
|
||||
@@ -76,6 +72,12 @@ impl KeystrokeMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
if bindings.len() == 0 && pending_key.is_none() && self.pending_keystrokes.len() > 0 {
|
||||
drop(keymap);
|
||||
self.pending_keystrokes.remove(0);
|
||||
return self.match_keystroke(keystroke, context_stack);
|
||||
}
|
||||
|
||||
let pending = if let Some(pending_key) = pending_key {
|
||||
self.pending_keystrokes.push(pending_key);
|
||||
true
|
||||
@@ -84,7 +86,7 @@ impl KeystrokeMatcher {
|
||||
false
|
||||
};
|
||||
|
||||
KeymatchResult { actions, pending }
|
||||
KeymatchResult { bindings, pending }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,4 +100,3 @@ pub enum KeyMatch {
|
||||
Pending,
|
||||
Matched,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
use crate::{
|
||||
px, AnyWindowHandle, AtlasKey, AtlasTextureId, AtlasTile, Bounds, KeyDownEvent, Keystroke,
|
||||
Pixels, Platform, PlatformAtlas, PlatformDisplay, PlatformInput, PlatformInputHandler,
|
||||
PlatformWindow, Point, Size, TestPlatform, TileId, WindowAppearance, WindowBounds,
|
||||
WindowOptions,
|
||||
Pixels, PlatformAtlas, PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow,
|
||||
Point, Size, TestPlatform, TileId, WindowAppearance, WindowBounds, WindowOptions,
|
||||
};
|
||||
use collections::HashMap;
|
||||
use parking_lot::Mutex;
|
||||
@@ -97,7 +96,19 @@ impl TestWindow {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn simulate_keystroke(&mut self, keystroke: Keystroke, is_held: bool) {
|
||||
pub fn simulate_keystroke(&mut self, mut keystroke: Keystroke, is_held: bool) {
|
||||
if keystroke.ime_key.is_none()
|
||||
&& !keystroke.modifiers.command
|
||||
&& !keystroke.modifiers.control
|
||||
&& !keystroke.modifiers.function
|
||||
{
|
||||
keystroke.ime_key = Some(if keystroke.modifiers.shift {
|
||||
keystroke.key.to_ascii_uppercase().clone()
|
||||
} else {
|
||||
keystroke.key.clone()
|
||||
})
|
||||
}
|
||||
|
||||
if self.simulate_input(PlatformInput::KeyDown(KeyDownEvent {
|
||||
keystroke: keystroke.clone(),
|
||||
is_held,
|
||||
@@ -113,8 +124,9 @@ impl TestWindow {
|
||||
);
|
||||
};
|
||||
drop(lock);
|
||||
let text = keystroke.ime_key.unwrap_or(keystroke.key);
|
||||
input_handler.replace_text_in_range(None, &text);
|
||||
if let Some(text) = keystroke.ime_key.as_ref() {
|
||||
input_handler.replace_text_in_range(None, &text);
|
||||
}
|
||||
|
||||
self.0.lock().input_handler = Some(input_handler);
|
||||
}
|
||||
|
||||
+22
-12
@@ -289,10 +289,10 @@ pub struct Window {
|
||||
pub(crate) focus_invalidated: bool,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Debug)]
|
||||
struct PendingInput {
|
||||
text: String,
|
||||
actions: SmallVec<[Box<dyn Action>; 1]>,
|
||||
bindings: SmallVec<[KeyBinding; 1]>,
|
||||
focus: Option<FocusId>,
|
||||
timer: Option<Task<()>>,
|
||||
}
|
||||
@@ -1796,7 +1796,7 @@ impl<'a> WindowContext<'a> {
|
||||
.dispatch_path(node_id);
|
||||
|
||||
if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
|
||||
let KeymatchResult { actions, pending } = self
|
||||
let KeymatchResult { bindings, pending } = self
|
||||
.window
|
||||
.rendered_frame
|
||||
.dispatch_tree
|
||||
@@ -1812,8 +1812,8 @@ impl<'a> WindowContext<'a> {
|
||||
if let Some(new_text) = &key_down_event.keystroke.ime_key.as_ref() {
|
||||
currently_pending.text += new_text
|
||||
}
|
||||
for action in actions {
|
||||
currently_pending.actions.push(action);
|
||||
for binding in bindings {
|
||||
currently_pending.bindings.push(binding);
|
||||
}
|
||||
|
||||
currently_pending.timer = Some(self.spawn(|mut cx| async move {
|
||||
@@ -1832,20 +1832,30 @@ impl<'a> WindowContext<'a> {
|
||||
self.propagate_event = false;
|
||||
return;
|
||||
} else if let Some(currently_pending) = self.window.pending_input.take() {
|
||||
if actions.is_empty() {
|
||||
// if you have bound , to one thing, and ,w to another.
|
||||
// then typing ,i should trigger the comma actions, then the i actions.
|
||||
// in that scenario "binding.keystrokes" is "i" and "pending.keystrokes" is ",".
|
||||
// on the other hand if you type ,, it should not trigger the , action.
|
||||
// in that scenario "binding.keystrokes" is ",w" and "pending.keystrokes" is ",".
|
||||
|
||||
if bindings.iter().all(|binding| {
|
||||
currently_pending.bindings.iter().all(|pending| {
|
||||
dbg!(!dbg!(binding.keystrokes()).starts_with(dbg!(&pending.keystrokes)))
|
||||
})
|
||||
}) {
|
||||
self.replay_pending_input(currently_pending)
|
||||
}
|
||||
}
|
||||
|
||||
if !actions.is_empty() {
|
||||
if !bindings.is_empty() {
|
||||
self.clear_pending_keystrokes();
|
||||
}
|
||||
|
||||
self.propagate_event = true;
|
||||
for action in actions {
|
||||
self.dispatch_action_on_node(node_id, action.boxed_clone());
|
||||
for binding in bindings {
|
||||
self.dispatch_action_on_node(node_id, binding.action.boxed_clone());
|
||||
if !self.propagate_event {
|
||||
self.dispatch_keystroke_observers(event, Some(action));
|
||||
self.dispatch_keystroke_observers(event, Some(binding.action));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1903,8 +1913,8 @@ impl<'a> WindowContext<'a> {
|
||||
}
|
||||
|
||||
self.propagate_event = true;
|
||||
for action in currently_pending.actions {
|
||||
self.dispatch_action_on_node(node_id, action);
|
||||
for binding in currently_pending.bindings {
|
||||
self.dispatch_action_on_node(node_id, binding.action.boxed_clone());
|
||||
if !self.propagate_event {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user