ArcForges.Desktop.Shell
1.0.0-ci.93.1
dotnet add package ArcForges.Desktop.Shell --version 1.0.0-ci.93.1
NuGet\Install-Package ArcForges.Desktop.Shell -Version 1.0.0-ci.93.1
<PackageReference Include="ArcForges.Desktop.Shell" Version="1.0.0-ci.93.1" />
<PackageVersion Include="ArcForges.Desktop.Shell" Version="1.0.0-ci.93.1" />
<PackageReference Include="ArcForges.Desktop.Shell" />
paket add ArcForges.Desktop.Shell --version 1.0.0-ci.93.1
#r "nuget: ArcForges.Desktop.Shell, 1.0.0-ci.93.1"
#:package ArcForges.Desktop.Shell@1.0.0-ci.93.1
#addin nuget:?package=ArcForges.Desktop.Shell&version=1.0.0-ci.93.1&prerelease
#tool nuget:?package=ArcForges.Desktop.Shell&version=1.0.0-ci.93.1&prerelease
ArcForges.Desktop.Shell
Framework-neutral state for a multi-window desktop shell: per-launch window ownership, dockable/collapsible panel arrangements, display-aware layout restoration, and device-local persistence. UI frameworks are adapters over these models; this project does not choose or load one.
WindowRegistry is scoped to one InstanceId for the current launch. Saved layouts deliberately do not use that ephemeral identity. A DeviceLocalLayoutStore is instead scoped by a validated application key and layout key beneath the owner-selected LocalApplicationData root, so a new launch can restore a prior arrangement without sharing it between applications or layouts. The keys are hashed before being used in the path.
Layout writes use a flushed same-directory temporary file followed by replacement, preserving the last committed layout if a write is interrupted. Invalid or truncated JSON is reported as corrupt without being overwritten. Restore filters panels no longer registered by the current application, clamps window bounds to the current display work areas, and falls back to the primary display if a saved display has disappeared.
Package
ArcForges.Desktop.Shell is published in the DesktopPlatform single-version release set together with ArcForges.DesignSystem. Its exact package dependencies are ArcForges.DesignSystem, ArcForges.Capabilities and ArcForges.Foundation at the same release version, plus the ArcForges.Contracts.Foundation coordinate pinned in eng/packaging/packages.json. It pulls in no UI framework, native runtime, storage engine or product package, so an application restores only the mechanisms it composes. The package contains the framework-neutral models and contracts below; UI-framework adapters, the control set they would use and every product flow stay with their own tasks and owners.
Lifecycle, menus and shutdown
ShellLifecycleCoordinator is a framework-neutral coordinator over host-owned operations (ShellLifecycleOperations); it owns ordering and safety, not product behavior, OS services, process discovery or any UI framework.
- Startup.
RunStartupAsyncruns the host's make-the-local-workspace-usable step first and only then the host's background step (account, Cloud, helpers, sync), never the other way round. It returns aShellStartupMeasurementof that path. The measurement covers only the coordinator's own path inside a running process; it is not the product Time To Usable (cold process to usable workspace, release AOT, reference hardware), which only a product host can measure. - Single-instance routing. The host decides whether a primary instance exists and owns the transport.
RouteActivationAsyncforwards one immutableShellActivationRequestto the primary at most once perRequestId(duplicates and in-flight retries share the first outcome, a conflicting payload for a known id is refused, a failed forward is not remembered). Duplicate suppression covers every in-flight request and the most recent 4096 completed ones; the transport must also treatRequestIdas its idempotency key. A duplicate that is waiting on a forward cancelled by the first caller's own token retries instead of inheriting that cancellation.ShellActivationRequest.Targetis only an opaque, bounded, control-free string: the host validates and authorises it (deep-link input handling is not this class's job), and primary election and the receiving side (focusing or opening in the primary) are host-owned. - Shutdown.
CreateShutdownPromptstates the consequences for the work snapshot the host supplies (ShellShutdownState: a host-advanced generation plus active and unsaved counts; Cloud-pending content that is already locally durable is not "unsaved") and offers only a choice that keeps work or one that quits safely. Strings come fromErrors/ErrorPresentationStrings.resx.ExecuteShutdownAsyncrevalidates the prompted snapshot, and a changed snapshot or an unavailable decision returns a new prompt instead of acting. It then stops writes, reaches safe points, saves unsaved work, flushes, disconnects services, drains and stops the native runtime, in that order; if work remains after the safe-point step it resumes writes and asks again. EachShellLifecycleOperationsdelegate documents its contract: stopping writes covers only new external or remote commands (it must not break saving or flushing), afalseor thrown workspace step is retryable, and a background-start failure or a failure after disconnect began is terminal. Startup and shutdown are serialized, and a failure after services began disconnecting makes the coordinator fail closed rather than replay teardown. - Menus.
ShellCommandPalette.GetMenuContributionsreturns the registered commands that carry aShellMenuPlacement, ordered by menu, section, order and command id. Titles, shortcuts and availability still come from the one registered command and the capability evaluator.
Accessibility and localisation baseline (PLT.33)
Both are framework-neutral contracts that a UI adapter binds; this project still loads no UI framework, and no Avalonia control or XAML is used or admitted here (see docs/third-party-control-admission.md).
- Accessibility semantics.
ShellSurfaceCatalogdeclares, for the workspace window, command palette, scoped settings, attention centre and error dialog, every element'sAccessibleRole, localised name and description, keyboard access (TabStop,RovingorCommand), Tab order, live-region politeness, state cues (colour is always paired with text, an icon or a shape), and modal trap-and-dismiss behaviour.ShellAccessibilityAuditchecks any set of surfaces against that contract (rulesAX-NAME,AX-ICON,AX-KEYBOARD,AX-FOCUS-ORDER,AX-DIALOG,AX-LIVE,AX-COLOUR,AX-TEXT,AX-ID,AX-ROLE,AX-COMMAND); a product audits the surfaces it hosts the same way.FocusNavigatorexecutes the focus contract: Tab and Shift+Tab, roving arrow keys that mirror in a right-to-left layout, focus trapped inside a modal surface, and focus restored to its origin on Escape. - Localisation. Shell-owned user text is a resource key plus named arguments (
LocalizedText), resolved byShellTextfrom the embeddedShellStringsandErrorPresentationStringssets.ShellMessageFormatterimplements named parameters and plural branches (an ICU subset with CLDR integer plural rules for single-form, one/other, Slavic and Arabic families), so a sentence is one resource and is never concatenated. Command titles, attention text and similar owner-supplied display text remain owned and localised by their producers. - Pseudo-localisation.
PseudoLocaliserandShellText.BeginPseudoLocalisation()render every shell string accented, expanded and wrapped in one start and one end marker. The shell tests render every reason-code presentation, notification fallback and catalogue name in that mode and require each to be exactly one whole marked message, which exposes hard-coded literals, concatenation and clipping. - Right-to-left.
FlowDirectionsmaps the leading and trailingDockRegionedges and horizontal spans to physical geometry only at presentation time, so stored layout never changes with the interface language and no RTL rewrite of the models is needed.
What this does not verify
The automated checks prove the declarations and the keyboard and localisation logic; they do not read a platform accessibility tree. The dated manual assistive-technology verification of a real UI adapter is an explicit local opt-in that cannot run until an adapter and an admitted UI control set exist. When one does, record against its exact build: the date, operating system and assistive technology with versions (for example Narrator or NVDA on Windows and Orca on Linux), and for each catalogue surface that the name, role, state and live announcements are spoken, the Tab order matches the catalogue, every action is reachable without a pointer, focus is visible, dialogs trap and restore focus, high-contrast and reduced-motion settings are honoured, and text scaled to 200 percent stays usable. Untested items stay listed as untested.
Known contract gaps in this release, stated so a consumer does not assume them: the surface catalogue does not include menu contributions and declares no menu role, and the accessibility node contract carries visual state cues but no assistive-technology state (toggled, selected, expanded, disabled, busy). Both belong to a later extension before an adapter relies on them.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- ArcForges.Capabilities (= 1.0.0-ci.93.1)
- ArcForges.Contracts.Foundation (= 1.0.0-ci.216.1)
- ArcForges.DesignSystem (= 1.0.0-ci.93.1)
- ArcForges.Foundation (= 1.0.0-ci.93.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-ci.93.1 | 0 | 10/4/2026 |
| 1.0.0-ci.92.1 | 0 | 10/4/2026 |
| 1.0.0-ci.91.1 | 0 | 10/4/2026 |
| 1.0.0-ci.90.1 | 0 | 10/4/2026 |
| 1.0.0-ci.89.1 | 0 | 10/3/2026 |
| 1.0.0-ci.88.1 | 0 | 10/3/2026 |
| 1.0.0-ci.87.1 | 0 | 10/3/2026 |
| 1.0.0-ci.86.1 | 0 | 10/3/2026 |
| 1.0.0-ci.85.1 | 0 | 10/3/2026 |
| 1.0.0-ci.84.1 | 0 | 10/3/2026 |
| 1.0.0-ci.83.1 | 0 | 10/3/2026 |
| 1.0.0-ci.82.1 | 0 | 10/3/2026 |
| 1.0.0-ci.81.1 | 34 | 10/2/2026 |
| 1.0.0-ci.80.1 | 32 | 10/2/2026 |
| 1.0.0-ci.79.1 | 38 | 10/2/2026 |
| 1.0.0-ci.78.1 | 28 | 10/2/2026 |
| 1.0.0-ci.77.1 | 31 | 10/2/2026 |
| 1.0.0-ci.76.1 | 33 | 10/2/2026 |
| 1.0.0-ci.75.1 | 30 | 10/2/2026 |
| 1.0.0-ci.74.1 | 38 | 10/2/2026 |