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
Make cnativeapi and nativeapi plain Dart; move Flutter code to nativeapi_flutter
cnativeapi is no longer a Flutter FFI plugin. A build hook
(hook/build.dart, native_toolchain_c) compiles core with the target's
toolchain, replacing the per-platform CMake, CocoaPods and SwiftPM
projects and the generated Apple source wrappers. ffigen (now 22) emits
top-level @Native functions bound to that code asset, so the
CNativeApiBindings class and cnativeApiBindings are gone. codegen.py is
folded into ./codegen as `./codegen ffigen`; the release workflow only
vendors core into cxx_impl/.
nativeapi drops its Flutter dependency. Point, Size, Rectangle and Color
are generated as nativeapi's own value types instead of dart:ui's Offset,
Size, Rect and Color, and every generated value type gets ==, hashCode
and toString over its data fields (callbacks left out).
nativeapi_flutter now holds the Flutter side: the widgets, ImageAsset,
windowing.dart, the widget tests and the example app, plus conversions
to and from dart:ui (toOffset/toSize/toRect/toColor, toNative). Its
re-export of nativeapi hides Brightness, Color, Display, Image and Size,
which would silently shadow dart:ui, and ModifierKey and ShortcutManager,
which are ambiguous with Flutter's.
The flutter_* examples depend on nativeapi_flutter and convert at the
nativeapi boundary; those that name a hidden type import nativeapi with
a prefix.
Copy file name to clipboardExpand all lines: AGENTS.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,7 +24,7 @@ codegen # Python entry point orchestrating the generators
24
24
25
25
-`core` — the C++ core library (repo: `nativeapi-core`). The source of truth for the native API surface (windows, tray icons, menus, displays, keyboard, dialogs, storage, etc.) with per-platform implementations (macOS/Windows/Linux).
26
26
-`tools/codegen` — three crates: `shared` (libclang parser, IR, naming), `capi` (C ABI + umbrella header), `bindings` (Rust/Dart/C# generators, consuming the IR JSON emitted by `capi`). Only `capi` depends on libclang. See tools/codegen/README.md.
27
-
-`bindings/*` — language bindings wrapping the core library. All live in this repo and build against the `core/` submodule directly (Rust `build.rs`, the Flutter plugin's CMake and generated Apple source wrappers, the C# native CMake). Only a published package carries its own copy of core, in `cxx_impl/`, which the release workflows vendor and never commit. The Rust binding layers `nativeapi` (safe API) over `cnativeapi` (FFI).
27
+
-`bindings/*` — language bindings wrapping the core library. All live in this repo and build against the `core/` submodule directly (Rust `build.rs`, the Dart `cnativeapi` package's build hook, the C# native CMake). Only a published package carries its own copy of core, in `cxx_impl/`, which the release workflows vendor and never commit. The Rust binding layers `nativeapi` (safe API) over `cnativeapi` (FFI).
28
28
29
29
## Design specs
30
30
@@ -63,12 +63,12 @@ A core change ripples to every binding. After editing headers in `core`, run:
63
63
./codegen sync -m "<core commit message>"
64
64
```
65
65
66
-
It regenerates everything, reruns `bindgen` (Rust raw FFI) and the Dart binding's `codegen.py` (umbrella headers + ffigen), then commits core and this repo (`Sync with core <sha>`: the core pointer plus everything regenerated under `bindings/`). Add `--push` to publish in dangling-safe order (core → workspace).
66
+
It regenerates everything, reruns `bindgen` (Rust raw FFI) and `ffigen` (Dart raw FFI), then commits core and this repo (`Sync with core <sha>`: the core pointer plus everything regenerated under `bindings/`). Add `--push` to publish in dangling-safe order (core → workspace).
67
67
68
68
Manual follow-ups sync cannot do (details in tools/codegen/README.md):
69
69
70
70
- New handle types need an `IdTypeTag<T>` entry in `core/src/foundation/id_allocator.h` (append only; a miss is a compile error, not silent).
71
-
- Hand-written files in the bindings (exports, re-exports, changelogs, examples) are never touched by the generators. Rust's `pub mod` list is generated (`modules.rs`); Flutter's `lib/nativeapi.dart` exports are not.
71
+
- Hand-written files in the bindings (exports, re-exports, changelogs, examples) are never touched by the generators. Rust's `pub mod` list is generated (`modules.rs`), and so is Dart's (`nativeapi/lib/src/generated.dart`); `nativeapi_flutter`'s exports are not.
72
72
73
73
The `core-api-change` skill walks the whole flow, including what to check before `sync` commits.
74
74
@@ -91,10 +91,10 @@ scenarios for *this project's* examples live in [tools/gui/](tools/gui/README.md
91
91
## Conventions
92
92
93
93
-`core` tracks `branch = main`. Use `make sync` to fast-forward it; `make status` to see dirty state everywhere; `make bump` to stage its pointer.
94
-
- 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` (and `cnativeapi`) and never commit the override.
94
+
- 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.
95
95
- Commit workspace submodule pointer updates only when the combination is compatible (a known-good snapshot).
96
96
- Examples live in `examples/<binding>_<name>_example` (`flutter_`, `rust_`, `csharp_`), 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`. Only the pub.dev package examples (`bindings/dart/*/example`) stay inside their package.
97
97
- CI is one workflow per binding (`dart-ci.yml`, `rust-ci.yml`, `csharp-ci.yml`), each running only for changes under its `bindings/<lang>/` and its examples (`examples/flutter_*` for Dart, `examples/rust_*`, `examples/csharp_*`). Release tags are per binding: `v*` publishes the Dart packages (`dart-release.yml`), `rust-v*` publishes the crates (`rust-release.yml`); never push a bare `v*` tag for anything but the Dart packages.
98
-
- 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. `nativeapi_flutter` is the Flutter-facing package; for now it only re-exports `package:nativeapi`.
98
+
- 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.
99
99
- 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
+18-8Lines changed: 18 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,16 +14,26 @@ English | [简体中文](./README-ZH.md)
14
14
15
15
| Package | What it is |
16
16
| --- | --- |
17
-
|[`nativeapi`](nativeapi)| The API: windows, tray icons, menus, displays, keyboard, dialogs, storage and more. |
18
-
|[`cnativeapi`](cnativeapi)| Raw FFI bindings to core's C ABI and the native build; used by `nativeapi`. |
19
-
|[`nativeapi_flutter`](nativeapi_flutter)|The Flutter-facing package. For now it re-exports `nativeapi`. |
17
+
|[`nativeapi`](nativeapi)| The API: windows, tray icons, menus, displays, keyboard, dialogs, storage and more. Plain Dart, usable without Flutter. |
18
+
|[`cnativeapi`](cnativeapi)| Raw FFI bindings to core's C ABI; its build hook compiles core. Used by `nativeapi`. |
19
+
|[`nativeapi_flutter`](nativeapi_flutter)|For Flutter apps: re-exports `nativeapi` and adds widgets, `dart:ui` conversions and the multi-window bridge. |
20
20
21
21
## Installation
22
22
23
+
A Flutter app:
24
+
23
25
```bash
24
-
flutter pub add nativeapi
26
+
flutter pub add nativeapi_flutter
25
27
```
26
28
29
+
A Dart app (command line, or any other Dart host):
30
+
31
+
```bash
32
+
dart pub add nativeapi
33
+
```
34
+
35
+
`nativeapi` has its own `Point`, `Size`, `Rectangle` and `Color` types. `nativeapi_flutter` converts them to and from `dart:ui` (`window.bounds.toRect()`, `Offset(10, 20).toNative()`), and leaves out the nativeapi names that Flutter already uses (`Brightness`, `Color`, `Display`, `Image`, `ModifierKey`, `ShortcutManager`, `Size`); import `package:nativeapi/nativeapi.dart` with a prefix to name one of those.
36
+
27
37
## Quick Start
28
38
29
39
```dart
@@ -36,7 +46,7 @@ for (final display in DisplayManager.instance.getAll()) {
36
46
37
47
### Custom window chrome
38
48
39
-
Wrap a custom title bar in `DragToMoveArea` to move the window by dragging (double tap to maximize/restore), and the window content in `DragToResizeArea` to resize from its edges and corners:
49
+
With `package:nativeapi_flutter/nativeapi_flutter.dart`, wrap a custom title bar in `DragToMoveArea` to move the window by dragging (double tap to maximize/restore), and the window content in `DragToResizeArea` to resize from its edges and corners:
40
50
41
51
```dart
42
52
DragToResizeArea(
@@ -61,8 +71,8 @@ Both widgets use `WindowManager.instance.getCurrent()` unless a `window` is pass
61
71
```dart
62
72
import 'package:flutter/src/foundation/_features.dart' show isWindowingEnabled;
63
73
import 'package:flutter/src/widgets/_window.dart' as fw;
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/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).
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).
0 commit comments