rust_widgets 1.1.2

Pure Rust cross-platform native GUI library with hardware-adaptive rendering, 60+ widgets, touch/gesture support, i18n, and SVG-pipeline-accurate output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
# Changelog

All notable changes to this project are documented in this file.

## 1.1.2 (2026-09-12) — Platform Correctness & Unsafe-Surface Audit Release

An audit-driven release. Work began as "complete the Apple-related items in `blue14.md`" and
continued through seven rotated audit directions (FFI soundness, error-path leaks, concurrency/panic
safety, memory/long-run, API-contract consistency, doc/code consistency, and unsafe-impl necessity).
Every fix below was reproduced first, then closed with a regression test and **negative verification**
(revert the fix → the test must fail).

### Fixed — Apple (host-visible only on macOS, so latent for the project's whole history)
- **`MacOSPlatform` (cocoa-legacy) made unguarded AppKit calls from any thread.** Creating a window
  or touching any of ~30 other call sites from a worker thread made AppKit raise a foreign
  Objective-C exception, which Rust cannot catch, so the **entire test process died with SIGABRT**
  (`cargo test --lib --features desktop` aborted in `c_abi_widget_lifecycle_roundtrip`).
  Added an `is_main_thread()` guard plus a state-only fallback handle to every AppKit entry point,
  and made `add_to_parent_window`/`sync_list_box_native` skip nil receivers (the `cocoa` crate
  dereferences null and aborts).
- **`macos_objc2` native FFI was gated on the alias feature `objc2-macos` instead of `macos`.**
  Because feature aliases are one-way, `--features macos` left **43 native call sites silently
  compiled out**, degrading the backend to state-only with no error. Now gated on the canonical
  feature.
- **`set_native_text` declared `performSelector:withObject:` as returning `()`**, but it returns
  `id`; the mismatch aborted at runtime. Return type corrected.
- **`ime_macos` declared `ImeCtx` as four identically-named *local* structs.** `Any::downcast_ref`
  matches on `TypeId`, not memory layout, so every downcast silently returned `None` and **three
  native IME paths were no-ops**. Types hoisted to module level.

### Fixed — FFI soundness
- **Removed three unnecessary `unsafe impl Sync`, each proven redundant by a delete-and-compile
  test**: `EventHandlerContext` (`json/events.rs`), `LinuxPlatform` (`linux/types.rs`), and
  `TsfThreadMgr` (`ime_windows.rs`). Each removal compiled clean across desktop, `--all-features`,
  every profile, and `x86_64-pc-windows-gnu`. `EventHandlerContext` was the sharpest case: it exposes
  both `user_data<T>() -> &T` and `user_data_mut<T>() -> &mut T` from the same unowned pointer, so a
  `Sync` impl would have legalized a genuine data race. `AndroidPlatform`'s `Sync` was **kept**  removing it produces 55 `E0277` errors, i.e. real code depends on it. The crate now has exactly
  one `unsafe impl Sync`.

### Fixed — resource leaks on error paths
- **`ffmpeg_encoder` leaked its temp file on any encode failure.** `format::output_as` creates the
  file before many `?` early-returns, so failures after that point left the file behind. Now guarded
  by RAII (`TempFileGuard`).
- **`ffmpeg_decoder` leaked on write failure** — same class, fixed the same way.

### Fixed — concurrency, panic safety, timing
- **i18n hot-reload trusted `mtime` alone**, so on coarse-granularity filesystems a change could be
  missed entirely. Replaced with a content fingerprint.
- **`undo/stack` test fixture used `static mut`**, a real data race between concurrent tests. Now atomic.
- **Data-binding's `syncing` re-entrancy flag stayed stuck forever if a callback panicked**, silently
  disabling all future two-way sync. Now an RAII guard, so a panic unwinds it.

### Fixed — API contracts and lifecycle
- **`StubPlatform` contradicted itself**: 21 `create_*` methods ignored their `parent` argument while
  19 sibling methods validated it. All 21 now validate, so tests built on the stub are a valid
  contract baseline. `create_menu_bar` requires a `Window` parent; `create_menu` requires
  `MenuBar | Menu`.
- **`macos`/cocoa's `create_spin_box`/`create_list_view`/`create_scroll_area` ignored `parent`**
  while the `create_group_box` directly beneath them validated it. Fixed.
- **Added `Platform::destroy_widget()` and `widget_count()`** (plus `rw_destroy_widget` in the C ABI,
  all 11 backends, and the `ControlBackend` trait). Previously there was **no way to destroy a
  widget at all**, so dynamic UIs accumulated registry entries without bound. Cleanup is real, not
  cosmetic: objc2 releases derived submenu ids and cascades menu children; cocoa now calls the
  previously-never-called `a11y_bridge.unregister_handle`; iOS releases its `ButtonTarget`.
- **GTK clipboard panicked off the main thread.** `gtk_clipboard()` called
  `gdk::Display::default()` directly, and GDK panics ("may only be used from the main thread") on a
  non-GTK thread, aborting the process; the function's own doc comment claimed it returned `None`
  there. Now guarded by `gtk::is_initialized_main_thread()` with the documented mirror fallback.
