chore(automation): Sync master → feature/breakingchanges - #23800
Conversation
|
@unoplatform/uno-core-team — |
|
Nick Randolph seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
- Guard a directory-less output assembly path (warn + skip) instead of null-forcing Path.GetDirectoryName, with test coverage - Narrow TryReadMvid to the expected open/read/parse failures
…ts baseline An update request racing the async workspace initialization was written to disk before the baseline solution was read, folding the edit into the baseline (never emitted as a delta) or landing before the FileSystemObserver existed (never observed). Requests are now gated on the workspace lifecycle by a WorkspaceGatedFileUpdater decorator: queued while initializing, flushed FIFO once the baseline is captured and the observer is active, pass-through when hot reload is IDE-driven (no workspace), failed with an explicit error on init failure/dispose or after a hard 30s queue timeout (configurable via the update-file-queue-timeout server configuration). Implements specs/050-hotreload-updatefile-workspace-gate; fixes #23787.
Harden WorkspaceGatedFileUpdater against a throwing diagnostics callback: complete each queued entry before invoking reporter/onEvent, guard those callbacks, and give DrainAsync an outer try/finally that always resets the draining flag (catching + logging any unexpected escape). WatchTimeoutAsync now guarantees the entry is resolved on any fault, _inner is volatile, and timed-out/cancelled entries are compacted out of the queue so a workspace stuck in Initializing cannot grow it unbounded. Adds two regression tests. Spec 050: add the standard header, drop the broken 049 link, use stable symbol references instead of file:line, draw the NoWorkspace -> Initializing edge, reword R2 (flush point is not today's Notify(Ready)), state TTL is timer-based, and add the mode-change test-plan item.
DrainAsync: reset _draining atomically with the empty-queue check under the same lock (removing the finally) so a request arriving in Ready state can no longer observe an empty queue with draining still latched and get stuck unflushed; the catch path also resets it under the lock on an unexpected escape. Re-check the lifecycle immediately before applying so an entry already dequeued when the workspace goes terminal (Failed/Disposed) is rejected rather than written to disk. Reject: guard against a default ImmutableArray (Select would throw NRE), matching FileUpdater's IsDefaultOrEmpty entry guard. ServerHotReloadProcessor: drop the dead `?? ex?.ToString()` (Message is never null on a non-null exception).
UpdateAsync: arm the TTL watcher (WatchTimeoutAsync) outside the _gate lock. If the token is already cancelled or the timeout is zero, the watcher runs synchronously through its finally -> CompactQueue, which re-enters _gate; starting it under the held lock ran that re-entrant queue mutation mid-enqueue. ServerHotReloadProcessor: in IDE-driven mode, report NoWorkspace before awaiting Notify(Ready) so an UpdateFile racing that window passes through immediately instead of being queued (strict IDE-driven pass-through).
UpdateAsync re-checks the workspace lifecycle immediately before the pass-through call to the inner updater: a terminal transition (Failed/Disposed) reported from the init task or Dispose can race the pass-through decision made under the lock, so re-check and reject without applying (mirrors the same re-check already on the drain path).
8aa68ec to
c3a9944
Compare
A layered child window is excluded from the OS's normal hit-testing and input routing (WindowFromPoint, mouse buttons, WM_SETCURSOR), so hosted native content such as WebView2 never received focus or clicks and showed the wrong cursor. AttachNativeElement applied WS_EX_LAYERED unconditionally to support opacity; it is now never set and is actively cleared (covering a window re-attached after a prior attach set it). ChangeNativeElementOpacity is a no-op (native element opacity is unsupported on Win32, as on X11). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Manual repro sample for WebView2 hosted in a ContentDialog on Skia Desktop (Win32): the text input should focus, type, and show the I-beam cursor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(hr): Re-point hot-reload baselines to the RID-specific build outputs
…pace-gate fix(hr): gate UpdateFile requests on workspace initialization (spec 050)
The nine >8-arg GL functions (glTexImage2D, glTexSubImage2D, glTexImage3D,
glTexSubImage3D, glCopyTexSubImage3D, glCompressed{Tex,TexSub}Image*, and
glBlitFramebuffer) crashed under WebAssembly full AOT with "null function or
function signature mismatch" on the first GLCanvasElement render.
Root cause: the shim routed Silk.NET's >8-arg calli into a C wrapper that
called back into a managed [UnmanagedCallersOnly] dispatcher resolved by
EntryPoint name. That native-to-interp callback has no valid entry under full
AOT (the managed->native calli hop itself works). The [UnmanagedCallersOnly]
8-arg cap (dotnet/runtime#109338) and the SignaturePrimer never addressed this.
Fix: the C shim now forwards straight to the JS WebGL layer via EM_JS, removing
the managed callback hop entirely. Silk.NET still calli's into the C wrappers
(the hop that already works). Removes the now-dead managed dispatchers, their
JSImports, and the ILLink descriptor that preserved them.
Validated against the unoplatform/kahua-private#520 repro: renders correctly on
both WASM full AOT (Release publish) and the interpreter (Debug), no crash.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A lit sphere encircled by a tilted ring, ported from the kahua-private#520 repro. Exercises the framebuffer color-attachment and texture-upload paths that regressed under WebAssembly full AOT, so it doubles as the regression artifact for a future full-AOT WASM validation leg. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The 8.0.3 pin is flagged by NU1903: CVE-2026-47304 and related July 2026 .NET XML-encryption advisories cover the whole 8.0.x line (up to the highest published 8.0.4), so no 8.0.x release clears them. Move the transitive-override pin to 10.0.10, the first 10.x release above the affected <= 10.0.9 range. It ships net9.0 and net10.0 assets, matching both target frameworks of these projects. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Serve GL entry points (including the >8-arg texture functions) from emscripten's native C GL library - shared with SkiaSharp via -lGL - through uno_gl_resolve, instead of forwarding each one to JS via EM_JS. Small C wrappers remain only for glTexImage2D/glTexImage3D to add the WebGL2 unsized->sized internal-format promotion emscripten omits; every other name falls back to the hand-written JS shim only when the native proc table has no entry. Silk.NET still calli's into the resolved addresses, so the build-time SignaturePrimer is kept to emit the matching interp->native trampolines. See unoplatform/kahua-private#520 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…to-xml-cve fix(security): Bump System.Security.Cryptography.Xml to 10.0.10
… change Follow-up kept as a separate PR to avoid re-triggering the parent PR's build: - Dispose the MSBuildWorkspace created on a failed OpenProjectAsync attempt before retrying — a transient failure no longer leaks an MSBuild evaluation host. - Extract the framework-version parsing out of the client's GetRuntimeTargetFramework into a testable ResolveFrameworkVersion helper (narrowing the catch to ArgumentException), and cover the missing / malformed / non-.NETCoreApp fallback with unit tests. - Rename a misleading `solution` local in a test helper (AddProject returns a Project). - Spec: the Windows ref-pack is already classified, so drop the stale "known gap" note.
…c failures The retry catch disposed the MSBuildWorkspace only while another attempt remained (when i > 1). On the final attempt an InvalidOperationException — or any other exception thrown after the workspace was created — propagated without disposing it, leaking its MSBuild evaluation hosts for the server's lifetime. Add a general catch that disposes before rethrowing every non-retried failure.
…rsion Add ClientHotReloadProcessor.FallbackVersion (=> Environment.Version) and use it as the ResolveFrameworkVersion fallback, so the unit test asserts against the same named member instead of duplicating Environment.Version. Addresses review feedback.
When_Repeater_ChangedView performs a smooth-scroll animation
(ChangeView disableAnimation:false) over a 300-item virtualized
ItemsRepeater, then polls for the last item to materialize. Under the
SkiaWasm CI stage's headless xvfb Chromium, requestAnimationFrame is
throttled, so the render-loop-driven scroll stalls before reaching the
end and the second WaitFor times out ("scrolled to the last item").
The prior de-flake pass hardened this test with WaitFor, but a stall
does not yield to a longer timeout.
Exclude it on SkiaWasm only, matching its render-loop siblings, tracked
under #23524. Coverage is retained on all other Skia targets
(Win32/X11/macOS) by construction since the same managed
scroll-presenter logic runs there; only the WASM render path loses this
specific smooth-scroll check.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mutter/GNOME (both Xorg and XWayland) advertises _NET_WM_FRAME_DRAWN, so GDK waits for the WM to acknowledge each frame before painting the next one. The webview window is reparented into the app's window and never managed by the WM, so no acknowledgement ever comes, GDK's frame clock stalls, and WebKit never paints (permanently blank webview). Weston (WSLg) and wlroots compositors don't support frame sync, so this is a no-op there. fixes #23159 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-23800/docs/index.html |
|
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-23800/wasm-skia-net9/index.html |
|
🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-23800/docs/index.html |
|
The build 224935 found UI Test snapshots differences: Details
|
|
|
…ner.listview.selection fix(itemcontainer): mute internal pointer capture release
- Restore the process-wide FeatureConfiguration.Rendering.SkipVisualTreePainting to its prior value on shutdown instead of leaving it forced on. - Tear down windows on shutdown (unregister from XamlRootMap, then stop the renderer) and ignore invalidations after the renderer is disposed, so late invalidations can't hit a disposed renderer and mappings don't leak. - Rename the host-builder extension class to HeadlessHostBuilderExtensions so its type name doesn't collide with the other Skia hosts' Uno.UI.Hosting.HostBuilder (avoids CS0433 when referenced together). Extension-method usage is unchanged. - Clarify in the docs that host selection is by registration order, not presence. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(hr): a re-observed up-to-date file must be a silent no-op (spec 055)
Fixes: #23923 Context: https://learn.microsoft.com/en-us/archive/blogs/cbrumme/lifetime-gc-keepalive-handle-recycling Context: mono/SkiaSharp#3393 Through (good? bad? dumb?) luck, when running SamplesApp on my handy emulator, building SamplesApp from a commit on the feature/breakingchanges branch: # note: commit 0ebec is on the feature/breakingchanges branch git checkout 0ebec1e # note: feature/breakingchanges is on .NET 11 P5 export PATH=path/to/dotnet-sdk-11.0.100-preview.5.26302.115:$PATH \cp build/ci/net11/_global.json global.json dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -r android-arm64 -f net11.0-android -p:UnoTargetFrameworkOverride=net11.0-android adb install src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net11.0-android/android-arm64/publish/uno.platform.samplesapp.skia-Signed.apk adb shell am start uno.platform.samplesapp.skia/crc6448f3b0362cbf4bc9.MainActivity Immediatley after launching the app, it would crash, with `adb logcat` containing: ActivityManager: Displayed uno.platform.samplesapp.skia/crc6448f3b0362cbf4bc9.MainActivity: +1s380ms samplesapp.ski: indirect_reference_table.cc:59] JNI ERROR (app bug): attempt to use stale Global 0x3916 (should be 0x391a) samplesapp.ski: runtime.cc:558] Runtime aborting... samplesapp.ski: runtime.cc:558] Dumping all threads without appropriate locks held: thread list lock samplesapp.ski: runtime.cc:558] All threads: samplesapp.ski: runtime.cc:558] DALVIK THREADS (20): samplesapp.ski: runtime.cc:558] "Thread-8" prio=10 tid=19 Runnable samplesapp.ski: runtime.cc:558] | group="" sCount=0 dsCount=0 flags=0 obj=0x12d01368 self=0x6f186fa800 samplesapp.ski: runtime.cc:558] | sysTid=7366 nice=-10 cgrp=default sched=0/0 handle=0x6f1993f4f0 samplesapp.ski: runtime.cc:558] | state=R schedstat=( 3289249 4228251 22 ) utm=0 stm=0 core=2 HZ=100 samplesapp.ski: runtime.cc:558] | stack=0x6f19844000-0x6f19846000 stackSize=1009KB samplesapp.ski: runtime.cc:558] | held mutexes= "abort lock" "mutator lock"(shared held) samplesapp.ski: runtime.cc:558] native: #00 pc 00000000003b49a0 /system/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+216) samplesapp.ski: runtime.cc:558] native: #1 pc 0000000000480e20 /system/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+348) samplesapp.ski: runtime.cc:558] native: #2 pc 000000000049a598 /system/lib64/libart.so (art::DumpCheckpoint::Run(art::Thread*)+812) samplesapp.ski: runtime.cc:558] native: #3 pc 000000000049350c /system/lib64/libart.so (art::ThreadList::RunCheckpoint(art::Closure*, art::Closure*)+464) samplesapp.ski: runtime.cc:558] native: #4 pc 00000000004927d4 /system/lib64/libart.so (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool)+504) samplesapp.ski: runtime.cc:558] native: #5 pc 00000000004564dc /system/lib64/libart.so (art::Runtime::Abort(char const*)+380) samplesapp.ski: runtime.cc:558] native: #6 pc 0000000000008cb0 /system/lib64/libbase.so (android::base::LogMessage::~LogMessage()+724) samplesapp.ski: runtime.cc:558] native: #7 pc 00000000002356e0 /system/lib64/libart.so (art::IndirectReferenceTable::AbortIfNoCheckJNI(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&)+236) samplesapp.ski: runtime.cc:558] native: #8 pc 00000000002e2790 /system/lib64/libart.so (art::IndirectReferenceTable::GetChecked(void*) const+436) samplesapp.ski: runtime.cc:558] native: #9 pc 00000000002ddabc /system/lib64/libart.so (art::JavaVMExt::DecodeGlobal(void*)+24) samplesapp.ski: runtime.cc:558] native: #10 pc 0000000000486734 /system/lib64/libart.so (art::Thread::DecodeJObject(_jobject*) const+152) samplesapp.ski: runtime.cc:558] native: #11 pc 00000000003439c4 /system/lib64/libart.so (art::JNI::GetObjectField(_JNIEnv*, _jobject*, _jfieldID*)+596) samplesapp.ski: runtime.cc:558] native: #12 pc 00000000000ff6bc /system/lib64/libandroid_runtime.so (android::android_view_Surface_getSurface(_JNIEnv*, _jobject*)+52) samplesapp.ski: runtime.cc:558] native: #13 pc 00000000000ff64c /system/lib64/libandroid_runtime.so (android::android_view_Surface_getNativeWindow(_JNIEnv*, _jobject*)+36) samplesapp.ski: runtime.cc:558] native: #14 pc 0000000000012394 /system/lib64/libandroid.so (ANativeWindow_fromSurface+32) samplesapp.ski: runtime.cc:558] native: #15 pc 00000000064927d0 <anonymous:6fd9e70000> (???) samplesapp.ski: runtime.cc:558] (no managed stack frames) For expository purposes, the relevant code is: /* 1 */ var surface = holder.Surface; /* 2 */ IntPtr __env = JNIEnv.Handle; /* 3 */ IntPtr __surface = surface.Handle; /* 4 */ _nativeWindow = ANativeWindow_fromSurface(__env, __surface); What appears to be happening is the following: 1. .NET 11 P5 changes the default Android runtime to CoreCLR. (.NET 11 P6 makes using MonoVM an *error*…) This means that we're now using a different GC than .NET 10+MonoVM. 2. The `surface` instance created on line 1 is not referenced again after line 3, which means it is eligible for collection immediately after the `surface.Handle` property invocation. 4. If the GC collects the `surface` instance between lines 3 and 4, then `__surface` will be an *invalid JNI handle*, as the GC collecting `surface` will invalidate it. 5. If `__surface` is an invalid handle, then `ANativeWindow_fromSurface()` will (rightfully!) crash with the "use [of] stale Global [JNI object reference]."" The fix for this, in a manner similar to that mentioned in mono/SkiaSharp#3393, is to extend the lifetime of `surface` so that the GC doesn't attempt to collect it before/during the `ANativeWindow_fromSurface()` invocation, by using `GC.KeepAlive()`: var surface = holder.Surface; IntPtr __env = JNIEnv.Handle; IntPtr __surface = surface.Handle; _nativeWindow = ANativeWindow_fromSurface(__env, __surface); GC.KeepAlive(surface); With this understanding in mind, review other use of `.Handle` within src/Uno.UI.Runtime.Skia.Android: git grep '\.Handle\>' src/Uno.UI.Runtime.Skia.Android and add `GC.KeepAlive()` invocations to ensure that the instance upon which `.Handle` is invoked is kept alive around the method call using `.Handle`.
…button fix(navview): Keep overflow button after overflow selection
- Replace the thread-static _isDispatcherThread flag (written from an instance method) with a captured dispatcher-thread id. - Drop the needless try/catch around Thread.Join in HeadlessRenderer.Dispose (a valid timeout on a started thread cannot throw). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ection-flyout feat(textbox): Touch/pen text selection flyout on Skia
…ANativeWindow_fromSurface-crash fix: extend Android Surface lifetime to avoid GC-related crash
Dev/rg/skia headless host
…ync/feature/breakingchanges
|
🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-23800/docs/index.html |
|
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-23800/wasm-skia-net9/index.html |
|
🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-23800/docs/index.html |
|
The build 225186 found UI Test snapshots differences: Details
|
Automated sync — merges the latest
masterintofeature/breakingchanges.Incoming commits from master: 343
Range:
5a1f5177ac..917810172fMerge method: merge commit (preserves ancestry so future syncs stay minimal)
Auto-merge: enabled — lands once required CI is green and a reviewer approves.
Maintained automatically; updates in place. Generated by this run.