3.5 KiB
3.5 KiB
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
// 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.
[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.