Drive the bar font from fontconfig (drop shell.json round-trip)

omarchy-font-set already updates ~/.config/fontconfig/fonts.conf, which
is what fc-match, Qt, and every other XDG app reads from. Storing the
same family in shell.json gives the same value two homes that can drift
apart, and stops the bar from picking up font changes without a shell
restart.

  - omarchy-font-set stops writing bar.fontFamily to shell.json and stops
    poking ~/.config/waybar/style.css. fontconfig + terminals + hyprlock
    + swayosd are still updated as before.
  - omarchy-font-current reads fc-match monospace -f '%{family}' and
    takes the first comma-separated entry; the old jq-on-shell.json
    path is gone.
  - Bar / SettingsPanel / NDropdown.qml default fontFamily to
    "monospace" and stop reading config.fontFamily. Qt resolves the
    family through fontconfig at paint time, so omarchy-font-set updates
    the bar live with no reload.
  - shell-defaults.json drops bar.fontFamily.

User-visible effect: pick a Nerd Font, the bar follows it. Pick a font
without glyphs and you get tofu — same failure mode the terminals and
hyprlock already had.
This commit is contained in:
Ryan Hughes
2026-05-14 16:34:21 -04:00
parent 90f0475a9d
commit 85199197af
6 changed files with 18 additions and 56 deletions
+4 -26
View File
@@ -3,29 +3,7 @@
# omarchy:summary=Show current monospace font # omarchy:summary=Show current monospace font
# omarchy:examples=omarchy font current # omarchy:examples=omarchy font current
shell_config="$HOME/.config/omarchy/shell.json" # fontconfig is the source of truth. fc-match returns a comma-separated
# alias list (e.g. "JetBrainsMono Nerd Font,JetBrainsMono NF") so take
if [[ -f $shell_config ]]; then # the first entry.
font_family=$(python3 - "$shell_config" <<'PY' fc-match monospace -f '%{family}\n' | head -n1 | cut -d, -f1
import json
import sys
try:
with open(sys.argv[1]) as file:
data = json.load(file)
except (FileNotFoundError, json.JSONDecodeError):
data = {}
bar = data.get("bar") if isinstance(data, dict) else None
font = bar.get("fontFamily") if isinstance(bar, dict) else None
if font:
print(font)
PY
)
fi
if [[ -n $font_family ]]; then
printf '%s\n' "$font_family"
else
grep -oP 'font-family:\s*["'\'']?\K[^;"'\'']+' ~/.config/waybar/style.css | head -n1
fi
+3 -19
View File
@@ -27,31 +27,15 @@ if [[ -n $font_name ]]; then
fi fi
sed -i "s/font_family = .*/font_family = $font_name/g" ~/.config/hypr/hyprlock.conf sed -i "s/font_family = .*/font_family = $font_name/g" ~/.config/hypr/hyprlock.conf
sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/waybar/style.css
mkdir -p "$HOME/.config/omarchy"
shell_config="$HOME/.config/omarchy/shell.json"
tmp=$(mktemp)
if [[ -s $shell_config ]] && jq -e 'type == "object"' "$shell_config" >/dev/null 2>&1; then
jq --arg font_name "$font_name" '
.version = 1 |
.bar = ((.bar // {}) | if type == "object" then . else {} end) |
.bar.fontFamily = $font_name
' "$shell_config" >"$tmp"
else
jq -n --arg font_name "$font_name" '{ version: 1, bar: { fontFamily: $font_name } }' >"$tmp"
fi
mv "$tmp" "$shell_config"
sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/swayosd/style.css sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/swayosd/style.css
# fontconfig is the canonical source of truth — the omarchy shell, Qt
# apps, and anything else that resolves "monospace" all read from here.
xmlstarlet ed -L \ xmlstarlet ed -L \
-u '//match[@target="pattern"][test/string="monospace"]/edit[@name="family"]/string' \ -u '//match[@target="pattern"][test/string="monospace"]/edit[@name="family"]/string' \
-v "$font_name" \ -v "$font_name" \
~/.config/fontconfig/fonts.conf ~/.config/fontconfig/fonts.conf
if pgrep -x waybar >/dev/null; then
omarchy-restart-waybar
fi
omarchy-restart-swayosd omarchy-restart-swayosd
if pgrep -x ghostty; then if pgrep -x ghostty; then
@@ -21,8 +21,9 @@ Item {
// see the same widget catalogue. // see the same widget catalogue.
required property var barWidgetRegistry required property var barWidgetRegistry
// Injected by the host shell every time shell.json is reloaded. Holds the // Injected by the host shell every time shell.json is reloaded. Holds the
// `bar:` subtree: position, centerAnchor, fontFamily, layout. The host owns // `bar:` subtree: position, centerAnchor, layout. The host owns file IO;
// file IO; the bar just renders whatever it's handed. // the bar just renders whatever it's handed. The bar font follows the
// OS-level fontconfig monospace binding — it is not stored in shell.json.
required property var barConfig required property var barConfig
// Injected by the host shell so the bar can detect Noctalia-compat plugins // Injected by the host shell so the bar can detect Noctalia-compat plugins
// and look up manifests when wiring per-widget Noctalia pluginApi. // and look up manifests when wiring per-widget Noctalia pluginApi.
@@ -38,7 +39,6 @@ Item {
property string omarchyConfigDir: home + "/.config/omarchy" property string omarchyConfigDir: home + "/.config/omarchy"
property var fallbackBarConfig: ({ property var fallbackBarConfig: ({
position: "top", position: "top",
fontFamily: "JetBrainsMono Nerd Font",
centerAnchor: "calendar", centerAnchor: "calendar",
layout: { left: [], center: [], right: [] } layout: { left: [], center: [], right: [] }
}) })
@@ -46,7 +46,9 @@ Item {
property string centerAnchor: "" property string centerAnchor: ""
property int barConfigSerial: 0 property int barConfigSerial: 0
property string position: "top" property string position: "top"
property string fontFamily: "JetBrainsMono Nerd Font" // "monospace" resolves through fontconfig at paint time, so changing the
// system font (via `omarchy-font-set`) updates the bar without a reload.
property string fontFamily: "monospace"
property color foreground: "#cacccc" property color foreground: "#cacccc"
property color background: "#101315" property color background: "#101315"
property color urgent: "#a55555" property color urgent: "#a55555"
@@ -187,7 +189,6 @@ Item {
var config = isPlainObject(barConfig) ? barConfig : fallbackBarConfig var config = isPlainObject(barConfig) ? barConfig : fallbackBarConfig
position = normalizePosition(config.position) position = normalizePosition(config.position)
fontFamily = String(config.fontFamily || "JetBrainsMono Nerd Font")
centerAnchor = String(config.centerAnchor || "") centerAnchor = String(config.centerAnchor || "")
layoutConfig = normalizeLayout(config.layout) layoutConfig = normalizeLayout(config.layout)
barConfigSerial++ barConfigSerial++
@@ -63,7 +63,7 @@ Item {
property color background: "#101315" property color background: "#101315"
property color accent: "#cacccc" property color accent: "#cacccc"
property color urgent: "#a55555" property color urgent: "#a55555"
property string fontFamily: "JetBrainsMono Nerd Font" property string fontFamily: "monospace"
// Source-of-truth for the shell-wide corner radius. Mirrors what the menu // Source-of-truth for the shell-wide corner radius. Mirrors what the menu
// reads from quickshell-menu.json so `omarchy style corners <sharp|round>` // reads from quickshell-menu.json so `omarchy style corners <sharp|round>`
@@ -189,7 +189,7 @@ Item {
version: 1, version: 1,
bar: { bar: {
position: "top", position: "top",
fontFamily: "JetBrainsMono Nerd Font", fontFamily: "monospace",
centerAnchor: "calendar", centerAnchor: "calendar",
layout: { layout: {
left: [{ id: "omarchy" }, { id: "workspaces" }, { id: "activeWindow" }], left: [{ id: "omarchy" }, { id: "workspaces" }, { id: "activeWindow" }],
@@ -210,7 +210,7 @@ Item {
}) })
property var defaultConfig: builtinShellConfig property var defaultConfig: builtinShellConfig
property var draft: ({ version: 1, bar: { position: "top", centerAnchor: "calendar", fontFamily: "JetBrainsMono Nerd Font", layout: { left: [], center: [], right: [] } }, plugins: [] }) property var draft: ({ version: 1, bar: { position: "top", centerAnchor: "calendar", layout: { left: [], center: [], right: [] } }, plugins: [] })
property int draftRevision: 0 property int draftRevision: 0
property bool suppressReload: false property bool suppressReload: false
@@ -248,7 +248,7 @@ Item {
bar: { bar: {
position: String(bar.position || "top"), position: String(bar.position || "top"),
centerAnchor: String(bar.centerAnchor || ""), centerAnchor: String(bar.centerAnchor || ""),
fontFamily: String(bar.fontFamily || "JetBrainsMono Nerd Font"), fontFamily: "monospace",
layout: normalizeLayout(bar.layout || {}) layout: normalizeLayout(bar.layout || {})
}, },
plugins: plugins plugins: plugins
@@ -13,7 +13,7 @@ Item {
property color foreground: "#cacccc" property color foreground: "#cacccc"
property color background: "#101315" property color background: "#101315"
property color accent: "#cacccc" property color accent: "#cacccc"
property string fontFamily: "JetBrainsMono Nerd Font" property string fontFamily: "monospace"
property int cornerRadius: 0 property int cornerRadius: 0
property int rowHeight: 28 property int rowHeight: 28
property int popupRowHeight: 28 property int popupRowHeight: 28
@@ -2,7 +2,6 @@
"version": 1, "version": 1,
"bar": { "bar": {
"position": "top", "position": "top",
"fontFamily": "JetBrainsMono Nerd Font",
"centerAnchor": "calendar", "centerAnchor": "calendar",
"layout": { "layout": {
"left": [ "left": [