Skip to content

compat: Isolate equally named case and example builds - #40

Open
honsunrise wants to merge 1 commit into
longbridge:mainfrom
honsunrise:fix/distinct-checkout-app-paths
Open

honsunrise wants to merge 1 commit into
longbridge:mainfrom
honsunrise:fix/distinct-checkout-app-paths

Conversation

@honsunrise

@honsunrise honsunrise commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Root cause

The desktop case and example have the same logical name. Concurrent builders previously shared both checkout/desktop and checkout/desktop.build, allowing one app's bundle/metadata to be paired with the other app's script. A green run could also silently run the same app twice.

Observed failure in framework #1008: tap id:case-window-open sees the example's nsh desktop title-bar screen instead of the case. The baseline passed with the same checker revision and cache key, consistent with the race rather than a platform-specific failure.

Fix

  • Keep logical names for NSH_COMPAT_APP selection, but use disjoint case-<name> and example-<name> build identities.
  • Put staging inside each app's own output directory, including for dotted names.
  • Recreate only the generated checkout output tree so stale apps do not affect coverage.
  • Keep concurrent builds, all scripts/assertions and frozen release records unchanged.
  • Add a deterministic build-name collision regression.

Verification

Against framework 8ddbc7e3: all 33 tests passed, including the full checkout run. The output now contains 17 independent apps (previously 16), including both case-desktop (com.example.api-desktop, window-case script) and example-desktop (com.example.desktop, title-bar example script).

The focused namespace regression and Rust formatting check passed. No test was skipped to repair the race.

This is a checker fix, separate from framework material changes; after it lands, rerun framework #1008 Compat.
Cloud CI also passed: 31 tests on upstream NSH, including the namespace regression and full checkout application run; formatting and strict Clippy clean. Run: https://github.com/longbridge/nsh-compat/actions/runs/42354818579 . Pending maintainer review/merge; framework #1008 should rerun Compat afterward even though its old-checker run happened to pass.

@honsunrise

Copy link
Copy Markdown
Contributor Author

CI has now passed: https://github.com/longbridge/nsh-compat/actions/runs/42354818579 . @huacnlee could you review/merge this independent checker fix? It removes the confirmed case/example output race blocking longbridge/nsh#1008. After merge, please rerun that PR’s Compat check even if an old-checker rerun happens to be green: the old race can silently execute one desktop app twice. No frozen record or assertion was changed.

huacnlee pushed a commit to longbridge/nsh that referenced this pull request Nov 7, 2026
## Scope
Expose native material composition without prescribing an application
theme:

- Apply the existing `mixBlendMode` API on macOS, including text, images
and clipped children; `normal` removes the filter.
- Add one typed `macos.backdrop` configuration for AppKit material,
blending and activity state.
- Make `glassTintColor` support tint updates and native-default
restoration on both iOS 26+ and macOS 26+.
- Allow a custom Rust `run_app` host to opt into a transparent window.
Standard hosts default to opaque windows but can use upstream window
attributes to request transparency; an embedded `AppView` never changes
its host window.

The unrelated browser keyboard patch is now a separate PR: #1098. This
branch contains no context-menu keyboard or CI-selection changes.

## API
`MacOsBackdrop` is `#[non_exhaustive]`: construct it with `Default` and
assign fields. Its existing fallback defaults remain `Popover`,
`WithinWindow`, and `Active`.

The three new native enums use `PropEnum`'s generated `js_name` and
`HostValue::decode` paths, with camelCase values. The redundant
handwritten `name`/`parse` methods and kebab-case overrides introduced
by this PR are removed. Existing CSS `mixBlendMode` values are
unchanged.

```tsx
<View macos={{ backdrop: {
  material: "hudWindow",
  blending: "behindWindow",
  state: "followsWindowActiveState",
} }} />
<View style={{ glassEffect: "regular", glassTintColor: "#4080ff80" }} />
```

`Styled::glass_tint_color` accepts
`IntoReactive<Option<AdaptiveColor>>`. Static
`AdaptiveColor`/`Hsla`/`Rgba`/`Color` values retain direct-call
ergonomics; optional signals and closures can set and clear the tint.

```rust
let tint = signal(Some(AdaptiveColor::rgb(0x4080ff, 0x4080ff)));
let panel = view().glass_effect(GlassEffect::Regular).glass_tint_color(tint);
// In a UI action:
tint.set(None); // native default, not a transparent color
```

`.glass_tint_color(None)` also directly restores the default. TS `null`
and removing the style property have the same reset meaning. Transparent
color remains an explicit tint.

## Native behavior
Explicit macOS material takes precedence over glass, then the existing
blur fallback. Effect-kind changes remove the old native view. Tint-only
changes retain the glass view, and material views remain noninteractive.

UIKit uses runtime `UIGlassEffect` lookup, updates `tintColor` on its
effect and assigns the effect back to the same `UIVisualEffectView`.
Blur effects are not sent glass-only selectors. Earlier-system
class-unavailable fallback is retained.

