frus-shell 0.5.0

frus — the platform layer: window + event loop (Milestone 0)
Documentation
[package]

name = "frus-shell"

description = "frus — the platform layer: window + event loop (Milestone 0)"

edition.workspace = true

rust-version.workspace = true

version.workspace = true

license.workspace = true

repository.workspace = true

readme = "README.md"

documentation = "https://docs.rs/frus-shell"

keywords = ["gui", "winit", "window", "event-loop", "wasm"]

categories = ["gui", "wasm"]



# The `net` feature turns on the cross-platform `fetch` HTTP helper: the `ureq`

# client natively, the browser's `fetch` on the Web. Off by default, so an app that

# does no networking bundles neither ureq nor its TLS stack.

# The `json` feature, which implies `net`, adds `Request::json_body` / `send_json`

# through serde.

#

# The `bundled-*` features forward the **bundled fonts** (milestone 292): they are

# ~3.4 MB of faces, and an application that ships its own turns off the ones it does

# not need. All on by default.

[features]

# A driver with no window, for an application's tests to feed input and frames through the

# shell's own paths. Hidden; not for applications to ship.

testing = []

# Hot reload under `frus run`: connects to the patch server it starts, applies each patch, and

# rebuilds the interface. Development only; `frus run` turns it on.

hot-reload = ["dep:dioxus-devtools", "dep:serde_json", "frus-widgets/hot-reload"]

# The system's file dialogs: `FileDialog` (milestone 698). Desktop only; off by default, as it

# brings the desktop portal's D-Bus client on Linux.

file-dialogs = ["dep:rfd"]

# The system's notifications: `SystemNotification` (milestones 701 to 704). The desktop,

# Android and the Web; off by default, as it brings the D-Bus client on Linux and the toast

# bindings on Windows.

notifications = ["dep:notify-rust"]

# The tray icon: `Tray` (milestone 706). The desktop; off by default. On Linux it needs GTK 3's

# development files to build (`libgtk-3-dev`), the menus being made with it.

tray = ["dep:tray-icon"]

# The taskbar's badge and progress: `Taskbar` (milestone 708). The desktop; off by default.

taskbar = ["dep:windows", "dep:objc2", "dep:objc2-app-kit", "dep:objc2-foundation", "dep:zbus"]

# Global shortcuts: `GlobalShortcut` (milestone 709). The desktop (X11 on Linux); off by default.

global-shortcuts = ["dep:global-hotkey"]

net = ["dep:ureq"]

json = ["net", "dep:serde", "dep:serde_json"]

default = ["frus-gpu/default", "frus-widgets/default"]

bundled-sans = ["frus-gpu/bundled-sans", "frus-widgets/bundled-sans"]

bundled-italic = ["frus-gpu/bundled-italic", "frus-widgets/bundled-italic"]

bundled-mono = ["frus-gpu/bundled-mono", "frus-widgets/bundled-mono"]

bundled-arabic = ["frus-gpu/bundled-arabic", "frus-widgets/bundled-arabic"]



# The `cfg` aliases (`desktop` / `android` / `ios` / `web`) — see `build.rs`. Already

# in the tree, since winit uses it, so nothing extra is downloaded.

[build-dependencies]

cfg_aliases = "0.2"



[dependencies]

# The client of the patch server `frus run` drives (the subsecond protocol).

dioxus-devtools = { version = "0.7", optional = true }

frus-gpu = { path = "../frus-gpu", version = "0.5", default-features = false }

# How long the fonts took to load, for the start-up report (milestone 683).

frus-text = { path = "../frus-text", version = "0.5", default-features = false }

frus-widgets = { path = "../frus-widgets", version = "0.5", default-features = false }

winit.workspace = true

anyhow.workspace = true

log.workspace = true

# Typed JSON for the `fetch` helper (the `json` feature): serialisation and

# deserialisation. Pure Rust, so it holds on all three targets, unlike ureq, which is

# native only.

serde = { version = "1", features = ["derive"], optional = true }

serde_json = { version = "1", optional = true }

