Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.
50-omarchy.conf accepts Noto Color Emoji ahead of Noto Sans Symbols 2, so text-presentation glyphs (✔ U+2714, ☑ U+2611) render as color emoji
Reported by sttwister · filed Sep 14, 2026Closed upstream on 2026-09-14 by its own reporter sttwister, as not planned. Closed by its own reporter — not by itself evidence of a fix.
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 2 · What does it affect?
- Not yet mapped to any requirement or component.
- 3 · Is it reproducible?
- No validation has been run yet.
- 4 · What remains unclear?
- Not validated yet: no claims, no reproducer.
- 5 · What happens next?
- Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. No decision has been recorded yet.
Original report
What happens
/etc/fonts/conf.d/50-omarchy.conf (from omarchy-settings) accepts Noto Color Emoji into the generic families:
<alias>
<family>sans-serif</family>
<accept>
<family>JetBrainsMono Nerd Font</family>
<family>Noto Color Emoji</family>
</accept>
</alias>At priority 50 this lands ahead of the stock Noto fallback chains (66-noto-sans.conf) and therefore ahead of Noto Sans Symbols 2. As a result, every codepoint that Noto Color Emoji happens to cover is rendered as a color emoji — including the ones whose Unicode default is text presentation (Emoji_Presentation=No), which should only become emoji when followed by VS16 (U+FE0F).
The most visible casualties are the check marks and checkboxes:
| Codepoint | Char | Emoji_Presentation | Resolves to on Omarchy | Should be |
|---|---|---|---|---|
| U+2714 | ✔ | No | Noto Color Emoji | Noto Sans Symbols 2 |
| U+2611 | ☑ | No | Noto Color Emoji | Noto Sans Symbols 2 |
| U+2610 | ☐ | n/a | Noto Sans Symbols 2 | Noto Sans Symbols 2 |
Note the inconsistency in that table: U+2610 ☐ renders correctly only because Noto Color Emoji has no glyph for it. So a plain ☐ → ☑ sequence in a web page renders as a black outline box followed by a blue-and-white emoji checkbox — two glyphs from two different design languages, side by side.
This affects anything going through fontconfig, not just browsers. It is not Chromium-specific; the same pages render correctly in Chrome on Ubuntu and Windows, where the emoji font sits at the end of the fallback chain.
Steps to reproduce
for c in 2714 2611 2610; do printf 'U+%s -> ' $c; fc-match "sans-serif:charset=$c"; doneOutput on a stock Omarchy 4.0.3 install:
U+2714 -> NotoColorEmoji.ttf: "Noto Color Emoji" "Regular"
U+2611 -> NotoColorEmoji.ttf: "Noto Color Emoji" "Regular"
U+2610 -> NotoSansSymbols2-Regular.ttf: "Noto Sans Symbols 2" "Regular"Or open any page containing a bare ✔ / ☑ (no VS16) in a browser — they come out as color emoji.
Expected
✔ and ☑ without VS16 resolve to a text-presentation font (Noto Sans Symbols 2), matching Unicode's default presentation and matching what the same page renders as on other distributions. Real emoji (😀, ✅ U+2705, which is Emoji_Presentation=Yes) should keep resolving to Noto Color Emoji.
Workaround
Subtracting the two codepoints from the emoji font's charset, in ~/.config/fontconfig/conf.d/60-symbols-text-presentation.conf:
<match target="scan">
<test name="family">
<string>Noto Color Emoji</string>
</test>
<edit name="charset" mode="assign">
<minus>
<name>charset</name>
<charset>
<int>0x2714</int>
<int>0x2611</int>
</charset>
</minus>
</edit>
</match>Requires fc-cache -f -r (a scan edit is baked in at cache build time) and a full browser restart.
It has to subtract from the emoji font, not prepend a symbol font. The obvious-looking fix —
<!-- DOES NOT WORK -->
<match target="pattern">
<edit name="family" mode="prepend" binding="weak">
<string>Noto Sans Symbols 2</string>
</edit>
</match>— breaks ASCII digits. Noto Sans Symbols 2 carries U+0020, U+0023, U+002A and U+0030..U+0039 as enclosing-keycap bases (note U+20E2..U+20E3 in its charset), and those glyphs have keycap-width advances. Chromium asks fontconfig only for the family list and then reads the real font file's cmap, so a prepended family wins for every glyph it actually contains: !548 renders as ! 5 4 8. Editing that font's charset does not help either, for the same reason — the charset only prunes fontconfig's own matching, which Chromium has already bypassed by that point.
That also means fc-match is not a sufficient check here: it prunes by the edited charset and will report a clean result while Chromium still renders the wrong font. Verified instead with CSS.getPlatformFontsForNode over CDP, which reports the fonts actually used, headless on this machine:
| sample | stock | with the fix |
|---|---|---|
!548 0123456789 #* | Liberation Sans(18) | Liberation Sans(18) |
✔ ☑ ☐ ✓ ✗ | Liberation Sans(4), Noto Color Emoji(2), Adwaita Mono(3) | Liberation Sans(4), Adwaita Mono(5) |
😀 ✅ ❤️ 🎉 ⚠️ | Liberation Sans(4), Noto Color Emoji(5) | Liberation Sans(4), Noto Color Emoji(5) |
→ ← ↑ • — … | Liberation Sans(11) | Liberation Sans(11) |
| monospace digits | JetBrainsMono NF(10) | JetBrainsMono NF(10) |
| Nerd Font PUA U+E0A0 | JetBrainsMono NF(5) | JetBrainsMono NF(5) |
Exactly one row changes, and the emoji font drops out of it entirely. Real emoji, digits, arrows, and Nerd Font glyphs are untouched.
The file has to go in ~/.config/fontconfig/conf.d/ rather than fonts.conf, because omarchy font set regenerates ~/.config/fontconfig/fonts.conf from scratch and would discard it.
A fix in 50-omarchy.conf could take the same shape. U+2714 and U+2611 are the two that show up in practice; the general set is every codepoint Noto Color Emoji covers with Emoji_Presentation=No.
System
- Omarchy 4.0.3-1 (
omarchy-settings4.0.3-1) - fontconfig 2:2.18.3-2, noto-fonts 1:2026.09.01-1, noto-fonts-emoji 1:2.051-1
- Google Chrome 153.0.8010.36
- AMD RYZEN AI MAX+ 395 w/ Radeon 8060S
View raw text
## What happens
`/etc/fonts/conf.d/50-omarchy.conf` (from `omarchy-settings`) accepts `Noto Color Emoji` into the generic families:
```xml
<alias>
<family>sans-serif</family>
<accept>
<family>JetBrainsMono Nerd Font</family>
<family>Noto Color Emoji</family>
</accept>
</alias>
```
At priority 50 this lands ahead of the stock Noto fallback chains (`66-noto-sans.conf`) and therefore ahead of **Noto Sans Symbols 2**. As a result, every codepoint that Noto Color Emoji happens to cover is rendered as a color emoji — including the ones whose Unicode default is *text* presentation (`Emoji_Presentation=No`), which should only become emoji when followed by VS16 (U+FE0F).
The most visible casualties are the check marks and checkboxes:
| Codepoint | Char | Emoji_Presentation | Resolves to on Omarchy | Should be |
|---|---|---|---|---|
| U+2714 | ✔ | No | Noto Color Emoji | Noto Sans Symbols 2 |
| U+2611 | ☑ | No | Noto Color Emoji | Noto Sans Symbols 2 |
| U+2610 | ☐ | n/a | Noto Sans Symbols 2 | Noto Sans Symbols 2 |
Note the inconsistency in that table: U+2610 ☐ renders correctly only because Noto Color Emoji has no glyph for it. So a plain `☐ → ☑` sequence in a web page renders as a *black outline box* followed by a *blue-and-white emoji checkbox* — two glyphs from two different design languages, side by side.
This affects anything going through fontconfig, not just browsers. It is not Chromium-specific; the same pages render correctly in Chrome on Ubuntu and Windows, where the emoji font sits at the end of the fallback chain.
## Steps to reproduce
```bash
for c in 2714 2611 2610; do printf 'U+%s -> ' $c; fc-match "sans-serif:charset=$c"; done
```
Output on a stock Omarchy 4.0.3 install:
```
U+2714 -> NotoColorEmoji.ttf: "Noto Color Emoji" "Regular"
U+2611 -> NotoColorEmoji.ttf: "Noto Color Emoji" "Regular"
U+2610 -> NotoSansSymbols2-Regular.ttf: "Noto Sans Symbols 2" "Regular"
```
Or open any page containing a bare `✔` / `☑` (no VS16) in a browser — they come out as color emoji.
## Expected
`✔` and `☑` without VS16 resolve to a text-presentation font (Noto Sans Symbols 2), matching Unicode's default presentation and matching what the same page renders as on other distributions. Real emoji (`😀`, `✅` U+2705, which *is* `Emoji_Presentation=Yes`) should keep resolving to Noto Color Emoji.
## Workaround
Subtracting the two codepoints from the emoji font's charset, in `~/.config/fontconfig/conf.d/60-symbols-text-presentation.conf`:
```xml
<match target="scan">
<test name="family">
<string>Noto Color Emoji</string>
</test>
<edit name="charset" mode="assign">
<minus>
<name>charset</name>
<charset>
<int>0x2714</int>
<int>0x2611</int>
</charset>
</minus>
</edit>
</match>
```
Requires `fc-cache -f -r` (a scan edit is baked in at cache build time) and a full browser restart.
**It has to subtract from the emoji font, not prepend a symbol font.** The obvious-looking fix —
```xml
<!-- DOES NOT WORK -->
<match target="pattern">
<edit name="family" mode="prepend" binding="weak">
<string>Noto Sans Symbols 2</string>
</edit>
</match>
```
— breaks ASCII digits. Noto Sans Symbols 2 carries U+0020, U+0023, U+002A and U+0030..U+0039 as enclosing-keycap bases (note U+20E2..U+20E3 in its charset), and those glyphs have keycap-width advances. Chromium asks fontconfig only for the *family list* and then reads the real font file's cmap, so a prepended family wins for every glyph it actually contains: `!548` renders as `! 5 4 8`. Editing that font's charset does not help either, for the same reason — the charset only prunes fontconfig's own matching, which Chromium has already bypassed by that point.
That also means `fc-match` is not a sufficient check here: it prunes by the edited charset and will report a clean result while Chromium still renders the wrong font. Verified instead with `CSS.getPlatformFontsForNode` over CDP, which reports the fonts actually used, headless on this machine:
| sample | stock | with the fix |
|---|---|---|
| `!548 0123456789 #*` | Liberation Sans(18) | Liberation Sans(18) |
| `✔ ☑ ☐ ✓ ✗` | Liberation Sans(4), **Noto Color Emoji(2)**, Adwaita Mono(3) | Liberation Sans(4), Adwaita Mono(5) |
| `😀 ✅ ❤️ 🎉 ⚠️` | Liberation Sans(4), Noto Color Emoji(5) | Liberation Sans(4), Noto Color Emoji(5) |
| `→ ← ↑ • — …` | Liberation Sans(11) | Liberation Sans(11) |
| monospace digits | JetBrainsMono NF(10) | JetBrainsMono NF(10) |
| Nerd Font PUA U+E0A0 | JetBrainsMono NF(5) | JetBrainsMono NF(5) |
Exactly one row changes, and the emoji font drops out of it entirely. Real emoji, digits, arrows, and Nerd Font glyphs are untouched.
The file has to go in `~/.config/fontconfig/conf.d/` rather than `fonts.conf`, because `omarchy font set` regenerates `~/.config/fontconfig/fonts.conf` from scratch and would discard it.
A fix in `50-omarchy.conf` could take the same shape. U+2714 and U+2611 are the two that show up in practice; the general set is every codepoint Noto Color Emoji covers with `Emoji_Presentation=No`.
## System
- Omarchy 4.0.3-1 (`omarchy-settings` 4.0.3-1)
- fontconfig 2:2.18.3-2, noto-fonts 1:2026.09.01-1, noto-fonts-emoji 1:2.051-1
- Google Chrome 153.0.8010.36
- AMD RYZEN AI MAX+ 395 w/ Radeon 8060S
Validation
Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.
Linked
Not linked to any known issue, other report or change yet.
Decision
Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.
No decision has been recorded yet.