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
//! Theme ladder L1's macOS half: pin every hosted control's `NSAppearance` to
//! the APP's `Brightness`, not the Mac's system appearance — the AppKit twin
//! of `crate::apple::theme`'s `overrideUserInterfaceStyle` (that module's doc
//! is the reference account; this one records only what differs).
//!
//! # `NSView.appearance`, set after construction
//!
//! Like UIKit, AppKit has no "construct against a themed context" step: every
//! control resolves its dynamic `NSColor`s and its bezel/track/thumb drawing
//! from its `effectiveAppearance` at DRAW time, and `NSView.appearance` (the
//! `NSAppearanceCustomization` protocol every `NSView` adopts) is the
//! per-view knob that pins it. Setting it applies to the whole subtree, so a
//! composite's children (`crate::demo`'s card) follow their root. With the
//! property unset (`nil`) a view inherits its window's — i.e. the Mac's
//! system — appearance, which is exactly the leak L1 closes: an app whose
//! theme is Light must draw light controls on a Mac running Dark Mode.
//!
//! [`apply_brightness`] picks `NSAppearanceNameDarkAqua` or
//! `NSAppearanceNameAqua` from the same [`crate::controls::DARK`] wire bit the
//! other two arms read ([`brightness_is_dark`]) — carried not only by the
//! built-in controls' own `params_for` (`crate::api::builders`) but by every
//! `NativeComponent` slot's params too, folded in by
//! `crate::component::component_params` from `crate::api::mount`'s
//! `ambient_dark` (the same `use_context::<Theme>()` the builders read).
//! Without that, a component root such as `crate::demo::DemoCard` would carry
//! no `dark` key at all and stay permanently pinned to the light appearance
//! regardless of the app's theme.
//!
//! # Re-pinned on EVERY update, like iOS — never baked like Android
//!
//! `NSView.appearance` is a plain mutable property, so there is nothing
//! forcing it to be baked at construction the way Android's
//! `createConfigurationContext` is. It is applied on create **and** on every
//! `update_params`: `crate::apple::theme`'s on-device gate found the bug
//! a create-only pin causes — a control culled off-screen and later
//! RECREATED adopts whatever brightness is current at recreate time while its
//! never-culled siblings keep the one they were born under, so the two
//! diverge (the reported repro drew a recreated switch's thumb
//! accent-on-accent, i.e. invisible). Re-pinning per update makes "which
//! appearance is this control pinned to" a function of the CURRENT theme, and
//! makes an in-place brightness toggle re-theme platform chrome live. Do not
//! "restore symmetry" with Android's construction-time bake — the asymmetry
//! belongs to the platforms (`docs/PLUGINS_CODE_STANDARDS.md`'s Plugin
//! Conventions). `Unchanged` updates re-pin too: brightness lives on the wire,
//! not in any control's diffed `Props`, so a props-equal update can still
//! carry a new brightness.
//!
//! # The call site: inside `AppKitFactory` itself, like iOS
//!
//! Both Apple arms now pin from inside the one factory: the iOS arm from its
//! typed `create_control`/`update_control`, this arm from
//! `crate::appkit::factory`'s `create`/`update_control`
//! (`crate::appkit::factory`'s own module doc — *Theme ladder L1*). That
//! covers every slot the desktop host drives — the built-in controls, every
//! `NativeComponent`, and a dead-slot placeholder alike (pinning an empty
//! `NSView` is harmless) — with no separate wrapper and no second
//! registration: `crate::appkit::factory::ensure_registered` is the one
//! registration function.
use ;
use crateDARK;
use crateParams;
/// Whether a slot's params requested the dark half of the active theme — read
/// straight off the raw wire ([`DARK`]), exactly like
/// `crate::apple::theme::brightness_is_dark`. Absent degrades to `false`
/// (light): appearance pinning is cosmetic, never a reason to fail a slot.
pub
/// L1: pin `view`'s (and its whole subtree's) appearance to Dark Aqua or Aqua
/// — see the module doc for why this is a per-view property and why it runs on
/// every update, not only at create.
///
/// `appearanceNamed:` answering `nil` (it does not for the two standard
/// names) degrades to clearing the pin, i.e. following the window — logged,
/// never a failure.
pub