Don't drop key bindings (#8019)

Fixes: #7748



Release Notes:

- Fixed a bug where keystrokes could be lost after focus changes
([#7748](https://github.com/zed-industries/zed/issues/7748)).

Co-authored-by: Antonio <as-cii@zed.dev>
This commit is contained in:
Conrad Irwin 2024-02-19 10:20:51 -07:00 committed by GitHub
parent 99559f3975
commit 4d1585b917
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -272,6 +272,7 @@ pub struct Window {
appearance_observers: SubscriberSet<(), AnyObserver>, appearance_observers: SubscriberSet<(), AnyObserver>,
active: Rc<Cell<bool>>, active: Rc<Cell<bool>>,
pub(crate) dirty: Rc<Cell<bool>>, pub(crate) dirty: Rc<Cell<bool>>,
pub(crate) needs_present: Rc<Cell<bool>>,
pub(crate) last_input_timestamp: Rc<Cell<Instant>>, pub(crate) last_input_timestamp: Rc<Cell<Instant>>,
pub(crate) refreshing: bool, pub(crate) refreshing: bool,
pub(crate) drawing: bool, pub(crate) drawing: bool,
@ -338,6 +339,7 @@ impl Window {
let text_system = Arc::new(WindowTextSystem::new(cx.text_system().clone())); let text_system = Arc::new(WindowTextSystem::new(cx.text_system().clone()));
let dirty = Rc::new(Cell::new(true)); let dirty = Rc::new(Cell::new(true));
let active = Rc::new(Cell::new(false)); let active = Rc::new(Cell::new(false));
let needs_present = Rc::new(Cell::new(false));
let next_frame_callbacks: Rc<RefCell<Vec<FrameCallback>>> = Default::default(); let next_frame_callbacks: Rc<RefCell<Vec<FrameCallback>>> = Default::default();
let last_input_timestamp = Rc::new(Cell::new(Instant::now())); let last_input_timestamp = Rc::new(Cell::new(Instant::now()));
@ -351,6 +353,7 @@ impl Window {
let mut cx = cx.to_async(); let mut cx = cx.to_async();
let dirty = dirty.clone(); let dirty = dirty.clone();
let active = active.clone(); let active = active.clone();
let needs_present = needs_present.clone();
let next_frame_callbacks = next_frame_callbacks.clone(); let next_frame_callbacks = next_frame_callbacks.clone();
let last_input_timestamp = last_input_timestamp.clone(); let last_input_timestamp = last_input_timestamp.clone();
move || { move || {
@ -365,6 +368,12 @@ impl Window {
.log_err(); .log_err();
} }
// Keep presenting the current scene for 1 extra second since the
// last input to prevent the display from underclocking the refresh rate.
let needs_present = needs_present.get()
|| (active.get()
&& last_input_timestamp.get().elapsed() < Duration::from_secs(1));
if dirty.get() { if dirty.get() {
measure("frame duration", || { measure("frame duration", || {
handle handle
@ -374,12 +383,7 @@ impl Window {
}) })
.log_err(); .log_err();
}) })
} } else if needs_present {
// Keep presenting the current scene for 1 extra second since the
// last input to prevent the display from underclocking the refresh rate.
else if active.get()
&& last_input_timestamp.get().elapsed() < Duration::from_secs(1)
{
handle.update(&mut cx, |_, cx| cx.present()).log_err(); handle.update(&mut cx, |_, cx| cx.present()).log_err();
} }
} }
@ -462,6 +466,7 @@ impl Window {
appearance_observers: SubscriberSet::new(), appearance_observers: SubscriberSet::new(),
active, active,
dirty, dirty,
needs_present,
last_input_timestamp, last_input_timestamp,
refreshing: false, refreshing: false,
drawing: false, drawing: false,
@ -1084,12 +1089,14 @@ impl<'a> WindowContext<'a> {
} }
self.window.refreshing = false; self.window.refreshing = false;
self.window.drawing = false; self.window.drawing = false;
self.window.needs_present.set(true);
} }
fn present(&self) { fn present(&self) {
self.window self.window
.platform_window .platform_window
.draw(&self.window.rendered_frame.scene); .draw(&self.window.rendered_frame.scene);
self.window.needs_present.set(false);
} }
/// Dispatch a mouse or keyboard event on the window. /// Dispatch a mouse or keyboard event on the window.
@ -1240,6 +1247,10 @@ impl<'a> WindowContext<'a> {
} }
fn dispatch_key_event(&mut self, event: &dyn Any) { fn dispatch_key_event(&mut self, event: &dyn Any) {
if self.window.dirty.get() {
self.draw();
}
let node_id = self let node_id = self
.window .window
.focus .focus