`AppOptions::transparent` defaults to false and now feeds the upstream
main-window attributes as an initial default. Explicit launch attributes
and later window updates take precedence; the standalone surface no
longer keeps a competing transparency flag. No CLI flags, `nsh.json`
keys, per-material utility classes, application color recipes or
terminal behavior are added.

## Verification scope
Earlier Apple tint/reset verification at `481f4a6e` was exercised
through real AppKit mouse events and UIKit accessibility activation in a
public `AppView` embedding host on Mac Catalyst. Light/dark native
appearance, red/blue, explicit transparent color, native-default
restoration and stable glass-view identity passed. UIKit blur also
ignored tint updates without replacing its view. WindowServer captures,
not in-process screenshots, record the material rendering.

Earlier validation at `481f4a6e` used an isolated build directory (not a
rerun of the current rebase):

| Check | Result |
| --- | --- |
| Core library | 1154 passed; 9 existing ignored |
| Engine platform selection | 23 passed; 320 filtered |
| macOS backend | 87 passed |
| UIKit lifecycle selection (Catalyst) | 2 passed |
| Core/engine all-target Clippy `-D warnings` | Passed |
| Paired checker, including checkout applications | 32 passed |
| Bundled guides / changed Rust formatting | 5 passed / clean |
| Native AppKit and UIKit | Both appearances, tint/reset, identity,
compositor captures verified |

## Previous rebase verification at 8ddbc7e
Both open PRs are rebased onto `origin/main` at
`beeb9fc7707e0d4a195a4f7274f77b30e134c500`, without merge commits.

The new upstream window APIs exposed a native interaction regression:
after starting with `AppOptions::transparent=true`, setting the main
window opaque left its background alpha at 0, including after a redraw.
The integration fix uses the upstream live window state; the same real
AppKit scenario now restores alpha 1, survives redraw, and can switch
back to alpha 0. Explicit opaque launch attributes win over the host
default, and normal hosts remain opaque by default. English/Chinese docs
and screenshot-fallback descriptions follow the new upstream contracts.

Fresh local verification after rebase: core 1207 passed / 9 existing
ignored; engine platform selection 32 passed / 322 filtered; macOS
backend 100 passed; core/engine/macOS all-target strict Clippy passed;
bundled guides 5 passed; CLI built; upstream checker all 32 passed.
Changed Rust formatting passed. The native window scenario verified both
runtime toggling and explicit/default launch precedence. Earlier Website
CI exceeded the then-hard Brotli budget by 2,471 bytes. Current upstream
has already changed that check to a reporting-only 5,000,000-byte
budget; this PR does not modify the budget. The old macOS lint failure
was fixed upstream in #1112.

The maintainer closed the independent native-verification follow-up with
its environment limitations, not a pass. Earlier author-side native
captures remain historical evidence; no new independent verification or
older-OS coverage is claimed here. Current local runtime verification
targets the rebased window-state integration.

## History and merge order
Framework head: `47e7de842b5a585a194a519067ddb74d9ec3b892`, linearly
rebased onto `4ca2672d30659a63b6358f2942383c6248b2772f`; no merge
commits.

Companion longbridge/nsh-compat#37 is now
merged. Validation uses the checker’s upstream `origin/main`; no rewrite
or push of the merged PR was performed.

Native evidence and reproduction:
https://github.com/honsunrise/nsh/tree/bc4e1f6037e6e37b8d20df619f041024d265e5c8/verification/pr1008

## Latest CI root causes and correction
All checks on `8ddbc7e3` finished: only Compat and GPUI Gallery failed.
GPUI has since been fixed upstream in #1205; the current rebase includes
it, with all four material commits unchanged by `range-diff`. Fresh
engine platform tests (32), macOS backend tests (100), and CLI build
passed. The original shifted-key assertion also passed on the upstream
GPUI implementation in a focused macOS run; a preceding full local run
had three setup timeouts, so it is not claimed as 9/9.

Compat is a checker race, not a material regression: the case and
example both named `desktop` shared output and staging directories. It
can mix the example bundle with the case script or silently run the same
app twice. **Earlier green checkout runs do not establish that both
desktop apps were covered.** The root fix is
longbridge/nsh-compat#40: distinct case/example
identities and private staging, with no skipped scripts or assertions.
All 33 tests passed locally against `8ddbc7e3`, and all 17 distinct app
outputs were inspected, including both desktop IDs and scripts. That fix
has passed its upstream CI and still needs maintainer review/merge; a
lucky rerun with the old checker is not proof the race is gone.

The duplicate GPUI fix #1211 was closed in favor of merged #1205. No
unrelated GPUI patch was added to this PR. All executed checks on
`47e7de84` have now passed, including Linux GPUI Gallery and Web;
deployment is skipped by the PR workflow. The green Compat job still
checked out old checker `f1e4188`, so it does not establish that the
directory race is eliminated. Merge checker #40 and rerun Compat to
verify the corrected harness.
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.

1 participant