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
@@ -3045,6 +3045,12 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::LayoutSettled => {
|
||||
// The notice frame has been presented, so the compositor has
|
||||
// had its answer. Let the next frame build the real thing.
|
||||
self.layout_settling = false;
|
||||
Task::none()
|
||||
}
|
||||
Message::GripDwellTick => {
|
||||
let i = self.active_tab;
|
||||
// Reuse the move-time logic — `p` is the last cursor
|
||||
|
||||
Reference in new issue
Block a user