forked from 1b-agent/opencadstudio-upstream
feat: draw a notice for one frame before rebuilding a layout
Switching to a Layout stops the main thread long enough that the compositor decides the application has stopped responding and offers to kill it. The switch itself is not the problem — `layout-switch` reports about 10 ms — it is the frame after it, which rebuilds the whole wire set. That frame now has a cheap one in front of it. `layout_settling` is set when the switch takes, and while it holds, the viewport is replaced by a centered "Preparing layout…" on the canvas background. No shader widget means no scene primitive, so `prepare` has nothing to do and the frame costs nothing. A `window::frames` subscription clears the flag, which is the guarantee this needs: that callback runs once a frame has actually been presented, so the notice is on screen and the compositor has been answered before the expensive frame starts. The deferral is of the *frame*, not the switch. Two callers depend on the switch having completed when it returns — one calls `fit_all` immediately after, another compares `current_layout` — so deferring the switch itself would have broken both. This restarts the compositor's timer immediately before the slow frame and replaces a stale window with something that says what is happening. It does not make the slow frame fast: if the rebuild still exceeds the compositor's timeout the dialog can return, and the durable fix is the 2 s `memo_miss` behind it, which is a separate change. Only `en-US` is validated against at build time; Greek is filled in too since it is in use here, and the rest fall back until translated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d9a1d55f2e
commit
09838be9ec
6 files changed
+62
-1
No files matched your search
@@ -5534,6 +5534,10 @@ impl OpenCADStudio {
|
||||
.layers
|
||||
.sync_with_viewports(&doc_layers, vp_info);
|
||||
let layers_ms = perf_phase.elapsed().as_secs_f64() * 1000.0;
|
||||
// The switch is cheap; the frame that follows it is not. Draw a notice
|
||||
// for one frame first, so the compositor gets an answer before the main
|
||||
// thread disappears into rebuilding the wire set.
|
||||
self.layout_settling = true;
|
||||
if perf {
|
||||
crate::perf_record!(
|
||||
"[perf] layout-switch from={} to={} total={:.2}ms sync={:.2}ms switch={:.2}ms restore={:.2}ms layers={:.2}ms epoch={}",
|
||||
|
||||
Reference in new issue
Block a user