# 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.