From 6eaa6a1874167f7d051d7fc0bc6bc4012c8e2ab1 Mon Sep 17 00:00:00 2001 From: Anilcan Cakir Date: Fri, 11 Sep 2026 01:24:27 +0300 Subject: [PATCH 1/3] chore(deps): raise the fluttersdk_wind floor to 1.5.3 The ceiling was already there: ^1.2.0 admitted 1.5.x, so any app resolving fresh was on it. Moving the floor is what reaches an app that pinned Wind lower, and 1.5.3 is where a focused WAnchor answers ActivateIntent (keyboard, gamepad, TV remote), where one control costs one Tab stop instead of two, and where disabled: reaches a WDiv inside a disabled WAnchor. Magic renders its views through W-widgets, so those were magic's bugs too. The span carries one behavioural break for a pinned consumer: wind 1.4.0 made a single-line WInput default its Return key to TextInputAction.done instead of .next. Magic constructs no WInput of its own, so this reaches consumer forms only; the CHANGELOG entry names the fix. --- CHANGELOG.md | 2 ++ example/pubspec.lock | 8 ++++---- pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 192c1f0..6ed46e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ All notable changes to this project will be documented in this file. ### Changed +- **`fluttersdk_wind` moves from `^1.2.0` to `^1.5.3`, so every magic app gets Wind's keyboard and focus fixes rather than only the apps that happened to resolve fresh.** The ceiling does not move; the floor does. Anyone running `flutter pub get` without a pin was already on 1.5.x, because `^1.2.0` admitted it, so for them this changes nothing. It changes something for an app that pinned Wind lower: 1.5.3 is now the minimum, and the span it is being pulled across carries one behavioural break, 1.4.0 making a single-line `WInput` default its Return key to `TextInputAction.done` instead of `.next`. A multi-field form that relied on Return advancing the focus needs `textInputAction: TextInputAction.next` written out. What the floor buys is worth that: 1.5.3 makes a focused `WAnchor` answer `ActivateIntent`, so a control reachable by keyboard, gamepad or a television remote actually activates; it makes one control cost one Tab stop rather than two, which every `focus:ring-*` control in magic's own views was paying; and it fixes `disabled:` not reaching a `WDiv` inside a disabled `WAnchor`. Magic renders its views through W-widgets, so these are magic's bugs as much as Wind's. (`pubspec.yaml`) + - **`MagicFile.size` stays filled for every picked file, and it costs a `stat` on Windows and Linux to keep it that way.** v12 replaced `PlatformFile.size` with two readings: `lengthSync()`, the size the native picker reported, and `length()`, which measures the file when it reported none. The Windows dialog and the Linux XDG portal return a path and nothing else, so the synchronous reading is null for every desktop pick; reading it would have left `size` null exactly where a desktop app is most likely to be checking an upload limit, and the null would arrive as a silently skipped check rather than as an error. `Pick` reads `length()` instead. Web and Android always report a size, so the fallback only runs on desktop. (`lib/src/facades/pick.dart`) ### Fixed diff --git a/example/pubspec.lock b/example/pubspec.lock index 4768f32..08de40c 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -393,18 +393,18 @@ packages: dependency: transitive description: name: fluttersdk_wind - sha256: "6e45c03595e7b42cd2b1467d7aae0b6290e5f486f486b9434c65497e29f362af" + sha256: b436a41ab042be1cc578a69a6634e3f39cae2801505e6e2514d4e2ad9dd7f4fd url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.5.3" fluttersdk_wind_diagnostics_contracts: dependency: transitive description: name: fluttersdk_wind_diagnostics_contracts - sha256: "5d6b324dc334da9ab0b4b4703a551af5b080c4f659f57209a5516cf94e04f1f1" + sha256: "3c302f7504c9e8037072b4d2be2c266fb5488aa907eda1ce9321f1ee8556c972" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.0" glob: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index ce3a3f6..c873ffa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - fluttersdk_wind: ^1.2.0 + fluttersdk_wind: ^1.5.3 meta: ^1.16.0 more: ^4.7.0 dio: ^5.9.0 From 4e04a47c29d0aa73fdd4aec99e8954b47e0328cc Mon Sep 17 00:00:00 2001 From: Anilcan Cakir Date: Fri, 11 Sep 2026 01:24:46 +0300 Subject: [PATCH 2/3] docs: correct the stale dependency versions in the stack line Both files claimed fluttersdk_wind ^1.1.2 and fluttersdk_artisan ^0.0.8. The real constraints had moved to ^1.2.0 and ^0.0.9 without these following, and the wind bump above moves one of them again. --- .github/copilot-instructions.md | 2 +- CLAUDE.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 5492fdb..cc3fac5 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -4,7 +4,7 @@ Laravel-inspired Flutter framework: IoC container, 18 facades, Eloquent-style ORM, service providers, routing, auth, validation, broadcasting. UI is `fluttersdk_wind`; CLI + scaffolding run on `fluttersdk_artisan`. -**Stack:** Dart >=3.11.0 · Flutter >=3.41.0. Runtime deps: `fluttersdk_wind ^1.1.2`, `fluttersdk_artisan ^0.0.8`, `dio`, `go_router`, `sqlite3`, `flutter_secure_storage`, `encrypt`. No `mockito` (mock via contract inheritance), no code generation. +**Stack:** Dart >=3.11.0 · Flutter >=3.41.0. Runtime deps: `fluttersdk_wind ^1.5.3`, `fluttersdk_artisan ^0.0.9`, `dio`, `go_router`, `sqlite3`, `flutter_secure_storage`, `encrypt`. No `mockito` (mock via contract inheritance), no code generation. **Branch:** `master` is the active **0.0.x** development line — what pub.dev resolves. Pre-1.0: breaking changes are allowed; `1.0.0` is the future stable milestone. Direct pushes blocked; everything lands via PR. The dev-tooling adapters (`MagicDuskIntegration`, `MagicTelescopeIntegration`) live in the sibling `magic_devtools` package; magic core has zero dependency on `fluttersdk_dusk` / `fluttersdk_telescope`. CLI/scaffolding internals: `CLAUDE.local.md`. LLM-agent surface: `skills/magic-framework/SKILL.md`. Consumer overview: `README.md`. diff --git a/CLAUDE.md b/CLAUDE.md index a820391..2d3c2e0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ Laravel-inspired Flutter framework: IoC container, 18 facades, Eloquent-style ORM, service providers, routing, auth, validation, broadcasting. UI is `fluttersdk_wind`; CLI + scaffolding run on `fluttersdk_artisan`. -**Stack:** Dart >=3.11.0 · Flutter >=3.41.0. Runtime deps: `fluttersdk_wind ^1.1.2`, `fluttersdk_artisan ^0.0.8`, `dio`, `go_router`, `sqlite3`, `flutter_secure_storage`, `encrypt`. No `mockito` (mock via contract inheritance), no code generation. +**Stack:** Dart >=3.11.0 · Flutter >=3.41.0. Runtime deps: `fluttersdk_wind ^1.5.3`, `fluttersdk_artisan ^0.0.9`, `dio`, `go_router`, `sqlite3`, `flutter_secure_storage`, `encrypt`. No `mockito` (mock via contract inheritance), no code generation. **Branch:** `master` is the active **0.0.x** development line — what pub.dev resolves. Pre-1.0: breaking changes are allowed; `1.0.0` is the future stable milestone. Direct pushes blocked; everything lands via PR. The dev-tooling adapters (`MagicDuskIntegration`, `MagicTelescopeIntegration`) live in the sibling `magic_devtools` package; magic core has zero dependency on `fluttersdk_dusk` / `fluttersdk_telescope`. CLI/scaffolding internals: `CLAUDE.local.md`. LLM-agent surface: `skills/magic-framework/SKILL.md`. Consumer overview: `README.md`. From ab387aaad7d28e8fd2433cecb94d05ea8dbc0751 Mon Sep 17 00:00:00 2001 From: Anilcan Cakir Date: Fri, 11 Sep 2026 01:58:24 +0300 Subject: [PATCH 3/3] docs(changelog): put the WInput Return-key fix where an upgrader looks for it The Wind floor raise is filed under Changed because magic's own API does not move, and that is still right. But the span crosses wind 1.4.0, which changed what Return does in a multi-field form, and a reader scanning BREAKING for the 0.0.10 upgrade notes would never reach the line telling them to write out textInputAction. BREAKING now carries a pointer with the fix in it. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ed46e0..8b76ece 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ All notable changes to this project will be documented in this file. ### BREAKING +- **If you pinned `fluttersdk_wind` below 1.5.3, Return no longer moves the focus to the next field.** The Wind floor moves to `^1.5.3` (see the `### Changed` entry for what that buys), and the span crosses Wind 1.4.0, which made a single-line `WInput` default its Return key to `TextInputAction.done` instead of `.next`. Write `textInputAction: TextInputAction.next` on every field in a multi-field form that relied on the old default. Nothing in magic's own API changes, which is why the constraint itself is filed under Changed; this line exists so the fix is where you would look for it. (`pubspec.yaml`) + - **`file_picker` moves from `>=11.0.2 <12.0.0-0` to `^12.2.0`, and the `Pick` facade moves with it.** v12 splits the plugin into federated platform packages and rewrites the surface magic wrapped: `pickFiles` returns a plain `List` instead of a nullable `FilePickerResult`, `saveFile` returns a `Uri?` instead of a `String?`, and `PlatformFile` loses its `size` and `bytes` fields in favour of `lengthSync()` and `readAsBytes()`. None of that is expressible in a version range spanning both majors, which is why the constraint moves to `^12` rather than widening. (`pubspec.yaml`, `lib/src/facades/pick.dart`) - **`Pick.saveFile` returns `Future` and takes `fileName` and `bytes` as required arguments.** The old signature accepted both as nullable and threw an `ArgumentError` at runtime when either was missing, which was a guard against a mistake the type system can catch on its own; `required` moves that failure from the user's device to the compiler. The return type follows file_picker rather than flattening it: v12 documents the scheme as possibly `file`, `content`, `http(s)`, `data` or `blob`, so a `String` would hand back `content://com.android.providers.downloads/42` to code that was written to open a filesystem path. Call `uri.toFilePath()` after checking `uri.scheme == 'file'`, and treat the rest as opaque handles. (`lib/src/facades/pick.dart`)