vim: Prevent flickering during movement actions (#52270)
Finn Eitreim
and
Cameron Mcloughlin
created
## Context
Closes #52202
Some actions we're unnecessarily delayed during execution by a
yield_now().await call, causing flickering while moving around.
Video Before:
https://github.com/user-attachments/assets/f9922915-8bc7-4e9e-8ce9-18a1e898b69e
Video After:
https://github.com/user-attachments/assets/a46a6338-3fef-4784-8fd7-ecec07a28cf6
## How to Review
when we call the yield in workspace.rs
## Self-Review Checklist
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- vim: fixed screen flickering during motions.
Co-authored-by: Cameron Mcloughlin <cameron.studdstreet@gmail.com>
@@ -3364,24 +3364,27 @@ impl Workspace {
};
keystroke
};
- cx.update(|window, cx| {- let focused = window.focused(cx);- window.dispatch_keystroke(keystroke.clone(), cx);- if window.focused(cx) != focused {- // dispatch_keystroke may cause the focus to change.- // draw's side effect is to schedule the FocusChanged events in the current flush effect cycle- // And we need that to happen before the next keystroke to keep vim mode happy...- // (Note that the tests always do this implicitly, so you must manually test with something like:- // "bindings": { "g z": ["workspace::SendKeystrokes", ": j <enter> u"]}- // )- window.draw(cx).clear();- }- })- .ok();
+ let focus_changed = cx
+ .update(|window, cx| {
+ let focused = window.focused(cx);
+ window.dispatch_keystroke(keystroke.clone(), cx);
+ if window.focused(cx) != focused {
+ // dispatch_keystroke may cause the focus to change.
+ // draw's side effect is to schedule the FocusChanged events in the current flush effect cycle
+ // And we need that to happen before the next keystroke to keep vim mode happy...
+ // (Note that the tests always do this implicitly, so you must manually test with something like:
+ // "bindings": { "g z": ["workspace::SendKeystrokes", ": j <enter> u"]}
+ // )
+ window.draw(cx).clear();
+ return true;
+ }
+ false
+ })
+ .unwrap_or(false);
- // Yield between synthetic keystrokes so deferred focus and- // other effects can settle before dispatching the next key.- yield_now().await;
+ if focus_changed {
+ yield_now().await;
+ }
}
*keystrokes.borrow_mut() = Default::default();