Repository navigation
fix(arm64-linux): fix CJK font rendering on flutter-elinux - #15324
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds ARM64 Linux CJK font support: a new ChangesCJK Font Fallback for ARM64 Linux
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@flutter/lib/native/font_manager.dart`:
- Around line 70-75: The fc-list command in the Process.run call uses `:lang=zh`
which only searches for Chinese fonts, but this can return a Chinese-only font
lacking Japanese and Korean glyph support, breaking the CJK goal. Modify the
language filter argument in the Process.run call to probe for fonts that support
all CJK languages (Chinese, Japanese, and Korean) instead of just Chinese,
ensuring the returned font can properly render characters for all three language
scripts.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0921c86a-a151-4f7d-a922-78cdbf84d4b1
📥 Commits
Reviewing files that changed from the base of the PR and between 36e812e and e9ff958b0aecdd36ba8e2f41f1da0abff1c1f724.
📒 Files selected for processing (3)
flutter/lib/common.dartflutter/lib/main.dartflutter/lib/native/font_manager.dart
There was a problem hiding this comment.
🧹 Nitpick comments (1)
flutter/lib/native/font_manager.dart (1)
40-45: 💤 Low valueConsider adding a timeout to
Process.runcalls.If
uname(orfc-listin_findCjkFontPath) hangs unexpectedly, the app startup will block indefinitely. Adding a timeout provides defense-in-depth for this startup path.♻️ Suggested improvement
try { - final r = await Process.run('uname', ['-m']); + final r = await Process.run('uname', ['-m']).timeout( + const Duration(seconds: 5), + onTimeout: () => ProcessResult(0, 1, '', 'timeout'), + ); if (r.stdout.toString().trim() != 'aarch64') return false; } catch (_) { return false; }Apply the same pattern to the
fc-listcall in_findCjkFontPath.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@flutter/lib/native/font_manager.dart` around lines 40 - 45, The Process.run calls for 'uname' and 'fc-list' lack timeouts, which could cause the app to hang indefinitely during startup if these commands become unresponsive. Add a timeout parameter to both Process.run calls: the 'uname' invocation in the current code block and the 'fc-list' call in the _findCjkFontPath method. Wrap the timeout in a Duration object and ensure that if the timeout expires, the catch block gracefully returns false to allow the app to continue startup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@flutter/lib/native/font_manager.dart`:
- Around line 40-45: The Process.run calls for 'uname' and 'fc-list' lack
timeouts, which could cause the app to hang indefinitely during startup if these
commands become unresponsive. Add a timeout parameter to both Process.run calls:
the 'uname' invocation in the current code block and the 'fc-list' call in the
_findCjkFontPath method. Wrap the timeout in a Duration object and ensure that
if the timeout expires, the catch block gracefully returns false to allow the
app to continue startup.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 04928a6b-f42a-4608-a2c0-5dc869091871
📥 Commits
Reviewing files that changed from the base of the PR and between fc35608a052f80da33c5442db24a1d06f3ab577e and 062289a88f22ea11ae1bb6d7ef13d84ff3cd07e3.
📒 Files selected for processing (3)
flutter/lib/common.dartflutter/lib/main.dartflutter/lib/native/font_manager.dart
🚧 Files skipped from review as they are similar to previous changes (2)
- flutter/lib/common.dart
- flutter/lib/main.dart
|
Good job. Please limit this to arm only. |
|
Done. Added a |
|
@coderabbitai review |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check the current state of font_manager.dart
cat flutter/lib/native/font_manager.dart 2>/dev/null || echo "File not found"
echo "---"
# Check relevant parts of main.dart
grep -n "cjk\|CJK\|arm\|aarch\|loadSystem\|_cjkFont" flutter/lib/main.dart 2>/dev/null || echo "No matches in main.dart"Length of output: 4757
This means the CJK workaround is completely inert on x86_64 Linux, macOS, Windows, and Android. The implementation aligns with the maintainer's feedback. Triggering a fresh review now. ✅ Action performedReview finished.
|
✅ Action performedReview finished.
|
|
The web version seems broken.
Please confirm. |
|
I asked claude, there is better way to detect arch. or You need to ensure web version again. |
|
Done. I think the web version should be fixed now. |
There was a problem hiding this comment.
Pull request overview
This PR adds an app-level workaround for ARM64 Linux builds where the flutter-elinux engine lacks --enable-fontconfig, causing Flutter to fail to discover system fonts and render CJK glyphs as tofu. It proactively loads a system CJK font at startup and propagates it through theming and default text styling so both Material widgets and bare Text() widgets can render CJK characters.
Changes:
- Add ARM64 Linux system CJK font discovery/loading via
FontLoader, with a web stub for conditional import compatibility. - Apply a theme-wide
fontFamilyFallbackto both light/dark themes at startup after a font is loaded. - Wrap app builders with a
DefaultTextStyle.mergefallback so non-themed/bareTextwidgets inherit the CJK fallback.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| flutter/lib/web/font_manager.dart | Web stub implementation for conditional import; no-op font loading. |
| flutter/lib/native/font_manager.dart | ARM64 Linux font discovery (fc-list + fallback paths) and FontLoader registration. |
| flutter/lib/main.dart | Calls font loader at startup; applies theme fallback and merges fallback into DefaultTextStyle via app builders. |
| flutter/lib/common.dart | Adds MyTheme.applyFontFallback() to apply fontFamilyFallback across both themes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| try { | ||
| final loader = FontLoader(kLinuxCjkFontFamily); | ||
| final bytes = await File(path).readAsBytes(); | ||
| loader.addFont(Future.value(ByteData.view(bytes.buffer))); |
The flutter-elinux engine used for ARM64 Linux builds is compiled without --enable-fontconfig, so Flutter's text shaper cannot discover system fonts. This causes CJK characters to render as tofu boxes even when fonts such as Noto Sans CJK are installed. See flutter/flutter#139293. Fix by loading a CJK font at startup via FontLoader (bypassing fontconfig) and propagating it through two paths so all text widgets are covered: 1. MyTheme.applyFontFallback() — updates textTheme on both light and dark ThemeData so Material components receive the fallback through the theme. 2. _mergeCjkFallback() in GetMaterialApp builders — wraps child widgets in DefaultTextStyle.merge so bare Text() widgets and those with inherit:true also render CJK characters correctly. Font discovery queries fc-list for zh, ja, and ko separately, preferring fonts present in all three sets (true pan-CJK fonts such as NotoSansCJK or SourceHanSans) over Chinese-only fonts that may lack Japanese kana or Korean hangul glyphs. Falls back to a hardcoded search-path list covering Debian/Ubuntu, Fedora/RHEL, Arch Linux, and WenQuanYi font layouts. This is an app-level workaround. The engine-level fix is tracked at flutter/flutter#180235 (open as of 2026-06). Fixes rustdesk#10666 Signed-off-by: Bia503 <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
|
Done. I've applied the first suggestion manually. |
|
I accidentally force-pushed and overwrote your commit 😫. I've already recovered that. |
|
I realized that since I recovered the commit, I'm now listed as the author. Would you mind re-pushing your original commit from your end? |
| } catch (e) { | ||
| debugPrint('ARM64 Linux: failed to load CJK font: $e'); | ||
| return false; | ||
| } |
| } catch (e) { | ||
| debugPrint('ARM64 Linux: fc-list failed for lang=$lang: $e'); | ||
| } |
|
Since #15376, this PR will be reverted. |
…15324) * fix(arm64-linux): fix CJK font rendering on flutter-elinux The flutter-elinux engine used for ARM64 Linux builds is compiled without --enable-fontconfig, so Flutter's text shaper cannot discover system fonts. This causes CJK characters to render as tofu boxes even when fonts such as Noto Sans CJK are installed. See flutter/flutter#139293. Fix by loading a CJK font at startup via FontLoader (bypassing fontconfig) and propagating it through two paths so all text widgets are covered: 1. MyTheme.applyFontFallback() — updates textTheme on both light and dark ThemeData so Material components receive the fallback through the theme. 2. _mergeCjkFallback() in GetMaterialApp builders — wraps child widgets in DefaultTextStyle.merge so bare Text() widgets and those with inherit:true also render CJK characters correctly. Font discovery queries fc-list for zh, ja, and ko separately, preferring fonts present in all three sets (true pan-CJK fonts such as NotoSansCJK or SourceHanSans) over Chinese-only fonts that may lack Japanese kana or Korean hangul glyphs. Falls back to a hardcoded search-path list covering Debian/Ubuntu, Fedora/RHEL, Arch Linux, and WenQuanYi font layouts. This is an app-level workaround. The engine-level fix is tracked at flutter/flutter#180235 (open as of 2026-06). Fixes rustdesk#10666 Signed-off-by: Bia503 <[email protected]> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <[email protected]> --------- Signed-off-by: Bia503 <[email protected]> Co-authored-by: RustDesk <[email protected]> Co-authored-by: Copilot Autofix powered by AI <[email protected]>
…ustdesk#15324)" (rustdesk#15377) This reverts commit c9391fb.
The flutter-elinux engine used for ARM64 Linux builds is compiled without --enable-fontconfig, so Flutter's text shaper cannot discover system fonts. This causes CJK characters to render as tofu boxes even when fonts such as Noto Sans CJK are installed. See flutter/flutter#139293.
Fix by loading a CJK font at startup via FontLoader (bypassing fontconfig) and propagating it through two paths so all text widgets are covered:
MyTheme.applyFontFallback() — updates textTheme on both light and dark ThemeData so Material components receive the fallback through the theme.
_mergeCjkFallback() in GetMaterialApp builders — wraps child widgets in DefaultTextStyle.merge so bare Text() widgets and those with inherit:true also render CJK characters correctly.
Font discovery first runs
fc-list :lang=zh(the fontconfig CLI tool is available system-wide even when the engine has no fontconfig support), then falls back to a hardcoded search-path list covering Debian/Ubuntu, Fedora/ RHEL, Arch Linux, and WenQuanYi font layouts.This is an app-level workaround. The engine-level fix is tracked at flutter/flutter#180235 (open as of 2026-06).
Fixes #10666
Summary by CodeRabbit
Textwidgets inherit the CJK fallback by integrating it into the app’s default text styling so CJK characters render more reliably.