gpui: Fix dropped frames when scrolling an unfocused window (#61600)
Scroll events are delivered to the window under the pointer even when it isn't focused, but we cap inactive windows at ~30fps to save energy, so scrolling an unfocused window visibly drops frames. We now exempt high-rate input from the cap using the existing `InputRateTracker`: a trackpad scroll stream lifts it while events are arriving and for one second after the last burst, then the cap resumes on its own. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed dropped frames when scrolling unfocused windows.
This commit is contained in:
1 parent
5d2df6acd5
commit
0fd17feb17
1 file changed
+6
-3
@@ -1589,13 +1589,16 @@ impl Window {
|
||||
|
||||
// Throttle frame rate based on conditions:
|
||||
// - Thermal pressure (Serious/Critical): cap to ~60fps
|
||||
// - Inactive window (not focused): cap to ~30fps to save energy
|
||||
// - Inactive window (not focused): cap to ~30fps to save energy,
|
||||
// unless input is arriving at a high rate (e.g. scrolling an
|
||||
// unfocused window, which is delivered to the window under
|
||||
// the pointer).
|
||||
let min_frame_interval = if !force_render
|
||||
&& !request_frame_options.require_presentation
|
||||
&& next_frame_callbacks.borrow().is_empty()
|
||||
{
|
||||
None
|
||||
} else if !active.get() {
|
||||
} else if !active.get() && !input_rate_tracker.borrow_mut().is_high_rate() {
|
||||
Some(Duration::from_micros(33333))
|
||||
} else if let Some(ThermalState::Critical | ThermalState::Serious) = thermal_state {
|
||||
Some(Duration::from_micros(16667))
|
||||
@@ -1638,7 +1641,7 @@ impl Window {
|
||||
// to prevent display underclocking during active input.
|
||||
let needs_present = request_frame_options.require_presentation
|
||||
|| needs_present.get()
|
||||
|| (active.get() && input_rate_tracker.borrow_mut().is_high_rate());
|
||||
|| input_rate_tracker.borrow_mut().is_high_rate();
|
||||
|
||||
if invalidator.is_dirty() || force_render {
|
||||
measure("frame duration", || {
|
||||
|
||||
Reference in new issue
Block a user