Disable extra frames for ProMotion when screen is not active. (#7410)
This was causing an issue where windows about 1/10 of the way across the display would hang for a fully second after being deactivated. Release Notes: - N/A Co-authored-by: max <max@zed.dev> Co-authored-by: nathan <nathan@zed.dev> Co-authored-by: antonio <antonio@zed.dev>
This commit is contained in:
parent
d04a286634
commit
c7c4166724
2 changed files with 15 additions and 9 deletions
|
@ -1530,6 +1530,7 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
|
||||||
extern "C" fn step(this: &Object, _: Sel, display_link: id) {
|
extern "C" fn step(this: &Object, _: Sel, display_link: id) {
|
||||||
let window_state = unsafe { get_window_state(this) };
|
let window_state = unsafe { get_window_state(this) };
|
||||||
let mut lock = window_state.lock();
|
let mut lock = window_state.lock();
|
||||||
|
|
||||||
if lock.display_link == display_link {
|
if lock.display_link == display_link {
|
||||||
if let Some(mut callback) = lock.request_frame_callback.take() {
|
if let Some(mut callback) = lock.request_frame_callback.take() {
|
||||||
drop(lock);
|
drop(lock);
|
||||||
|
|
|
@ -271,7 +271,7 @@ pub struct Window {
|
||||||
bounds_observers: SubscriberSet<(), AnyObserver>,
|
bounds_observers: SubscriberSet<(), AnyObserver>,
|
||||||
appearance: WindowAppearance,
|
appearance: WindowAppearance,
|
||||||
appearance_observers: SubscriberSet<(), AnyObserver>,
|
appearance_observers: SubscriberSet<(), AnyObserver>,
|
||||||
active: bool,
|
active: Rc<Cell<bool>>,
|
||||||
pub(crate) dirty: Rc<Cell<bool>>,
|
pub(crate) dirty: 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,
|
||||||
|
@ -337,11 +337,13 @@ impl Window {
|
||||||
let appearance = platform_window.appearance();
|
let appearance = platform_window.appearance();
|
||||||
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 last_input_timestamp = Rc::new(Cell::new(Instant::now()));
|
let last_input_timestamp = Rc::new(Cell::new(Instant::now()));
|
||||||
|
|
||||||
platform_window.on_request_frame(Box::new({
|
platform_window.on_request_frame(Box::new({
|
||||||
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 last_input_timestamp = last_input_timestamp.clone();
|
let last_input_timestamp = last_input_timestamp.clone();
|
||||||
move || {
|
move || {
|
||||||
if dirty.get() {
|
if dirty.get() {
|
||||||
|
@ -353,9 +355,12 @@ impl Window {
|
||||||
})
|
})
|
||||||
.log_err();
|
.log_err();
|
||||||
})
|
})
|
||||||
} else if last_input_timestamp.get().elapsed() < Duration::from_secs(1) {
|
}
|
||||||
// Keep presenting the current scene for 1 extra second since the
|
// Keep presenting the current scene for 1 extra second since the
|
||||||
// last input to prevent the display from underclocking the refresh rate.
|
// 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,7 +394,7 @@ impl Window {
|
||||||
move |active| {
|
move |active| {
|
||||||
handle
|
handle
|
||||||
.update(&mut cx, |_, cx| {
|
.update(&mut cx, |_, cx| {
|
||||||
cx.window.active = active;
|
cx.window.active.set(active);
|
||||||
cx.window
|
cx.window
|
||||||
.activation_observers
|
.activation_observers
|
||||||
.clone()
|
.clone()
|
||||||
|
@ -435,7 +440,7 @@ impl Window {
|
||||||
bounds_observers: SubscriberSet::new(),
|
bounds_observers: SubscriberSet::new(),
|
||||||
appearance,
|
appearance,
|
||||||
appearance_observers: SubscriberSet::new(),
|
appearance_observers: SubscriberSet::new(),
|
||||||
active: false,
|
active,
|
||||||
dirty,
|
dirty,
|
||||||
last_input_timestamp,
|
last_input_timestamp,
|
||||||
refreshing: false,
|
refreshing: false,
|
||||||
|
@ -777,7 +782,7 @@ impl<'a> WindowContext<'a> {
|
||||||
|
|
||||||
/// Returns whether this window is focused by the operating system (receiving key events).
|
/// Returns whether this window is focused by the operating system (receiving key events).
|
||||||
pub fn is_window_active(&self) -> bool {
|
pub fn is_window_active(&self) -> bool {
|
||||||
self.window.active
|
self.window.active.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Toggle zoom on the window.
|
/// Toggle zoom on the window.
|
||||||
|
@ -1033,7 +1038,7 @@ impl<'a> WindowContext<'a> {
|
||||||
self.window.focus,
|
self.window.focus,
|
||||||
);
|
);
|
||||||
self.window.next_frame.focus = self.window.focus;
|
self.window.next_frame.focus = self.window.focus;
|
||||||
self.window.next_frame.window_active = self.window.active;
|
self.window.next_frame.window_active = self.window.active.get();
|
||||||
self.window.root_view = Some(root_view);
|
self.window.root_view = Some(root_view);
|
||||||
|
|
||||||
// Set the cursor only if we're the active window.
|
// Set the cursor only if we're the active window.
|
||||||
|
@ -2553,7 +2558,7 @@ impl<V: 'static + Render> WindowHandle<V> {
|
||||||
pub fn is_active(&self, cx: &AppContext) -> Option<bool> {
|
pub fn is_active(&self, cx: &AppContext) -> Option<bool> {
|
||||||
cx.windows
|
cx.windows
|
||||||
.get(self.id)
|
.get(self.id)
|
||||||
.and_then(|window| window.as_ref().map(|window| window.active))
|
.and_then(|window| window.as_ref().map(|window| window.active.get()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue