Fix slow focus transitions to the terminal panel (#24172)
This long standing bug was caused by `Pane`'s focus_in handler bouncing the focus to another handle. Because focus resolution happens _after_ a frame has been rendered, the only way to deal with this case is to schedule another frame to be redrawn. However, we where suppressing all window refreshes that occur during a focus transfer, causing this focus change to be completely missed. However, changing this behavior can lead to infinite notify loops, due to drawing a frame causing another to be rendered. This PR fixes this problem narrowly by adding an `on_next_frame()` callback in the pane's focus handle, so that the focus changes take effect almost immediately. But only for this case, where we know it doesn't cause infinite notify loops. TODO: - [x] Fix the infinite notify loop bug or determine a third way to fix this lag Release Notes: - Fixed a bug where shifting focus to the terminal panel could be slow
This commit is contained in:
parent
cfe0932c0a
commit
69bb0a0597
2 changed files with 7 additions and 2 deletions
|
@ -137,7 +137,7 @@ impl WindowInvalidator {
|
||||||
self.inner.borrow_mut().dirty_views = views;
|
self.inner.borrow_mut().dirty_views = views;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn not_painting(&self) -> bool {
|
pub fn not_drawing(&self) -> bool {
|
||||||
self.inner.borrow().draw_phase == DrawPhase::None
|
self.inner.borrow().draw_phase == DrawPhase::None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1035,7 +1035,7 @@ impl Window {
|
||||||
|
|
||||||
/// Mark the window as dirty, scheduling it to be redrawn on the next frame.
|
/// Mark the window as dirty, scheduling it to be redrawn on the next frame.
|
||||||
pub fn refresh(&mut self) {
|
pub fn refresh(&mut self) {
|
||||||
if self.invalidator.not_painting() {
|
if self.invalidator.not_drawing() {
|
||||||
self.refreshing = true;
|
self.refreshing = true;
|
||||||
self.invalidator.set_dirty(true);
|
self.invalidator.set_dirty(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -582,6 +582,11 @@ impl Pane {
|
||||||
|
|
||||||
if let Some(active_item) = self.active_item() {
|
if let Some(active_item) = self.active_item() {
|
||||||
if self.focus_handle.is_focused(window) {
|
if self.focus_handle.is_focused(window) {
|
||||||
|
// Schedule a redraw next frame, so that the focus changes below take effect
|
||||||
|
cx.on_next_frame(window, |_, _, cx| {
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
|
||||||
// Pane was focused directly. We need to either focus a view inside the active item,
|
// Pane was focused directly. We need to either focus a view inside the active item,
|
||||||
// or focus the active item itself
|
// or focus the active item itself
|
||||||
if let Some(weak_last_focus_handle) =
|
if let Some(weak_last_focus_handle) =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue