feat(gui): use the compositor's native title bar where it exists - #6
Open
plutack wants to merge 3 commits into
Open
feat(gui): use the compositor's native title bar where it exists#6plutack wants to merge 3 commits into
plutack wants to merge 3 commits into
Conversation
Exploring captures (rapidly clicking rows in the All-traffic view) froze the UI, and large bodies eventually crashed the WebKit web process (JS heap exhaustion; confirmed by a user-session WebKitWeb- Process SIGABRT coredump). Four compounding causes, all fixed: - The 2s poll loop always installed fresh array identities into state, re-rendering the entire tree — including any open detail pane — even when nothing changed. Loaders now bail out via functional setState when a row fingerprint is unchanged. - BodyViewer re-ran prettyBody (JSON.parse + stringify), regex syntax highlighting, and a full innerHTML swap on every render, because dangerouslySetInnerHTML got a new object identity each time. All transforms are now memoized, pretty-print/highlight are skipped above 1 MiB (with an explanatory notice), and the innerHTML prop identity is stable. - Every capture detail embedded an ExportSnippet that auto-fired a snippet conversion on each selection change — one goja JS VM + httpsnippet eval per click. Conversion is now debounced 250ms and the snippet <pre> no longer re-assigns innerHTML per poll. - Rapid row clicks each fetched the full body payload and rendered every response on arrival. Detail fetches are now deduplicated per row while in flight, and superseded responses are dropped. GetCapture also stopped shipping bodies twice (UTF-8 + base64); base64 alone halves the response the webview has to parse. Validated live on Linux/webkit2gtk: a 5 MiB body that killed the app outright now opens fine, and 12 rapid clicks across 1 MiB-body rows settle cleanly (transient RSS spike, full GC recovery, UI responsive throughout). Idle polling no longer rebuilds the detail DOM: RSS is flat between real data changes.
Memoization removed the repeated cost but the FIRST render of a multi-megabyte body still blocked the webview for 0.5-2s: the whole body was base64-decoded per byte, escaped with three regex passes, and materialized as DOM text. Measured on a 4.8 MB JSON body, one open plus a few row switches cost the shipped v0.2.0 ~7.1s of webview CPU and ~1 GB of RSS growth; the same interaction now costs ~0.5s with flat RSS. The viewer now decodes and renders at most DISPLAY_LIMIT (256 KiB) up front, with a notice and a 'Show entire body' escalation. Copy, Save, and Image still operate on the full payload, decoded on demand. escapeHTML is a single pass, and the base64 prefix is cut on a 4-character boundary so the slice always decodes cleanly.
On Wayland desktops whose compositor draws server-side decorations (COSMIC, KDE Plasma), GTK3's fallback client-side bar renders light gray against the app's dark theme and looks foreign next to every other window. Marking the window frameless makes the compositor draw its own native bar instead — verified live on a COSMIC session. Gated by a new gui.native_titlebar config key (auto | always | never, default auto). auto enables it only on Linux desktops that actually decorate frameless clients; Windows and macOS never go frameless (DWM and NSWindow already provide the native bar, and frameless there means no bar at all).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
On Wayland sessions whose compositor provides server-side decorations (COSMIC, KDE Plasma), the GUI showed GTK3's fallback client-side title bar — rendered light gray against the app's dark theme, looking foreign next to every other window. (This is why the same binary looked "more native" when run under XWayland: the compositor decorates X11 clients itself.)
What
gui.native_titlebarconfig key: auto (default — on for COSMIC/KDE), always, never.auto/alwaysare ignored off Linux.Stacked on #5 (only the last commit is unique until that merges).