spike: two stacked webviews, to find out if the substrate holds - #119
Open
zmaril wants to merge 3 commits into
Open
spike: two stacked webviews, to find out if the substrate holds#119zmaril wants to merge 3 commits into
zmaril wants to merge 3 commits into
Conversation
powderman previewhttps://powderman-pr-119.fly.dev The workbench, live: split/join/swap areas, the F3 palette, the widgets, themes, tooltips, the status bar. On branches with the MCP server, point an agent at it: claude mcp add --transport http powderman-preview "https://powderman-pr-119.fly.dev/mcp"Updated on every push. Destroyed when this PR closes. |
The question is whether a native shell can host real web pages as areas without giving up the chords and the right-click menu. Three things have to be true, and only one of them is a matter of opinion. One window, two child webviews. The lower one loads github.com — chosen because it sets X-Frame-Options: DENY, so if it renders then this is definitively not an iframe, which is the premise everything else rests on. The upper one is transparent and holds the chrome that has to draw over it. A shim is injected into the page before it loads. It is keymap.js and contextmenu.js with the transport swapped — window.ipc.postMessage instead of dioxus.send — and it claims only the keys the workbench asks for, leaving the rest to the page, which is the difference between embedding a page and breaking it. Matching in the guest rather than posting every keystroke is the same one-message-per-meaningful-event budget the rest of the workbench holds to. Four of the five questions the program answers out loud: the page rendered, a chord got out of it, a right-click got out of it, a click still reaches it. The fifth — does the overlay draw above the page, transparently — is the one that decides the architecture and the one nothing can check for you, so the overlay draws a magenta frame and a dimmed backdrop and the program tells you to look at it. The `p` key is the question behind the question. The overlay is hidden between uses rather than made click-through, because hiding needs no platform code and click-through needs an NSView hitTest: override. That is fine for menus and modals; it is not fine for a tooltip that follows the pointer. `p` holds the overlay up and empty so you can find out whether clicks pass through a transparent webview anyway — free persistent chrome if they do, interop if they do not, and better to know now. Outside the workspace, because it drags in wry and a WebKit toolchain and neither belongs in the lockfile every CI run resolves. Not compiled and not run: no WebKit toolchain and no display here, and build_as_child is macOS / Windows / X11 only regardless. Both injected scripts parse, and two tests pin the seams this kind of thing rots at — the JSON kinds the scripts emit against the enum that receives them, and the imOverlay functions the host calls by name against the ones the overlay defines. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XjCx5QszLXroGYh1YBxybw
apt landed, so the two suspects got checked: the winit 0.30 ApplicationHandler shape and the dpi re-export path were both fine. One unused import, and cargo check / clippy / test are clean against wry 0.56 and winit 0.30. What is still unverified is everything that needs a screen — whether the overlay is transparent, whether it stacks above, whether clicks pass through it, and whether the injected shim really takes the keys back from a live page. Those were always the point. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XjCx5QszLXroGYh1YBxybw
straitjacket [color]. They are the instrument rather than a style — a magenta that cannot be mistaken for part of the page beneath is the whole z-order test — and pointing them at theme tokens would make the spike depend on the library whose substrate it exists to check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XjCx5QszLXroGYh1YBxybw
zmaril
force-pushed
the
spike/webview-stack
branch
from
August 21, 2026 16:43
8b51a52 to
94dde25
Compare
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.
Not compiled, not run. No WebKit toolchain and no display on this machine, and
build_as_childis macOS / Windows / X11 only regardless. This is a thing to run on your Mac, built so one command answers the questions instead of you having to design the test.The setup
One window, two child webviews. The lower one loads github.com — chosen because it sets
X-Frame-Options: DENY, so if it renders then this is definitively not an iframe, which is the premise everything else rests on. The upper one is transparent and holds the chrome that has to draw over it.A shim is injected into the page before it loads. It's
keymap.jsandcontextmenu.jswith the transport swapped —window.ipc.postMessageinstead ofdioxus.send— and it claims only the keys the workbench asks for, leaving the rest to the page. That's the difference between embedding a page and breaking it. Matching in the guest rather than posting every keystroke is the same one-message-per-meaningful-event budget everything else here holds to.What it answers on its own
What only you can answer
Did the magenta frame and the menu draw above the page, and could you read the page through the dimmed backdrop? z-order and transparency — the pair that decides the architecture, and the thing no program can check. macOS is reported to handle this well; Windows is where wry's transparency bugs live (#1540).
The
pkey is the question behind the questionThe overlay is hidden between uses rather than made click-through, because hiding needs no platform code and click-through needs an
NSView hitTest:override on macOS.Fine for menus and modals, which are transient. Not fine for a tooltip that follows the pointer.
pholds the overlay up and empty so you can find out whether clicks reach the page through a transparent webview anyway — free persistent chrome if they do, interop if they don't, and much better to know now.Notes
exclude), so wry and a WebKit toolchain never touch the lockfile CI resolves. Nothing about the existing build changes.bun build), and two tests pin the seams this kind of code rots at — the JSON kinds the scripts emit vs. the enum that receives them, and theimOverlayfunctions the host calls by name vs. the ones the overlay defines. They need a machine that can build wry to run.Everything else is unverified, including whether it compiles. If it doesn't, the likely culprits are the winit 0.30
ApplicationHandlershape and thedpire-export path — both cheap to fix once a compiler has seen them.🤖 Generated with Claude Code
https://claude.ai/code/session_01XjCx5QszLXroGYh1YBxybw