nigig-org/crates/nigig-system-prefs/README.md
2026-07-26 19:38:26 +03:00

87 lines
3.5 KiB
Markdown

# nigig-system-prefs
Cross-platform reader for OS-level preferences (dark mode, locale, accent
color). Follows the `robius-sms` cross-platform pattern: a `cfg_if!` block
dispatches to a per-platform `sys/*.rs` submodule.
## Why this exists
Makepad's `Cx` does not expose `platform_is_dark_mode()` on all branches
of its public API, and even where it does the value is cached at window
creation time — it does not update when the user toggles dark mode while
the app is running. This crate queries the OS directly on every call.
## API
```rust
// Boolean convenience:
let dark: bool = nigig_system_prefs::is_dark_mode().unwrap_or(false);
// Three-way (Linux exposes "no preference"):
let scheme: ColorScheme = nigig_system_prefs::color_scheme()?;
// BCP-47 locale tag ("en-US", "sw-KE"):
let locale: String = nigig_system_prefs::system_locale()?;
// Language subtag only ("en", "sw"):
let lang: String = nigig_system_prefs::system_language()?;
// Accent color as [r, g, b, a] floats (macOS / Windows only):
let rgba: [f32; 4] = nigig_system_prefs::accent_color()?;
```
## Platform support
| Platform | Dark mode | Locale | Accent |
|---|---|---|---|
| Android | ✅ `Configuration.uiMode` | ✅ `Configuration.locales[0]` | ❌ |
| macOS | ✅ `NSUserDefaults` | ✅ `NSLocale.currentLocale` | ✅ `NSColor.controlAccentColor` |
| iOS | ⚠️ TODO (`UITraitCollection`) | ✅ `NSLocale.currentLocale` | ❌ |
| Windows | ✅ registry `AppsUseLightTheme` | ✅ `GetUserDefaultLocaleName` | ✅ registry `AccentColor` |
| Linux | ✅ `gsettings` (GNOME 42+) | ✅ `$LANG` / `$LC_ALL` | ❌ |
| Other | ❌ `PermanentlyUnavailable` | ❌ | ❌ |
## Layout
```
nigig-system-prefs/
├── Cargo.toml # cfg-if + per-platform target deps
├── README.md
└── src/
├── lib.rs # public API + tests
├── error.rs # Error / Result
└── sys/
├── mod.rs # cfg_if! dispatch
├── android.rs # JNI via robius-android-env
├── apple.rs # objc2 + objc2-foundation (NSUserDefaults, NSLocale)
├── windows.rs # windows crate (registry + Globalization)
├── linux.rs # std::process::Command + std::env
└── unsupported.rs # fallback
```
## objc2 feature notes (Apple targets)
`NSUserDefaults` and `NSLocale` are Foundation classes — their cargo
features live on `objc2-foundation`, NOT on `objc2-app-kit`.
```toml
[target.'cfg(target_vendor = "apple")'.dependencies]
objc2-foundation = { version = "0.3", default-features = false, features = [
"std", "NSString", "NSArray", "NSObjCRuntime",
"NSUserDefaults", # ← Foundation feature
"NSLocale", # ← Foundation feature
] }
[target.'cfg(all(target_vendor = "apple", target_os = "macos"))'.dependencies]
objc2-app-kit = { version = "0.3", default-features = false, features = [
"std", "NSColor", "NSApplication",
# NOTE: objc2-app-kit 0.3.x does NOT have an NSUserDefaults feature.
# If you add it here you'll get:
# error: failed to select a version for `objc2-app-kit`.
# package depends on `objc2-app-kit` with feature `NSUserDefaults`
# but `objc2-app-kit` does not have that feature.
] }
```
The `objc2-app-kit` 0.3.x feature list is large (NSColor, NSApplication,
NSWindow, NSView, ...) but `NSUserDefaults` is not on it.