Repository navigation
[Resources] Support prioritized locale fallback chain for resources (CMP-6840) - #5754
Closed
Abhishek Keshri (2KAbhishek) wants to merge 6 commits into
Closed
Abhishek Keshri (2KAbhishek) wants to merge 6 commits into
Abhishek Keshri (2KAbhishek) wants to merge 6 commits into
Conversation
Abhishek Keshri (2KAbhishek)
marked this pull request as ready for review
October 13, 2026 07:46
Abhishek Keshri (2KAbhishek)
force-pushed
the
fix/resource-locale-fallback-chain
branch
2 times, most recently
from
October 13, 2026 08:00
840049a to
abb46ae
Compare
Abhishek Keshri (2KAbhishek)
force-pushed
the
fix/resource-locale-fallback-chain
branch
2 times, most recently
from
October 13, 2026 10:10
9012f2a to
d856db1
Compare
Resource matching only looked at the first preferred language, so an app that ships Spanish but no French gave a user who prefers French, then Spanish, the unqualified values/ folder. Walk the list and take the first locale that matches, as in table 3 of Android's multilingual support guide. A locale also falls back to another region of the same language first, as in table 2, but never across scripts: a locale that names one is matched on it, and otherwise the script the region implies is compared, so neither zh-Hans nor zh-CN lands on values-zh-rTW. Fixes https://youtrack.jetbrains.com/issue/CMP-6840
Every platform handed the matcher a list of one, so a user whose first language has no resources could not reach their second. Android reads LocaleList.getDefault(), which follows a per-app language where Resources.getSystem() does not. Apple reads NSLocale.preferredLanguages, and the web reads navigator.languages. A single locale from LocaleList.current stays in front of the list, since an app that calls Locale.setDefault to choose its language cannot be told apart from a platform default here. The new internal systemPreferredLocales() keeps composition from also resolving a theme and a screen DPI that it takes from Compose anyway. Fixes https://youtrack.jetbrains.com/issue/CMP-6840
Plural categories came from the first preferred locale, which is no longer the language the string is written in. A user who prefers French and then English, in an app shipping only English plurals, got the French rule for zero. Take the language and the region from the matched resource item instead. Fixes https://youtrack.jetbrains.com/issue/CMP-6840
Desktop was the last target still reporting a single locale. Neither the JDK nor a dependency of this module exposes the list, so the Windows one is read from the registry, the macOS one through defaults, and other systems fall back to the gettext environment variables. Both subprocesses resolve once per process behind a timeout, and any failure leaves the single platform locale in place. A POSIX locale has no script field and carries it in the modifier, so the script-bearing modifiers from glibc localedata/SUPPORTED are mapped and the rest, which name a currency or a dialect, are dropped. Fixes https://youtrack.jetbrains.com/issue/CMP-6840
An application shipping base development resources without language qualifiers in values/ (by convention, English) must not skip those resources when a user's prioritized locale list includes English ahead of a secondary language that has explicit overrides (e.g. values-hi/). Allow unqualified resources to provide the unregionalized base candidates for the default language when no explicit values-en/ folder is present. Fixes https://youtrack.jetbrains.com/issue/CMP-6840
Sync golden API and KLib ABI files after introducing LocaleQualifiers and syncing upstream changes.
Abhishek Keshri (2KAbhishek)
force-pushed
the
fix/resource-locale-fallback-chain
branch
from
October 13, 2026 10:12
d856db1 to
4b0e568
Compare
Contributor
Author
|
I have raised a fix for https://youtrack.jetbrains.com/issue/CMP-6840 here and was hoping to get your feedback, can you please take a look when you have a chance 🙏🏽 If you think I should reach out to someone else please let me know, Thank you |
Member
|
It is already WIP: #5759 |
Member
|
(and next time, please, don't send as AI slop PRs) |
Abhishek Keshri (2KAbhishek)
deleted the
fix/resource-locale-fallback-chain
branch
October 15, 2026 12:35
Abhishek Keshri (2KAbhishek)
restored the
fix/resource-locale-fallback-chain
branch
October 15, 2026 12:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Resolves CMP-6840 by supporting prioritized multi-locale resource matching across all platforms.
Previously, resource matching evaluated only a single platform locale. If an application provided resources in Spanish (
values-es/) but not French, a bilingual user preferring French then Spanish ([fr, es]) received the defaultvalues/folder instead of their second-preference Spanish. Furthermore, platforms reported only a single preferred locale to Compose.Key Changes & Design Considerations
Prioritized Multi-Locale Matching:
fr-CHfr-FR). To avoid bundling heavy CLDR distance tables across KMP targets, CMP uses deterministic alphabetical selection (.minOrNull()) when multiple alternate regions are available.zh-Hans/zh-CNnever substitutes forzh-Hant/zh-TW), covering both region-qualified and script-qualified folders (values-b+zh+Hans/). Explicit script qualifiers are respected across all languages.Full Preferred Locale Reporting Across Platforms:
LocaleList.getDefault(), respecting per-app language settings and Android 13+ app locales.NSLocale.preferredLanguagesdirectly (retaining region and script qualifiers without Xcode bundle filtering).navigator.languages.HKCU\Control Panel\International\User Profile), macOS (/usr/bin/defaults read -g AppleLanguages), or POSIX environment variables (LANGUAGE,LC_ALL,LANG), with a 2-second timeout and lazy single-instance caching. Falls back safely toLocale.getDefault()if subprocess execution is restricted (e.g., sandboxed macOS environments).androidx.compose.ui.text.intl.LocaleList.currentat the head of the chain when set (preserving explicit app overrides likeLocale.setDefault).Base Language Convention for Unqualified Resources:
composeResources/values/represents the base development language (English by default).values-en/directory, unqualifiedvalues/resources satisfy unregionalized English candidates. This ensures bilingual English users (e.g.,[en-US, es-US]) receive base English rather than unintentionally skipping to a secondary language override.values-en/and regionalvalues-en-rXX/folders continue to take strict precedence when provided.Resource-Aware Pluralization:
API Stability:
apiDump) for the@InternalResourceApi data class LocaleQualifiersaddition.Fixes CMP-6840
Testing
Run from the
componentsdirectory:ResourceTestcovering multi-locale fallback chains, regional fallback, script mismatch isolation, pluralization locale selection, and unqualified resource precedence.:resources:library:desktopTestand:resources:library:testAndroidHostTest.Release Notes
Fixes - Resources
fr-CHusesvalues-fr-rFR). Script compatibility is strictly enforced sozh-Hansnever matchesvalues-zh-rTWvalues/resources satisfy base English when no explicitvalues-en/folder exists, preventing bilingual users with English as a primary preference from unintentionally falling back to secondary language overrides