Skip to content

Fix e2e-windows (#54), a second WebView in a window (#55), and the CI workflow - #71

Open
angelix wants to merge 3 commits into
NucleusFramework:mainfrom
angelix:fix/windows-webview-creation
Open

angelix wants to merge 3 commits into
NucleusFramework:mainfrom
angelix:fix/windows-webview-creation

Conversation

@angelix

@angelix angelix commented Nov 12, 2026 •

Copy link
Copy Markdown

Fixes #54, and the failure reported in #55.

The build check cannot pass today, for three reasons. One commit each.

1. The host's messages were dispatched while a view was being created (#54)

WebView2 is created synchronously: compose_webview_create runs the calling thread's message queue until the environment and the controller have reported back. It dispatched every message it found there, the host's among them, while the host was in the middle of the call that waits.

  • A pointer message ran the host's handlers inside that call. With a view already attached, that re-entered Compose's dispatcher, which threw, and the window's event loop ended. The process stays up with nothing more to say. This is how the suite ends on main.
  • A wake-up or a redraw request was lost. Tao sets aside what it receives while its handler is busy and hands it over with the next event. Nucleus asks for a wake-up or a redraw once and then waits for it. With both taken off the queue during a creation, no next event came: the window stopped drawing and its dispatcher stopped running until something else reached the loop. A mouse move does that on a desktop; on a runner nothing does. I saw this one when the suite created its views from the window's own dispatcher.

The wait now dispatches only what is queued for WebView2's own windows, those of a class whose window procedure is in the module WebView2's objects come from. Everything else stays queued for the host's loop.

2. Only the first view in a window could be created (#55)

Each view made a DirectComposition device and a topmost target for the host window. A window takes one topmost target, so creating a second view in the same window failed with Failed to create WebView2 (is WebView2 Runtime installed?).

A window now has one composition tree, made by its first view and gone with its last. Each view adds a visual of its own to it.

A creation that fails now says on stderr which step failed and with what HRESULT. #63 reports the same exception for the first view of a window; I do not know its cause, but that line would name the step.

3. The workflow asks for what GitHub no longer has

  • build-natives / macos and e2e-macos run on macos-14. The native build is cancelled at once (The configuration 'macos-14-arm64-us-default' is not supported), and every job that needs the natives is skipped: common-tests-jvm and the three desktop e2e jobs.
  • setup-android's default package list names tools. sdkmanager answers Failed to find package 'tools', and common-tests-android and e2e-android fail in that step. common-tests-jvm has the same step.

Both jobs now run on macos-15, as common-tests-ios already does, and the Android setup installs platform-tools only.

Verify

./gradlew :e2e-desktop:run on windows-latest, one job per tree (run):

tree result
main CoroutinesInternalError out of Compose's dispatcher within half a minute, then nothing until the step is cancelled
main + commit 1 65 passed, 5 failed: K07, S01, S02, S06 and L08, each with Failed to create WebView2 (is WebView2 Runtime installed?)
main + commits 1 and 2 70 passed, 0 failed

PR Build Check with the three commits, on my fork (run): every job passes. e2e-windows, e2e-linux and e2e-macos each end with 70 passed, 0 failed.

  • It took nine attempts. GitHub had no macOS runner for my fork for most of the day (The job was not acquired by Runner of type hosted even after multiple attempts), and the desktop jobs wait behind the macOS native build.
  • e2e-android failed C07 and C08 in the first attempt and passed when re-run: both assert the loading state as soon as the page's marker can be read, which can be before Android has reported the page finished. Nothing here touches them.

Not changed: Kotlin sources, the macOS and Linux backends.

Left as it is: a creation still blocks the UI thread until WebView2 has started.

WebView2 is created synchronously: the Windows backend runs the thread's
message queue until the environment and the controller report back. It
dispatched every message there, the host's among them, while the host was in
the middle of the call that waits.

A pointer message ran the host's handlers inside that call. Under a Compose
scene with a view already attached, that re-entered Compose's dispatcher,
which threw, and the window's event loop ended.

A wake-up or a request to redraw was lost. Tao sets aside what it receives
while its handler is busy and hands it over with the next event, and Nucleus
asks for a wake-up or a redraw once and then waits for it. With both taken
off the queue during a creation, no next event came: the window stopped
drawing and its dispatcher stopped running until something else reached the
loop, which on a machine with no one at it is never.

The wait now dispatches only what is queued for WebView2's own windows, those
of a class whose procedure is in the module its objects come from, and leaves
the host's messages queued for the host's loop. A failed creation says on
stderr which step failed and with what result.
Each view made a DirectComposition device and a topmost target for the host
window. A window takes one topmost target, so only the first view in a window
could be created: a second one failed, and with it every screen that shows two
views or replaces one with another in the same composition.

A window now has one tree, made by its first view and gone with its last, and
each view adds its own visual to it. The steps of a creation that can fail
after the controller exists say so on stderr too.
…xists

GitHub no longer offers the macos-14 runner image, so the macOS native build
was cancelled before it started and every job that needs the natives (the
JVM tests and the three desktop e2e suites) was skipped. setup-android's
default package list still names "tools", which sdkmanager no longer has,
so the Android jobs failed in their setup step.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

e2e-windows hangs in :e2e-desktop:run and times out after 45 min

1 participant