# A portable monotonic clock: `std::time` natively, `performance.now()` on the Web,

# where `std::time::Instant` panics. One API for all three platforms.

web-time = "1"



# Native (desktop + Android): a blocking wait on GPU init. The Web is asynchronous

# instead — see `run_web`.

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]

pollster.workspace = true

# The async runtime (see `src/runtime.rs`). `async-executor` is the scheduler and

# `async-io` the reactor — the part that was missing, and without which a future that

# waits on a timer or a socket simply never wakes up. Both are small, pure Rust and

# free of proc macros; between them they are what lets a `Command` be a real future

# rather than a blocking call wearing a future's clothes.

async-executor = "1"

async-io = "2"

futures-lite = "2"

# Moving a **blocking** call off the executor and onto a pool sized for waiting. The

# `net` feature's client is blocking, and a blocking call on a four-worker executor

# is how you starve every other effect in the application.

blocking = "1"

# The `fetch` helper's native HTTP client (the `net` feature): blocking, driven to

# completion inside the async future's body, on its own thread. TLS through rustls,

# ureq's default.

ureq = { version = "3", optional = true }



# The reader's preferred languages, everywhere but Android and the Web — Windows,

# macOS, Linux and iOS each keep them somewhere different, and this is one small crate

# over the four. It is **already in the tree**: cosmic-text pulls it, so naming it here

# adds no dependency at all. Android has a better answer (the activity's `Configuration`,

# read over the JNI walk that is already there) and the Web has its own.

[target.'cfg(not(any(target_os = "android", target_arch = "wasm32")))'.dependencies]

sys-locale = "0.3"



# Desktop only — not Android, not iOS, not the Web: clipboard, console logger and

# accessibility. (AccessKit exposes the semantic tree to the native screen readers —

# UIA on Windows, AT-SPI on Linux, macOS; the Android and Web providers are separate.)

#

# iOS is excluded explicitly: `arboard`, a desktop clipboard, and `accesskit_winit`

# have no UIKit backend, and stderr is not readable on a device. Cargo does not

# evaluate `build.rs` aliases here, hence the list spelled out in full.

[target.'cfg(not(any(target_os = "android", target_os = "ios", target_arch = "wasm32")))'.dependencies]

# Decodes the application's icon for the window (`AppIcon`); already in the tree through the

# widgets' `images` feature.

frus-image = { path = "../frus-image", version = "0.5" }

arboard.workspace = true

env_logger.workspace = true

accesskit = "0.25"

accesskit_winit = "0.34"

# The system's file dialogs (feature `file-dialogs`): the Windows and macOS dialogs, and the

# desktop portal on Linux, which needs no system library to build against.

rfd = { version = "0.17.2", optional = true }

# The system's notifications (feature `notifications`): Windows toasts, macOS notifications,

# and the desktop's notification server over D-Bus on Linux, in pure Rust.

notify-rust = { version = "4.18.2", optional = true }

# The tray icon (feature `tray`): the notification area on Windows, the menu bar on macOS, and

# the desktop's status area over D-Bus on Linux (below, with its `ksni` feature).

tray-icon = { version = "0.26.1", optional = true, default-features = false }

# Global shortcuts (feature `global-shortcuts`): RegisterHotKey on Windows, the Carbon hot keys on

# macOS, a key grab on X11 — pure Rust everywhere, no system library to build against.

global-hotkey = { version = "0.9.0", optional = true }



# Web (wasm32 + WebGPU): the browser entry point, JS futures, console logs.

# The application's content on the title bar's line (milestone 640): the frame and the

# window procedure, which winit does not reach. Already in the tree.

# The tray icon on Linux and the BSDs: the desktop's status area through D-Bus (`ksni`), not the

# older indicator library a desktop may not have.

[target.'cfg(all(unix, not(any(target_os = "macos", target_os = "android", target_os = "ios"))))'.dependencies]

tray-icon = { version = "0.26.1", optional = true, default-features = false, features = ["ksni"] }



# The taskbar (feature `taskbar`) on Linux: the launcher entry signal, over D-Bus.

