fix: present frames during continuous input
This commit is contained in:
@@ -90,8 +90,9 @@ Real and verified:
|
||||
macOS Metal toolchain so `cargo run`'s shader-build failure is fixed.
|
||||
- Scroll input: consecutive same-document wheel requests coalesce at the
|
||||
profile worker boundary while preserving total device-pixel distance;
|
||||
clicks, text, and allow-once permission transfers retain strict ordering.
|
||||
Verified by a blocked-worker burst regression and the live-site scroll e2e.
|
||||
frames from the active render epoch remain presentable while newer input is
|
||||
queued. Clicks, text, and allow-once permission transfers retain strict
|
||||
ordering. Verified by generation, blocked-worker burst, and live-site tests.
|
||||
- Website color scheme: resolved System/Light/Dark state crosses sidecar
|
||||
protocol v4 and reaches `WebView::notify_theme_change`; GPUI appearance
|
||||
events trigger a shell repaint, and first-navigation WebView replacement
|
||||
|
||||
@@ -104,9 +104,11 @@ impl WebSurfaceRuntime {
|
||||
let submitted_at = Instant::now();
|
||||
let started_loading = {
|
||||
let session = session_for_scope(&mut self.sessions, tab.id(), scope.clone());
|
||||
let started_loading = session.started_loading(&requested_url, size, zoom_percent);
|
||||
let started_loading =
|
||||
session.started_loading(&requested_url, size, zoom_percent, self.color_scheme);
|
||||
if started_loading {
|
||||
session.pending_user_navigation = false;
|
||||
session.frame_generation_floor = Some(generation);
|
||||
}
|
||||
if user_navigation_input {
|
||||
session.pending_user_navigation = true;
|
||||
@@ -114,6 +116,7 @@ impl WebSurfaceRuntime {
|
||||
session.requested_url = requested_url.clone();
|
||||
session.size = size;
|
||||
session.zoom_percent = zoom_percent;
|
||||
session.color_scheme = Some(self.color_scheme);
|
||||
session.scroll_offset = next_scroll_offset;
|
||||
session.generation = Some(generation);
|
||||
session.cadence.note_ensure(input_kind, started_loading, submitted_at);
|
||||
@@ -296,7 +299,7 @@ impl WebSurfaceRuntime {
|
||||
continue;
|
||||
};
|
||||
if !self.sessions.get(&tab_id_obj).is_some_and(|session| {
|
||||
&session.scope == scope && session.generation == Some(generation)
|
||||
&session.scope == scope && session.accepts_frame_generation(generation)
|
||||
}) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -145,6 +145,35 @@ fn late_frame_is_discarded_after_tab_session_closes() -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn earlier_frame_from_same_render_epoch_remains_presentable() -> Result<(), String> {
|
||||
let mut runtime = WebSurfaceRuntime::new_with_client_factory(empty_client_factory);
|
||||
let tab_id = TabId::new();
|
||||
let profile_id = ProfileId::new();
|
||||
let tab = web_tab(tab_id.clone(), profile_id.clone(), "https://example.com/page")?;
|
||||
|
||||
runtime.ensure_tab(&tab, surface_size(), ProfileDataMode::Transient, &[], pending_input())?;
|
||||
let earlier = current_generation(&runtime, &tab_id)?;
|
||||
runtime.ensure_tab(&tab, surface_size(), ProfileDataMode::Transient, &[], pending_input())?;
|
||||
let latest = current_generation(&runtime, &tab_id)?;
|
||||
|
||||
let mut frames = Vec::new();
|
||||
runtime.collect_responses(
|
||||
&scope(&profile_id),
|
||||
vec![WorkerResponse::Frame {
|
||||
generation: earlier,
|
||||
tab_id: tab_id.as_str().to_string(),
|
||||
frame: live_frame(),
|
||||
}],
|
||||
Instant::now(),
|
||||
&mut frames,
|
||||
);
|
||||
|
||||
assert!(earlier < latest);
|
||||
assert!(matches!(frames.as_slice(), [WebSurfaceRuntimeFrame::Ready { .. }]));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scope_change_returns_submitted_permission_grants_on_the_next_tick() -> Result<(), String> {
|
||||
let mut runtime = WebSurfaceRuntime::new_with_client_factory(empty_client_factory);
|
||||
|
||||
@@ -57,7 +57,9 @@ fn successful_frame_resets_scope_retry_state() {
|
||||
let scope = WebSurfaceRuntimeScope::new(ProfileId::new(), ProfileDataMode::Transient);
|
||||
let tab_id = TabId::new();
|
||||
let generation = RequestGeneration::new(1);
|
||||
session_for_scope(&mut runtime.sessions, &tab_id, scope.clone()).generation = Some(generation);
|
||||
let session = session_for_scope(&mut runtime.sessions, &tab_id, scope.clone());
|
||||
session.generation = Some(generation);
|
||||
session.frame_generation_floor = Some(generation);
|
||||
runtime.note_scope_failure(&scope, Instant::now());
|
||||
let mut frames = Vec::new();
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::services::{
|
||||
transient_profile_data_dir,
|
||||
},
|
||||
};
|
||||
use ely_domain::{ProfileId, TabId};
|
||||
use ely_domain::{ColorScheme, ProfileId, TabId};
|
||||
|
||||
use super::{
|
||||
web_surface_cadence::WebSurfacePollCadence,
|
||||
@@ -42,6 +42,8 @@ pub(super) struct WebSurfaceSession {
|
||||
pub(super) scroll_offset: WebSurfaceScrollOffset,
|
||||
pub(super) pending_user_navigation: bool,
|
||||
pub(super) generation: Option<RequestGeneration>,
|
||||
pub(super) frame_generation_floor: Option<RequestGeneration>,
|
||||
pub(super) color_scheme: Option<ColorScheme>,
|
||||
pub(super) cadence: WebSurfacePollCadence,
|
||||
}
|
||||
|
||||
@@ -55,6 +57,8 @@ impl WebSurfaceSession {
|
||||
scroll_offset: WebSurfaceScrollOffset::default(),
|
||||
pending_user_navigation: false,
|
||||
generation: None,
|
||||
frame_generation_floor: None,
|
||||
color_scheme: None,
|
||||
cadence: WebSurfacePollCadence::default(),
|
||||
}
|
||||
}
|
||||
@@ -64,10 +68,17 @@ impl WebSurfaceSession {
|
||||
requested_url: &str,
|
||||
size: WebSurfaceSize,
|
||||
zoom_percent: u16,
|
||||
color_scheme: ColorScheme,
|
||||
) -> bool {
|
||||
self.requested_url != requested_url
|
||||
|| self.size != size
|
||||
|| self.zoom_percent != zoom_percent
|
||||
|| self.color_scheme != Some(color_scheme)
|
||||
}
|
||||
|
||||
pub(super) fn accepts_frame_generation(&self, generation: RequestGeneration) -> bool {
|
||||
self.frame_generation_floor.is_some_and(|floor| generation >= floor)
|
||||
&& self.generation.is_some_and(|latest| generation <= latest)
|
||||
}
|
||||
|
||||
pub(super) fn url_change_for(
|
||||
|
||||
Reference in New Issue
Block a user