- **`libvorbis` was hard-coded as an external encoder.** This had been misattributed as an
  "environment failure"; `brew deps ffmpeg` / `otool -L` proved Homebrew's ffmpeg ships no vorbis.
  Now falls back to ffmpeg's native Vorbis encoder.

### Fixed — test coverage that was not actually running
- **50 logic-only tests were excluded from the build** by module-level `#[cfg(target_os = ...)]`:
  `ime_macos` (19), `macos_objc2` (17), `android` (8), `ios` (6). All now execute on the host.
  Un-gating them exposed a previously-uncompilable `assert_eq!` in the `android` tests
  (`AndroidHandleKind` lacked `Debug`).
- Earlier rounds likewise recovered `ime_windows` (15) and `windows_notify` (11) tests that were
  trapped behind `target_os` gates despite being pure state-machine logic.
- Added `platform::contract_tests` (11 tests, incl. a 17-method parent-rejection matrix) and
  `platform::teardown_tests` (3 tests asserting the library's own registry sizes).

### Added
- `tools/check_widget_kind_count.sh` — mechanically parses `src/widget/kind.rs` and fails if any
  document's stated widget-kind count has drifted. Wired into the CI `validation-gates` job.
- `tools/check_apple_native.sh`, `tools/check_apple_thread_safety.sh`, `tools/build_ios_testapp.sh`,
  `tools/run_ios_testapp.sh` — a real iOS `.app` (staticlib + ObjC host, no Xcode project) that
  boots an iOS simulator, installs, launches, and asserts `RESULT: PASS`; plus AppKit probes for
  both macOS backends.
- `examples/apple_appkit_probe_objc2.rs` — a separate probe for the objc2 backend (the two macOS
  backends use different Objective-C crates).
- An `apple-native` CI job covering both macOS backends and the iOS simulator run.

### Changed
- Crate version bumped `1.1.1``1.1.2`. **No ABI change**: `rw_bindings_api_version` remains `8`.
  `rw_destroy_widget` is a new symbol in the generated header (106 declarations, up from 105).
- Version references aligned to `1.1.2` in `Cargo.toml`, the `CoreConfig` runtime version contract,
  Node.js/Python package metadata, the demo banner, and the en/zh-CN/zh-TW cookbooks.
- **Docs corrected where they contradicted the code**: `codemap.md` claimed 166 `WidgetKind`
  variants (actual 167), and both READMEs advertised "80+ widgets" (actual 167 kinds).

### Verification
- `cargo test --lib`: **3854 passed**, 0 failed (desktop) / **3946** (full) / **1869**
  (`--all-features`); mobile 3662, tablet 3653, wasm 2263, harmony 2268 — all 0 failed.
- `clippy --all-features --all-targets -- -D warnings`: **0 warnings**; `cargo fmt --check` clean.
- `cargo check --all-targets` across desktop/full/mini/embedded/mobile/tablet/wasm/harmony: 0 errors.
- Eight CI gates pass: profiles, ABI, widget-kind count, platform capability matrix, capability
  truthfulness, control route matrix, platform impl matrix, Apple thread safety.
- Both macOS AppKit probes report `RESULT: PASS` (12 named checks each) against live AppKit objects.

### Notes on what was deliberately *not* changed
- **Dialog parent validation stays as-is.** `create_message_box` / `create_file_dialog` /
  `create_color_dialog` / `create_font_dialog` ignore the parent on 7 of 11 backends and validate on
  4. Ignoring is the majority convention and is semantically right (dialogs are top-level modals,
  not children of a widget); forcing uniformity would break the 7 backends behaving correctly. The
  contract is now pinned by a test so future audits do not re-flag it.
- **`accessibility/windows` stays gated.** It references `winapi::um::winuser::EVENT_*`
  unconditionally, so it genuinely cannot compile off Windows, and un-gating it would only produce
  an empty assertion body (false coverage).
- **An RSS-based leak claim was retracted as wrong.** A draft report asserted a leak from
  "8000 widgets → +49 MB RSS". Three independent checks disproved it: macOS `leaks --atExit`
  reported `0 leaks for 0 total leaked bytes`, malloc node counts did not grow under churn, and a
  pure-AppKit control (no rust-widgets code) reproduced the same RSS curve. The growth is AppKit's
  own caching. Regression tests now assert registry state, not RSS.

## 1.1.1 (2026-09-11) — Cross-compilation & Coverage Visibility Release

### Fixed — cross-compilation
- **AVIF now uses the pure-Rust `avif` codec instead of `avif-native`.**
  `avif-native` pulled in `dav1d-sys`, a system C library that fails to cross-compile for
  Android/iOS/wasm unless a pkg-config sysroot is configured by hand. This made the
  `mobile`/`tablet`/`desktop` profiles impossible to build for any foreign target.
  Trade-off: slower AVIF decode and ~15 extra build-time crates (`rav1e` et al.), in exchange
  for genuinely cross-compilable builds. Verified: Android (2 ABIs × 5 profiles), iOS,
  Windows (msvc/gnullvm), and wasm32 all compile clean.
- **Cross-target cfg-gating mismatches fixed** in `platform/runtime.rs`, `platform/android/types.rs`,
  `platform/ios/types.rs`, `gpu/adapter.rs`, and `compat.rs`. Several imports and helpers were gated on
  `target_os` alone while their users were also gated on `not(feature = "mini")` /
  `not(feature = "embedded")`, producing `E0432`/`E0433`/`E0599` on the affected combinations.
- **`compat::OnceLock` gained `set()`** so the `mini` profile matches the `std::sync::OnceLock` API
  surface (the Windows notify path calls it).

### Fixed — control routing
- **`NativeControlBackend` delegated to the wrong platform primitives**, discarding real Win32
  implementations:
  - `create_checkbox``create_toggle_button` (bypassed `BS_AUTOCHECKBOX`)
  - `create_spin_box``create_double_spin_box` (bypassed `msctls_updown32`)
  - `create_scroll_area``create_panel` (bypassed the scrollable child window)
  The two reverse delegations (`create_toggle_button`, `create_double_spin_box`) were dead code and
  now preserve widget identity.
- **Per-OS routing for `SpinBox`/`ListView`/`ScrollArea`.** They have real Win32 implementations but
  were listed in the global `CustomRequired` arm, so the native path was unreachable on Windows while
  other platforms (which have no such primitive) genuinely need the custom backend. Routing now
  promotes them to `NativePreferred` **only under `cfg(target_os = "windows")`**, pinned by two
  complementary tests.

### Fixed — test coverage visibility
- **50 pure-logic tests that never compiled or ran on any reachable path** are now part of the host
  build, following the BLUE14 rule that "not in the build" must be distinguished from "failed" and
  "ignored": `ime_macos` (19), `android` (8), `ios` (6), `macos_objc2` (17). Each was verified by
  mechanical scan to touch no OS API.
- **`AndroidHandleKind` was missing `Debug`**, which made three of its own `assert_eq!` tests
  impossible to compile. Never surfaced because the module was excluded from the host build.
- **`cargo test --all-features` (the actual CI command) did not compile** (`E0277`): `serialize_state`
  was gated more loosely than the `BackendState` `Serialize` derive it depends on.
- **`tools/generate_platform_capability_matrix.py`** now derives the degradation table by mechanically
  parsing `native.rs`; the capability-matrix doc is gated against drift in CI. Its prose is generated,
  so hand-editing the markdown is no longer possible without the freshness check failing.

### CI
- **`wasm-check` job was permanently broken**: it ran `--features wasm` without
  `--no-default-features`, which pulled in the whole `desktop` profile (audio, JS engine) for a wasm32
  target. Now pinned to `--no-default-features --features wasm`.
- **`android-cross-check` job was a no-op**: it passed `-Zlinker-features`/`-C linker` (rustc flags,
  invalid for `cargo check`) and swallowed every failure with `|| echo skipped`. It now exports the
  NDK linker/compiler via `CARGO_TARGET_*`/`CC_*` and checks 2 ABIs × 5 profiles with no failure mask.

### Changed
- Crate version bumped `1.1.0``1.1.1`. **No ABI change**: `rw_bindings_api_version` remains `8`
  and no exported symbols were added or removed.
- Version references aligned to `1.1.1` across `Cargo.toml`, the `CoreConfig` runtime version contract,
  Node.js/Python package metadata, the demo banner, and the en/zh-CN/zh-TW cookbooks.

### Documentation
- README (en + zh-CN) refreshed: corrected the stale test-count badge (`3700+`/`3400+``3850+`),
  documented the AVIF codec switch and its trade-off, added the CI cross-compile commands, and
  filled in zh-CN sections that had drifted (Web widget list, Special widgets, `performance`/`memory`
  core modules, Performance section).
- `docs/plans/blue14.md` updated with the round-8 audit record (E-class), including the one item
  deliberately left gated (`accessibility/windows`) because un-gating it would only produce an
  empty assertion body.

### Verification
- `cargo test --lib`: **3853 passed**, 0 failed (was 3820).
- `cargo test --all-features` (CI command): 0 failed (previously failed to compile).
- `clippy --all-targets -D warnings` and `clippy --all-features --all-targets -D warnings`: 0 warnings.
- All profiles (desktop/mobile/tablet/mini/embedded/full) and cross-targets
  (iOS / wasm32 / Windows gnullvm) build with 0 errors, 0 warnings.
- Android JNI test APK builds and signs via `tools/build_android_testapp.sh`.

## 1.1.0 (2026-09-09) — Version Contract Sync Release

### Changed
- Crate version bumped `1.0.0``1.1.0` (stable line; **not** an ABI break).

### Bindings & docs
- Version references aligned to `1.1.0` across code, demo banner, and documentation:
  `Cargo.toml`, package metadata (Node.js `package.json`, Python `setup.py`), demo/control banner,
  CoreConfig default version contract, and all cookbook/README version mentions.

### Connectivity
- `CoreConfig::desktop()/embedded()/mobile()` default version synced to `1.1.0`
  (runtime `Version` contract mirrors the crate semantic version; existing `Version`-type API
  examples and ABI contract `rw_bindings_api_version` = `8` are unchanged).

## 1.0.0 (2026-09-02) — Stable Release

### Stability & Quality
- **Stable public API line declared**; `rw_bindings_api_version` bumped to `8` for the 1.0 ABI contract.
- **Full compile matrix at zero errors/warnings**: every profile (desktop/tablet/mobile/mini/embedded/bare),
  every capability feature and cross-combination, plus all installed targets
  (windows-msvc, android aarch64/x86_64/armv7, wasm32-unknown-unknown/wasip1/wasip1-threads) verified clean.
- **Platform code compiled for the first time**: Windows (TSF `Send` safety, winapi pointer types) and
  Android backends now build and lint cleanly.
- **WASM end-to-end**: real `cargo test` on `wasm32-wasip1` (2158 tests passing via wasmtime);
  browser wasm (`wasm32-unknown-unknown`) builds/lints clean.
- **Tablet/mobile profiles compile for the first time**: dependency/feature gaps fixed
  (i18n/video feature cohesion, `tr!` macro gating, runtime stub cfg), 3509/3514 tests passing.

### Honest implementation pass (no fake/stub behavior)
- Audio: removed synthetic FLAC/OGG/AAC/Opus decoding and PCM-impersonating encoders; missing codec
  features now return explicit `Err`. Real FFmpeg/symphonia paths verified (2195 tests).
- Image: PNG decoder rewritten (scanline filters, RGBA stride, 16-bit sampling, bounds safety);
  GIF/WebP/TIFF/AVIF/ICO/SVG decoders now refuse instead of fabricating pixels.
- Video MJPEG failures are explicit (`FrameType::Synthetic` + diagnostics); web-engine JS evaluation
  wired to a real engine; PDF security markers no longer leak passwords.
- Line-edit clipboard shortcuts wired; undo zero-capacity panic fixed; software text rastering
  handles Unicode instead of truncating to `u8`.
- Dead code removed (`misc_widgets/chip.rs`, `image/svg_utils.rs`); dead test file mounted (`pdf/tests.rs`).

### Bindings & docs
- FFI bindings complete: C++ header and Python wrapper cover all 105 exported symbols (105/105);
  `rw_bindings_api_version` = 8 for the 1.0 ABI line.
- Capability matrix regenerated at 167 rows matching the 167 `WidgetKind` variants, with honest
  degradation notes; `unexpected_cfgs` lint restored to `warn`.
- README/docs aligned with code; version bumped 0.9.10 → 1.0.0 everywhere (Cargo, demo banner,
  Node.js package, migration guide).

### Full release backlog (folded in from the former `[Unreleased]` section)
### Added

- Signal-first event model migration notes for `v9`:
  - generic `Signal<T>` core with typed payload dispatch
  - `connect_once` one-shot slot semantics
  - scoped auto-disconnect via owner lifetime drop
- Expanded typed widget trigger kinds in platform/C ABI routing:
  - `3`: `selection-changed`
  - `4`: `closed`
- Geometry/style baseline primitives for `v10`:
  - `Point::new/origin`, `Size::new/is_empty`, `Rect::new/from_position_size/position/size/decompose/is_valid`
  - `Color::parse_hex` (`#RGB/#RGBA/#RRGGBB/#RRGGBBAA`), canonical hex serializers, `u32` pack/unpack
  - `Font` weight baseline (`100..=900`), shared defaults, and normalization helpers
  - `Padding`/`Margin` per-side types with `all/symmetric/normalized` constructors
  - axis-specific alignment enums and mapping helpers (`HorizontalAlignment`/`VerticalAlignment`)
- Basic widget full-class baseline for `v12`:
  - `Label`: deterministic text/alignment/image/word-wrap state with change signals
  - `LineEdit`: return-pressed signal, password-mode masking, selection/copy/cut/paste contract
  - `CheckBox`/`RadioButton`: tri-state + group-selection routing with explicit state/selected signals
  - `ComboBox`/`Slider`/`ProgressBar`: deterministic index/value range-clamped change signaling
- CI signal-first guard:
  - `tools/check_event_model_signal_first.sh` blocks wxWidgets-style event table patterns
  - validation gate wired in `.github/workflows/ci.yml`
- Layout system baseline for `v13`:
  - explicit `HBoxLayout` / `VBoxLayout` named layout types with `Layout` parity
  - deterministic `BoxLayout` major-axis allocation (remainder-aware, constraint-safe)
  - spacing/margin/item-count tuning APIs for directional layout control
  - focused layout regressions for box/grid/stack placement and auto geometry conversion
- Action system baseline for `v14`:
  - shared action routing parity across menu/button/toolbar hosts plus shortcut triggers
  - deterministic trigger contract with enabled gating and trigger result semantics
  - checkable action semantics (`checkable`, `checked`, toggle-on-trigger)
  - action state signals for signal-first routes (`triggered`, `toggled`, `enabled_changed`)
  - focused regressions for action binding/trigger/toggle behavior
- Intermediate widgets slice for `v15`:
  - `ScrollBar` full-state contract (`min/max/value/page_step/single_step`) with deterministic `value_changed`
  - `ScrollArea` baseline contract (`content_size`/`viewport_size`/`scroll_offset`) with signal-first change events
  - focused widget regressions for bounded scroll behavior and offset normalization
  - `GroupBox` title/checkable/checked deterministic contract with state change signals
  - `TabWidget` deterministic selected-index routing (`add/remove/select`) with `current_index_changed`
  - `Splitter` pane-ratio/size distribution contract with orientation/layout change signals
  - `MenuBar`/`Menu`/`ToolBar`/`StatusBar` intermediate host contracts for action routing and status/message state signals
  - dialog-family baseline contracts: `Dialog`, `MessageBox`, `FileDialog`, `ColorDialog`, `FontDialog`
    with deterministic result/state signals for accept/reject/select flows
- Model/view architecture baseline for `v16`:
  - observable model signal surface via `data_changed_signal` on `ListModel`/`TreeModel`/`TableModel`
  - in-memory observable model contracts: `VecListModel`, `VecTreeModel`, `VecTableModel`
  - auto-refresh wiring in `TreeView::set_model` and `TableWidget::set_model` (model changes trigger redraw/layout requests)
  - focused regressions for model signal propagation and tree/table view refresh behavior
- Advanced widgets kickoff for `v17`:
  - `ListView` baseline contract with `ListModel` projection, deterministic selection, and model-driven auto-refresh wiring
  - dedicated `TableView` contract wrapper with `TableWidget` parity for model/delegate/selection APIs
  - expanded tree/table/list advanced view state contracts with focused row/node state and projection-safe normalization on model rebind
  - `RichEdit` baseline contract with text/selection/read-only state and deterministic edit/cursor signals
  - container baselines: `DockPanel` pane-placement contract and `MdiArea` document/active-document state contract
  - focused regressions for `ListView`/`TableView` baseline behavior and full widget-suite compatibility
- Runtime GUI mode contract for `v18`:
  - `RuntimeGuiMode::{NativeInteractive, PreviewOrStub}` and active-backend resolvers
  - startup mode reporting in `demo_main` for explicit backend behavior visibility
  - v18 startup smoke matrix and evidence template in `docs/QA_HARNESS.md`

### Changed

- Native signal bridge routing now normalizes covered widget interactions through typed trigger routes
  (`clicked`, `value-changed`, `selection-changed`, `closed`) instead of per-kind ad-hoc paths.
- Widget interaction baseline now emits explicit selection/closed signals for covered controls
  (window, combo box, tree view, table widget).
- Representative widget/layout entry points now accept primitive geometry/style workflows:
  - widget trait helpers: `position/size`, `set_position/set_size`, `padding/margin`, `set_padding/set_margin`
  - layout trait helper: `update_from_position_size(position, size, ...)`
- XML style parsing now reuses shared color parser (`Color::parse_hex`) and supports short/alpha hex forms.
- Advanced widget runtime kinds are now disambiguated for `RichEdit`, `ListView`, `DockPanel`, and `MdiArea`
  (no longer aliased to baseline kinds like `TextEdit`/`ListBox`/`Panel`/`StackWidget`).
- Historical roadmap audit coverage for `v1~v9` is now explicitly recorded and re-validated against code/tests/scripts.
- Embedded profile behavior-matrix validation now stays green by gating `serde_json`-dependent core deserialization test behind `desktop-runtime` feature.
- Validation sweep for this audit slice is green: `check_profiles`, `check_event_model_signal_first`, `cargo test --lib`, `check_behavior_matrix`, `check_visual_regression`, and `check_abi`.
- Windows runtime lifecycle path now uses active message pumping with stable loop-alive behavior for `demo_main`.
- Non-native preview backends now emit explicit runtime diagnostics:
  - Linux (non-`gtk-native`)
  - Harmony desktop preview path
  - Android mobile preview backend
  - macOS objc2 preview backend
- Cross-platform control creation routing now uses explicit backend `create_*` implementations (Linux/Harmony/macOS-objc2/mobile + Windows overrides) with no implicit demo/C-ABI button fallback shims for slider/progress/combo paths.
- Platform default `create_*` methods now fail explicitly (`0`) when unsupported; Windows backend create failures also return `0` with runtime diagnostics instead of silent button downgrade.

### Migration Notes

- Existing `Font::new(family, size, bold, italic)` remains supported; it now derives normalized `weight`
  (`400` regular, `700` bold). Prefer `Font::with_weight(...)` for explicit typography contracts.
- Existing uniform spacing behavior is preserved (`Padding::all`, `Margin::all`), while per-side values are
  now available for forward-compatible style contracts.
- Geometry callers can incrementally adopt primitive helpers without breaking existing `Rect` call sites.

## 0.9.10 (2026-07-23) — Code Quality Release

### Infrastructure
- **mod.rs refactoring (20/20 complete)**: All module declaration files now contain only `pub mod` declarations and `pub use` re-exports; implementation code moved to dedicated files (custom_paint, init, legacy_types, a11y_wiring, arc_helpers, gpu_types, backend, test_types)
- **Three profiles at 0 errors**: `default`, `mini`, and `embedded` all pass `cargo check` with zero errors
- **0 clippy warnings**: All unnecessary casts and manual range checks eliminated
- **0 `#[deprecated]` items**: All 28 deprecated annotations removed
- **0 `todo!()` / `unimplemented!()`** across the entire codebase

### Bug Fixes
- PdfPage naming conflict: struct renamed to `ExportPage`, trait retained as `PdfPage`
- Control backend dispatcher: fixed overlapping `#[cfg]` conditions causing duplicate function definitions in mini profile
- Embedded profile: 70 errors fixed (chrono/serde dependency gating, advanced widget module gating)

### Dependency Management
- `serde::Serialize`/`Deserialize` derives made conditional: `#[cfg_attr(feature = "serde", derive(...))]` across core types (Color, Font, WidgetRecord, etc.)
- `chrono` imports gated behind `not(mini)` / `not(embedded)` in capability layer
- `serde_json::Value` usage gated behind `not(embedded)` for json module
- Asset, advanced_widgets, media_widgets modules gated behind `cfg` for embedded profile

### Test
- Total: 3771 tests passing (3676 lib, 70 integration, 25 doctests)

## [0.10.0] - 2026-06-10

### Added

- **WidgetKind cleanup**: Removed orphan/duplicate variants from the widget kind enum
  for a cleaner, more maintainable categorisation.
- **macOS + iOS native FFI wiring**: Full native platform FFI bridges for macOS
  (AppKit/NSAccessibility) and iOS (UIKit/UIAccessibility), enabling native control
  creation and accessibility event routing.
- **i18n system (complete)**: Fully functional internationalisation with locale
  loading, plural rules, and context-based message translation.
- **StyleSheet engine**: CSS-like declarative style system with selector matching,
  cascading, and computed property resolution.
- **New layouts**:
  - `FlexLayout` — flex-box style responsive layout
  - `WrapLayout` — flow-based wrapping layout
  - `KeyboardAwareLayout` — auto-offset layout for soft keyboard
  - `ConstraintLayout` — anchor/constraint-based positioning
  - `Center` — centred container layout
  - `AspectRatio` — fixed-ratio sizing wrapper
- **New infrastructure**:
  - `App Lifecycle` — structured application lifecycle management
  - `Undo/Redo` — full undo/redo framework with command stack and composite commands
  - `Data Binding` — reactive model-to-view automatic synchronisation
  - `Print framework` — cross-platform print and preview API
  - `PDF export` — PDF document generation with form, image, and security support
- **New widgets** (65+):
  - Tooltip, SegmentedButton, NavigationStack, ProgressCircle, Icon
  - Popover, MenuButton, DropdownMenu
  - MaskedEdit, AutoCompleteEdit, MultiSelectComboBox
  - RangeSlider, FloatingLabel
  - TabView, SearchBar
  - Cupertino* controls: CupertinoNavigationBar, CupertinoSegmentedControl,
    CupertinoDatePicker
  - SwipeToDismiss, Pager/PageView, RefreshControl
  - ModalBottomSheet
  - FindReplaceDialog, PropertiesPanel
  - Charts: LineChart, BarChart, PieChart, Sparkline
  - EditableComboBox, DateRangePicker
  - AnimatedImage — frame-based animation widget with loop control
  - HeroAnimation — shared-element transition animation widget
  - BezierCurveEditor — interactive cubic Bézier curve editor
  - ColorHistory — colour swatch history with selection/hover signals
  - FontPreview — live font preview with configurable sample text
  - ShortcutEditor — keyboard shortcut configuration editor
  - InplaceEditor — click-to-edit text field with accept/cancel signals
- **Platform backends**:
  - `android` — full Android Platform trait implementation (state-driven)
  - `wasm` — WASM platform module for web browser execution
- **IME implementations**:
  - `macOS` — NSTextInputContext-based IME bridge
  - `Windows` — TSF-based IME bridge
  - `Linux` — IBus-based IME bridge
- **A11y enhancements**:
  - `A11yRole` enum with 27 semantic roles (Button..Unknown)
  - `A11yState` / `A11yNode` / `A11yTree` for screen reader tree management
  - `A11yProvider` trait for cross-platform screen reader integration
  - NSAccessibility protocol helpers (macOS) and UIA control type helpers (Windows)
  - `DefaultA11yProvider` in-memory implementation with focus traversal
- **Text shaping & rich text**:
  - `TextShaper` / `SimpleTextShaper` — text measurement and glyph run shaping
  - `RichText` / `TextSpan` / `TextStyle` — multi-span styled text rendering
  - `TextOverflow` / `TextClamp` — ellipsis, clip, and multi-line clamp handling
  - `GraphemeCluster` / `GraphemeProcessor` — Unicode emoji, combining marks, and ZWJ grapheme support
- **Platform backend refactoring**:
  - `macOS` (objc2) — `platform_impl.rs` split into `widget_creation.rs`, `menu_impl.rs`,
    `widget_state.rs`, `clipboard_dnd.rs`, `dialog_creation.rs`, `native.rs` for maintainability
  - `Linux``platform_impl.rs` split into `widget_creation.rs`, `menu_impl.rs`,
    `widget_state.rs` for maintainability
- **Render pipeline refactoring**:
  - `render/pipeline/` split — `containers.rs` extracted from monolithic pipeline
    into dedicated sub-module per widget family for maintainability
- **Testing**: 3400+ test cases across all subsystems

### Changed

- Missing docs lint changed from `allow` to `warn` to surface documentation gaps.

## 0.9.6 (2026-06-09) — BLUE11 Release

### New Widgets (28 new controls)
- **Popular Controls**: Switch, SearchBox, Chip, Badge, SkeletonLoader, FAB, Avatar, Rating, Stepper, Divider, Carousel, EmptyState, ColorWell, QRCode
- **Mobile-First**: PullToRefresh, BottomSheet, BottomNavigationBar, NavigationDrawer, AppBar, MobileDatePicker, ContextMenu (alias)
- **Platform Styles**: CupertinoSwitch, MaterialSnackbar, AdaptiveScaffold
- **Desktop Advanced**: PropertyGrid, WizardDialog, TagInput
- **Input Support**: ImePreedit
- **Layout**: MasonryLayout

### Visual Effects (R5)
- BoxShadow, Blur, ClipPath, BlendMode (16 modes), ConicGradient render commands
- Software and SVG backend support for all new commands

### Animation System (R6)
- KeyframeAnimation with multi-keyframe interpolation
- TransitionManager for CSS-style property transitions
- SpringAnimation with physical spring dynamics
- ThemeStateManager dark/light auto mode

### Accessibility (R7)
- AccessibleRole mappings for all 30+ new widgets
- AriaProperties struct for platform API bridging
- FocusTraversalStrategy (TabOrder, RowMajor, ColumnMajor)
- HighContrastMode support (BlackOnWhite, WhiteOnBlack, Custom)
- ReducedMotionPreference detection

### Event System (R8)
- Pointer Events with pressure and tilt support
- Gamepad Events (press, release, axis, connect/disconnect)
- AsyncTask with thread-local task queue
- IdleTask with frame-threshold scheduling

### Configuration & Documentation (R4)
- Cargo.toml enhanced (authors, categories, include/exclude)
- deny.toml for cargo-deny license auditing
- ARCHITECTURE.md and TUTORIAL.md documentation
- WIDGET_GALLERY.md visual reference
- .gitignore coverage improvements

### Quality & CI (R3)
- 130+ new tests across all new widgets
- CI: cargo-deny license audit job
- CI: docs-build check job
- Full feature build verification

### Architecture (R9)
- Widget re-export normalization
- containers.rs confirmed at 849 lines (no split needed)
- missing_docs and unsafe_code lint warnings added

## [0.5.19] - 2026-03-03

### Added

- v19 GPU visual parity coverage builders and regressions for covered controls:
  - base controls: `Window`/`Panel`/`Label`/`Button`/`CheckBox`/`RadioButton`/`LineEdit`
  - data/range controls: `ComboBox`/`ListBox`/`ProgressBar`/`Slider`/`ScrollBar`
  - host/navigation controls: `MenuBar`/`Menu`/`ToolBar`/`StatusBar`/`TabWidget`/`StackWidget`
- GPU parity aggregate regression tests:
  - `render::tests::gpu_parity_covered_controls_emit_non_empty_command_suite`
  - `render::tests::gpu_parity_covered_controls_auto_compose_runs_with_gpu_or_cpu_backend`
- New covered-control GPU parity demo:
  - `demos/demo_wgpu_control_parity.rs` (`cargo run --features gpu-wgpu --example demo_wgpu_control_parity`)
- QA/profile gate integration for P3g parity checks:
  - `tools/check_behavior_matrix.sh`
  - `tools/check_profiles.sh`

### Changed

- Embedded v19 closure stream is now fully documented as complete (`P4a`..`P4d`) with explicit residual embedded host-control unsupported boundaries.
- Version updated from `0.5.0` to `0.5.19` in `Cargo.toml`.

### Notes

- GPU implementation mode remains the light-weight route by design for this cycle:
  CPU command rasterization + `wgpu` upload/readback through the unified auto backend selection path.
- Controls without explicit GPU parity builders remain documented as uncovered in roadmap/docs for follow-up expansion.

## [0.5.0] - 2026-03-02

### Added

- Basic widgets milestone is complete and stabilized (Button/Label/LineEdit/CheckBox/RadioButton/ComboBox/SpinBox/Slider/ProgressBar).

### Changed

- Project crate version is now `0.5.0`.

## [0.1.0] - 2026-03-01

### Added

- CI validation gate job in `.github/workflows/ci.yml`:
  - profile matrix gate via `tools/check_profiles.sh`
  - ABI gate via `tools/check_abi.sh`
- New C ABI profile-aware capability contract query:
  - `rust_widgets_platform_capability_contract(profile_code)`
- Demo smoke script:
  - `tools/smoke_demos.sh` for `default` (`demo_main`) and `embedded` (`demo_button`) checks.
- First Python binding adapter path:
  - `examples/python/rust_widgets.py` (ctypes adapter)
  - `examples/python/demo_basic.py` (basic usage demo)
- Feature-completeness CI artifact pipeline:
  - `feature-completeness-matrix` job in `.github/workflows/ci.yml`
  - artifact upload for `target/qa/feature_completeness_matrix.md`
- Allowlist-aware matrix auditing inputs:
  - `tools/feature_completeness_allowlist.toml`

### Implemented

- PDF form serialization baseline in `src/pdf/mod.rs`:
  - `PdfPage` form APIs now emit `/AcroForm` and page `/Annots` widget objects
  - text/checkbox/button widgets are serialized into the object graph
- PDF security persistence diagnostics path in `src/pdf/mod.rs`:
  - `PdfSecurity` settings are persisted via explicit unsupported-encryption diagnostic entries
  - reader path restores those diagnostics on round-trip load
- PDF image deterministic encoding route in `src/pdf/mod.rs`:
  - image normalization routes (`exact-rgb`, `exact-rgba-drop-alpha`, `exact-gray-expand`, `raw-truncate-pad`)
  - removed synthetic payload-tiling behavior and added stream route metadata comments
- PDF regression expansion:
  - focused and combined tests now cover forms + security + image pipelines and reader round-trip behavior

### Changed

- Release preparation baseline for `0.1.0` (metadata hardening + publish dry-run workflow).
- Runtime diagnostics output is now structured as:
  - `[rust_widgets.runtime] stage=<...> profile=<...> backend=<...> route=<...>`
- Feature-completeness report format now includes:
  - raw/effective/suppressed signal counts
  - allowlist suppression reasons by file/category

## [0.0.2] - 2026-03-01

### Added

- GitHub project governance and collaboration files:
  - `LICENSE` (MIT), `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `SECURITY.md`, `SUPPORT.md`
  - Issue templates and PR template under `.github/`
  - CI workflow and Dependabot configuration
- Desktop shell capability parity improvements:
  - richer menu/menu item lifecycle support in desktop backends
  - typed widget trigger event model (clicked/value-changed)
- C ABI enhancements:
  - typed trigger polling API: `rust_widgets_poll_widget_trigger_event`
  - expanded core control constructors (`label`, `radio_button`, `slider`, `progress_bar`, `combo_box`, `list_box`, `panel`)
  - trigger injection APIs for host/native event sources
  - Harmony callback entrypoints for direct ArkUI/NAPI integration
  - node-handle registry APIs (`node_handle ↔ widget_id`) for Harmony integration
- New bridge and onboarding assets:
  - `docs/C_ABI_QUICKSTART.md`
  - `docs/HARMONY_NATIVE_BRIDGE.md` and localized variants
  - `examples/rust_widgets.h`
  - `examples/c_abi_poll_demo.c`
  - `examples/harmony_napi_bridge_sample.c`
- New runtime demo:
  - `demos/demo_native_events.rs`
- v2 validation tooling:
  - `tools/check_profiles.sh` for default/examples/embedded matrix checks
  - `tools/check_abi.sh` for ABI header drift + symbol and version gate checks

### Implemented

- Real print backend path in `src/print/mod.rs`:
  - system spool submission via `lpr`/`lp` on macOS/Linux
  - print-verb submission path on Windows
  - `Printer::print_with_result` for explicit backend error reporting
- Real PDF backend path in `src/pdf/mod.rs`:
  - valid minimal PDF (`%PDF-1.4`) serialization with catalog/pages/xref/trailer
  - page drawing commands mapped to PDF operators (`BT/Tj`, `m/l/S`, `re`, `f`)
  - reader supports `/Count` page parsing for round-trip loading baseline
- Real chart backend path in `src/chart/mod.rs`:
  - SVG rendering context (`SvgChartContext`) for concrete vector output
  - file export helper `render_chart_to_svg_file`
  - demo integration that exports `target/debug/demo_chart.svg`
- Embedded deep trimming path:
  - embedded builds exclude `xml`, `i18n`, `theme`, and `bindings` modules
  - `init()` uses a no-op i18n initializer under `embedded` profile
  - verified by `cargo check --no-default-features --features embedded`
- Dual-engine architecture baseline:
  - new `render_engine` module with `RenderEngine` trait
  - `NativeRenderEngine` and `EmbeddedRenderEngine` implementations
  - lifecycle APIs (`init`/`run`/`quit`) routed through default engine selection
- Object reflection/property enhancement:
  - dynamic `PropertyValue` model in `src/object/mod.rs`
  - reflective property APIs (`set_property`, `property`, `remove_property`, `property_keys`)
- Platform capability expansion:
  - `PlatformCapabilities` model and DPI scale query in `src/platform/mod.rs`
  - C ABI exposure via `rust_widgets_platform_capabilities` and `rust_widgets_platform_dpi_scale_factor`
  - C header sync in `examples/rust_widgets.h`
- ABI engineering improvements:
  - automated header generator `tools/generate_c_header.py`
  - generated artifact `examples/rust_widgets.generated.h`
  - C ABI versioning advanced to `5`

### Changed

- Linux backend now supports optional native GTK signal path under feature `gtk-native`.
- Documentation index expanded in `README.md` and localized help docs for C ABI and Harmony bridge coverage.
- C ABI version increased to `5` to reflect newly added public ABI functions.
- Lifecycle routing boundaries are profile-explicit:
  - desktop profile calls native platform lifecycle directly
  - embedded profile keeps lifecycle routed through `RenderEngine`
- Desktop-only dependencies (`serde_json`, `lazy_static`, `roxmltree`) are now optional via `desktop-runtime` feature to reduce embedded footprint.

### Notes

- Default builds remain stable and pass `cargo check` and `cargo check --examples`.
- Optional feature checks pass for `gtk-native` and `harmony-native`.