mirror of
https://github.com/zhukunpenglinyutong/jetbrains-cc-gui.git
synced 2026-08-29 00:41:38 +08:00
4ab851f780
Problem and evidence: Multi-project startup could restore complete history state and React DOM while the first visible Remote JCEF OSR surface kept a blank or partial backing image. Hover repaired only locally damaged regions, while a real resize or tab remap restored the full viewport without another history query, message update, reload, or browser recreation. The data path was therefore correct; the missing completion boundary was publication of a current full frame through Chromium, CefRenderHandler, the JetBrains backing image, and Swing. DOM and bridge protocol: Preserve historyLoadComplete calls that arrive before React callback registration, including explicit zero-message history. Emit history_dom_committed from a layout effect with a monotonic content revision so the signal means only that the restored message DOM committed. Bind Java handling to the owning JBCefBrowser, CefBrowser, page generation, frontend-ready epoch, and content revision; reject stale callbacks without treating rAF, timers, load completion, or executeJavaScript submission as rendered pixels. OSR handler integration and compatibility: Wrap the JetBrains default JBCefOSRHandlerFactory rather than replacing its component, input, IME, HiDPI, shared-memory, or disposal behavior. Install the wrapper whenever supplied because Remote JCEF may force OSR after the requested rendering mode is selected. Fail closed if a wrapped Remote browser cannot be constructed. Discover CefNativeRenderHandler reflectively so the same binary loads on IDEA 2023.3, 2024.1, 2024.3, and 2025.2. Forward the final Remote non-popup frame with dirtyRectsCount zero and the classic OSR frame with a full-viewport rectangle; pass popup and unrelated frames through unchanged. Publication fence and ownership: Add SurfaceFrameFence with latest pending request, one active attempt, and a published watermark. A request carries browser identities, page generation, ready epoch, content revision, request serial, and attempt id. Exact phase-applied acknowledgments open the frame gates: the first matching OnPaint drains stale in-flight work, phase B restores the damage source, and only the second matching OnPaint is forwarded as a full frame. Completion advances the watermark only after the default handler receives that frame and the current Swing surface is painted. Keep request serial and attempt ownership separate. Timeout releases only its exact attempt, retains the logical pending request, and never loops by itself. A newer pending request receives a guarded handoff; late frames, acknowledgments, timeout callbacks, or paint tasks from A cannot complete B, cancel B's timeout, or clear the same request after it is re-armed with a new attempt id. Damage and activation behavior: Generate the two required Chromium damage frames with an alternating two-pixel raster sentinel outside the React root. Restore the transparent baseline on completion or cancellation and coordinate ordinary repaint requests around the strict pulse. The publication path never changes app zoom, font scale, scroll position, or React layout. Create frontend-ready revision zero even while hidden, but arm it only when the real native surface is showing, displayable, and has valid bounds. A new history commit supersedes older content revisions. Tab activation and window showing wake existing unpublished work; once content is published, ordinary OSR activation only presents the cached JetBrains backing image and does not create a serial or manufacture Chromium damage. Ready loss, generation changes, browser replacement, and disposal invalidate pending, active, published, timeout, and frontend pulse ownership together. Windowed JCEF keeps its existing bounds and repaint path. Scope and relationship: Build on the preceding hidden-tab lifecycle fix so inactive pages retain work without running bridge retry or watchdog recovery loops. Do not call loadHTML, reload, or recreate as part of surface publication, consume watchdog recovery budget, or change provider, model, context-usage, and session routing behavior. The daemon heartbeat restart burst observed after system sleep is independent and remains tracked by issue 1601. Validation: - Full Gradle test suite and checkstyleMain passed after the squash. - WebView production TypeScript and Vite build passed. - Frontend suite passed 127 files and 1091 tests, including TypeScript test checking. - git diff --check passed with no generated-file pollution. - R18 passed repeated IDEA 2025.2 multi-project restored startups without blank first tabs or visible tab-switch layout jitter. - Sleep/wake validation retained a timed-out publication and successfully re-armed the same serial with a new attempt after activation, without a WebView reload/recreate storm. Refs #1592