You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 6d477b1
Browse filesBrowse the repository at this point in the historyBrowse files
Dart: native views from plain Dart programs, and a view example
- runNativeApp() in nativeapi runs an app on the platform's UI thread without
Flutter: on macOS it takes over the main thread the Dart VM keeps parked, on
Windows and Linux it starts a thread of its own, and it pumps the platform
loop between Dart's timers. Backed by an event loop shim in cnativeapi
(src/event_loop*), compiled by the build hook. nativeapi_flutter does not
re-export it.
- examples/dart_view_example: a workbench of native views (sign-in form, task
list, layout playground, notes, generated avatar) and a second window that
inspects its view tree and events. `dart run bin/main.dart`.
- Bump core: content-sized containers and the fixes the example needed.
- CI, melos and the docs cover examples/dart_*.
Cargo.toml # cargo workspace root: Rust crates and examples
18
18
tools/codegen/ # in-repo Rust workspace: the code generator
@@ -95,8 +95,8 @@ scenarios for *this project's* examples live in [tools/gui/](tools/gui/README.md
95
95
-`core` tracks `branch = main`. Use `make sync` to fast-forward it; `make status` to see dirty state everywhere; `make bump` to stage its pointer.
96
96
- The leanflutter packages built on nativeapi (`tray_manager`, `window_manager`, `launch_at_startup`, …) live in their own repos under github.com/leanflutter and depend on the published `nativeapi`; they are not part of this repo. To try one against local changes, point a `dependency_overrides` entry in that package at `bindings/dart/nativeapi_flutter` (and `nativeapi`, `cnativeapi`) and never commit the override.
97
97
- Commit workspace submodule pointer updates only when the combination is compatible (a known-good snapshot).
98
-
- Examples live in `examples/<binding>_<name>_example` (`flutter_`, `rust_`, `csharp_`, `js_`, `python_`), not inside the bindings; a new Flutter or Rust example must also be listed in the root `pubspec.yaml` / `Cargo.toml`, a C# one in `bindings/csharp/NativeAPI.slnx`, a JS one in the root `package.json`. A Python example is a standalone uv project whose `pyproject.toml` points `nativeapi` at `../../bindings/python` (`uv run main.py` builds the wheel). Only the pub.dev package examples (`bindings/dart/*/example`) stay inside their package.
99
-
- CI is one workflow per binding (`dart-ci.yml`, `rust-ci.yml`, `csharp-ci.yml`, `js-ci.yml`, `python-ci.yml`), each running only for changes under its `bindings/<lang>/` and its examples (`examples/flutter_*` for Dart, `examples/rust_*`, `examples/csharp_*`, `examples/js_*`, `examples/python_*`). Release tags are per binding: `v*` publishes the Dart packages (`dart-release.yml`), `rust-v*` publishes the crates (`rust-release.yml`), `python-v*` publishes the Python package to PyPI (`python-release.yml`: an sdist carrying core in `cxx_impl/`, and wheels built from it with cibuildwheel; the tag must equal `python-v` + the version in `bindings/python/pyproject.toml`); never push a bare `v*` tag for anything but the Dart packages. Nothing has been published to PyPI yet: the first release needs `nativeapi` set up on PyPI with this workflow and the `pypi` environment as a trusted publisher.
98
+
- Examples live in `examples/<binding>_<name>_example` (`dart_` for plain Dart programs, `flutter_`, `rust_`, `csharp_`, `js_`, `python_`), not inside the bindings; a new Dart, Flutter or Rust example must also be listed in the root `pubspec.yaml` / `Cargo.toml`, a C# one in `bindings/csharp/NativeAPI.slnx`, a JS one in the root `package.json`. A Python example is a standalone uv project whose `pyproject.toml` points `nativeapi` at `../../bindings/python` (`uv run main.py` builds the wheel). Only the pub.dev package examples (`bindings/dart/*/example`) stay inside their package.
99
+
- CI is one workflow per binding (`dart-ci.yml`, `rust-ci.yml`, `csharp-ci.yml`, `js-ci.yml`, `python-ci.yml`), each running only for changes under its `bindings/<lang>/` and its examples (`examples/dart_*` and `examples/flutter_*` for Dart, `examples/rust_*`, `examples/csharp_*`, `examples/js_*`, `examples/python_*`). Release tags are per binding: `v*` publishes the Dart packages (`dart-release.yml`), `rust-v*` publishes the crates (`rust-release.yml`), `python-v*` publishes the Python package to PyPI (`python-release.yml`: an sdist carrying core in `cxx_impl/`, and wheels built from it with cibuildwheel; the tag must equal `python-v` + the version in `bindings/python/pyproject.toml`); never push a bare `v*` tag for anything but the Dart packages. Nothing has been published to PyPI yet: the first release needs `nativeapi` set up on PyPI with this workflow and the `pypi` environment as a trusted publisher.
100
100
- The Dart packages `cnativeapi`, `nativeapi` and `nativeapi_flutter` share one version: a release bumps all three pubspecs and CHANGELOGs, because pub.dev's automated publishing matches the tag `v<version>` against each package's own version. `cnativeapi` and `nativeapi` are plain Dart (no Flutter dependency; a build hook compiles core); `nativeapi_flutter` is the Flutter-facing package, holding the widgets, the `dart:ui` conversions and `windowing.dart`, and re-exporting `nativeapi` minus the names that clash with Flutter's.
101
101
- Never commit in a submodule while on a detached HEAD — check out `main` first (`./codegen sync` enforces this).
Copy file name to clipboardExpand all lines: bindings/dart/README.md
+31-1Lines changed: 31 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -92,9 +92,39 @@ window?.isAlwaysOnTop = true;
92
92
93
93
All windows share one engine and one isolate, so they talk to each other through ordinary Dart objects — no runner changes, no message channels. Flutter's multi-window API is experimental and internal to the framework, which is why the bridge lives in its own library, `package:nativeapi_flutter/windowing.dart`. It is written against the **stable** channel (checked with 3.47.5); stable does not offer `flutter config --enable-windowing`, so the examples set Flutter's internal `isWindowingEnabled` in `main()`. See [`floating_toolbar_example`](../../examples/flutter_floating_toolbar_example) for a child window built this way, and [`browser_tabs_example`](../../examples/flutter_browser_tabs_example) and [`detachable_window_example`](../../examples/flutter_detachable_window_example).
94
94
95
+
### Windows and native views from plain Dart
96
+
97
+
A Dart program without Flutter can open windows too. Hand the app to `runNativeApp()`, which runs it on the platform's UI thread and keeps the platform loop turning between Dart's timers and futures:
if (event is ButtonClickedEvent) label.text = 'Clicked ${++clicks}×';
113
+
});
114
+
root
115
+
..addSubview(label)
116
+
..addSubview(button);
117
+
window.show();
118
+
}
119
+
120
+
void main() => runNativeApp(app);
121
+
```
122
+
123
+
`app` must be a top-level or static function: it runs in an isolate of its own. On macOS that isolate lives on the process's first thread, the only one AppKit accepts, which the Dart VM otherwise keeps parked. The process ends when the app quits (`Application.instance.quit()`, Cmd+Q). See [`dart_view_example`](../../examples/dart_view_example) for a larger app built this way.
124
+
95
125
## Examples
96
126
97
-
The examples are the `flutter_*` directories in the repository's [`examples/`](../../examples). Each is a Flutter app for one module; they resolve through the pub workspace at the repository root:
127
+
The examples are the `flutter_*` directories in the repository's [`examples/`](../../examples), plus [`dart_view_example`](../../examples/dart_view_example), a plain Dart program (`dart run bin/main.dart`). Each Flutter one is an app for one module; they resolve through the pub workspace at the repository root:
0 commit comments