incular-platform 0.1.0

Shared platform abstractions for Incular
Documentation

incular-platform

Architecture and support

Contract Status
Ownership Portable native IDs, events, capabilities, commands, metrics and errors.
API class backend; re-exports and path overrides follow the architecture contract.
Support Portable contracts; Winit conversion and raw access belong to desktop.

Owns portable native events and the logical/physical DPI boundary. Winit translation and raw-handle extraction live in incular_desktop::winit_adapter. Desktop adapters convert physical pointers through WindowMetrics before hit testing.

Window contract

WindowId is an Incular-owned (slot, generation) identity, never a Winit ID or a native pointer. A window registry advances the generation whenever it reuses a slot, allowing queued stale commands and handles to be rejected.

WindowOptions contains the portable desktop creation subset: title, initial and minimum/maximum logical sizes, resizability, initial visibility, decorations, transparency request, maximized state, borderless fullscreen, portable window level, and optional validated RGBA window icon. validate rejects contradictory or non-positive dimensions before native creation.

Mutable native policy is expressed with semantic WindowOperation values: compositor-owned move/resize dragging, minimize/maximize/fullscreen, resizability/decorations, logical size limits, window level/icon, and user attention. WindowRequestedState is deliberately separate from WindowObservedState: enqueueing a setter records application intent, while a backend StateChanged event records only values the operating system can actually report. An unobservable state is None, never guessed from intent.

WindowCommand pairs that ID with a data-only WindowOperation. Ordinary fire-and-observe operations carry no request identity; operations whose native outcome matters may carry a runtime-owned NativeRequestId. The platform adapter reports those results as NativeOperationCompletion, using the stable PlatformOperationErrorKind taxonomy rather than leaking Winit/native error objects through the framework. A native close gesture is first represented by WindowEvent::platform(id, PlatformEvent::CloseRequested) so the runtime can apply an application close policy before issuing Close.

PlatformCapabilities is the runtime capability contract. It is grouped into window control, display/placement, transient surfaces, native menus, data transfer, application services, and advanced input instead of one platform flag. Unknown means no backend/session has published support yet; Unsupported is an explicit backend statement. This distinction is important for session-dependent facilities such as Wayland placement and native desktop services.

Transient capability discovery is role-aware. native_surface is the aggregate summary, while popover, menu, context-menu, combo-box, and tooltip support can be queried independently. A backend must report Unsupported rather than silently manufacturing a top-level window that cannot honor the platform's popup relationship. In particular, the current Wayland adapter does not claim native popup support until the backend can provide real xdg-popup semantics.

Displays and placement

DisplayId is a generational Incular identity, not a monitor name or an enumeration index. DisplaySnapshot is immutable and distinguishes monitor pixel size from optional desktop-global bounds and optional usable/work area. Display-local logical/physical coordinates have dedicated wrapper types so a mixed-DPI conversion never silently treats one monitor's scale as a global desktop scale. Global screen positions likewise use explicit physical screen types rather than widget Offset values.

Top-level placement is capability-gated. Win32, AppKit, and X11 can expose Winit's physical desktop position/bounds; Wayland deliberately reports global bounds, outer-position queries, and outer-position setters as unsupported. Wayland still exposes display-local size/scale/name and current-display association where Winit can provide them. A missing work area is represented as None and must never be replaced with full monitor bounds under the same API.

WindowEvent associates existing PlatformEvent input/metrics/close data with a normalized WindowId; WindowLifecycle, RedrawRequested, and StateChanged provide the extra per-window state native adapters need without extending the legacy single-window event stream. Application lifecycle remains separate from window visibility and focus lifecycle.

Keyboard navigation, printable text and IME composition are normalized into separate InputEvent variants. TextInputConfiguration, TextInputState, and TextInputCommand form the data-only native text-input bridge: the runtime selects the focused client, publishes selection/composing/caret state, and receives explicit soft-keyboard actions through PlatformEvent. Winit adapters apply those commands to the native IME; mobile hosts can consume the same commands without a window dependency. Clipboard is the backend boundary; the shared desktop runner installs an arboard system-clipboard bridge with a safe in-memory fallback and publishes whether native clipboard interop is actually available for the current session.

Pointer input has one metadata-rich representation. Mouse events carry a stable process-local device ID, the complete pressed-button chord, and the button that changed on Down/Up; primary, secondary, middle, back, forward, and representable extra buttons use distinct portable bits. Touch uses the same event shape with stable contact/device identity. PointerPhase::Enter/Exit represent native surface crossings without fabricating a local coordinate on enter.

Native cursor policy is separate from cursor styling. CursorGrabMode and validated LogicalWindowPosition back result-bearing window operations for grab/lock, visibility, and cursor warping. AdvancedInputCapabilities reports icons, visibility, position, confinement, and locking independently. Optional Wayland pointer-constraints support remains Unknown until the actual Winit operation reports success or a typed unsupported/native failure.

The scroll convention is positive logical delta.y increasing the controller offset (content moves upward). Winit LineDelta is scaled by 40 logical px; PixelDelta is converted through DPI and normalized to natural content direction without rounding, preserving fractional trackpad movement. Key commands are delivered on pressed events (including native repeats); control-text payloads such as Backspace are not forwarded as committed text.