[target.'cfg(all(unix, not(any(target_os = "macos", target_os = "android", target_os = "ios"))))'.dependencies.zbus]

version = "5"

optional = true



# The taskbar (feature `taskbar`) on macOS: the Dock tile's badge.

[target.'cfg(target_os = "macos")'.dependencies]

objc2 = { version = "0.6", optional = true }

objc2-app-kit = { version = "0.3", optional = true, default-features = false, features = ["std", "NSApplication", "NSDockTile", "NSResponder"] }

objc2-foundation = { version = "0.3", optional = true, default-features = false, features = ["std", "NSString"] }



[target.'cfg(windows)'.dependencies]

# The taskbar (feature `taskbar`): its button's progress and overlay, a COM interface the raw

# bindings below do not carry. Already in the tree through the tray and the notifications.

windows = { version = "0.62", optional = true, features = ["Win32_Foundation", "Win32_Graphics_Gdi", "Win32_System_Com", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] }

windows-sys = { version = "0.59", features = [

    "Win32_Foundation",

    "Win32_Graphics_Dwm",

    "Win32_Graphics_Gdi",

    "Win32_System_LibraryLoader",

    "Win32_System_Registry",

    "Win32_System_SystemInformation",

    # The process's creation time, for the start-up report (milestone 683).

    "Win32_System_Threading",

    "Win32_UI_Accessibility",

    "Win32_UI_Controls",

    "Win32_UI_HiDpi",

    "Win32_UI_Input_KeyboardAndMouse",

    "Win32_UI_Shell",

    "Win32_UI_WindowsAndMessaging",

] }



[target.'cfg(target_arch = "wasm32")'.dependencies]

wasm-bindgen = "0.2"

wasm-bindgen-futures = "0.4"

# `Uint8Array`: reading a response body as bytes rather than as text (milestone 373).

js-sys = "0.3"

console_error_panic_hook = "0.1"

# `Request`/`RequestInit`/`Headers`/`Abort*`: the `fetch` HTTP helper (`net`) on the Web.

web-sys = { version = "0.3", features = [

    "Document",

    "Window",

    # `navigator.languages`: the reader's preferred languages, in order (milestone 454).

    "Navigator",

    # `navigator.clipboard`: copy and paste (milestone 526, #17).

    "Clipboard",

    # The address bar and the browser history (deep links): `location`, `history`, the base URL

    # of the document and the `popstate` listener.

    "History",

    "Location",

    "Url",

    # The tab's session storage: the component states a reload under `frus run` keeps.

    "Storage",

    "Node",

    "Event",

    "EventTarget",

    # The bridge's buttons stop an Enter or a Space from reaching the shell as a key (#23).

    "KeyboardEvent",

    # The tab's icon: the PNG becomes a Blob, and its object URL the icon link's address.

    "Blob",

    "BlobPropertyBag",

    "Element",

    "Response",

    "Request",

    "RequestInit",

    "Headers",

    "AbortController",

    "AbortSignal",

    # The page's notifications (milestone 704): `SystemNotification` on the Web.

    "Notification",

    "NotificationOptions",

    "NotificationPermission",

    # The accessibility bridge (milestone 564, #18): the canvas winit attached the

    # window to, and the element type its fallback-content nodes are built as.

    "HtmlCanvasElement",

    "HtmlElement",

    # The element a text field is edited through (milestone 711): the two kinds, the keys it

    # hands to the canvas, a composition's text, and where the canvas is on the page.

    "HtmlInputElement",

    "HtmlTextAreaElement",

    "KeyboardEventInit",

    "CompositionEvent",

    "DomRect",

    # The browser's console, a method per log level (milestone 604).

    "console",

    # The page's clock, which counts from the navigation (milestone 683).

    "Performance",

] }



# On Android, winit goes through the native activity (android-activity) and the logs

# land in logcat.

[target.'cfg(target_os = "android")'.dependencies]

winit = { workspace = true, features = ["android-native-activity"] }

android_logger = "0.14"

# The input bridge (InputConnection): loading the bundled dex plus its natives.

jni = "0.21"