Files
omarchycn/default/quickshell/bar
Ryan Hughes af5a71347b Address reviewer findings for bar settings GUI
CRITICAL:
- Re-inject working entry into the settings form every time the dialog
  opens. Previously the Loader's onLoaded only fires when the
  sourceComponent identity changes, so reopening the dialog on the same
  widget id (or on a second instance of the same id, e.g. two spacers)
  showed stale field values.
- 'Add widget' menu and the centerAnchor dropdown both read
  draft.layout[section] without depending on the section array
  identity. Mutating the array in place did not invalidate those
  bindings, so the menu would show a stale availability list and let
  non-spacer widgets be added twice. Layout mutations now replace the
  whole  object so any binding that reads it re-evaluates.

WARNINGS:
- Save now writes only the diff against the merged defaults so future
  bar-defaults changes are not silently shadowed by a stale snapshot.
- FileView onFileChanged handlers simplified to a single reload() —
  the explicit second loader call was duplicating loadConfig and
  bumping barConfigSerial twice per change (visible flicker).
- userFile onLoaded ignores reloads while the user has an unsaved
  working draft so external edits during editing do not clobber the
  in-progress state.
- SpinBox forms switched from onValueChanged to onValueModified so the
  initial-value bind no longer fires fieldChanged.
- Hyprland window-rule sizes aligned with the FloatingWindow
  implicitWidth/Height values (720 main, 380 dialog).
- omarchy-launch-bar-settings falls back to initialTitle when focusing,
  so a dialog that has not yet had its title applied still surfaces
  the existing instance.
2026-05-14 02:21:47 -04:00
..
2026-05-14 02:21:47 -04:00
2026-05-14 02:21:47 -04:00
2026-05-14 02:21:47 -04:00

Omarchy bar

This is the Quickshell implementation of the Omarchy status bar.

  • shell.qml is Omarchy-owned bar engine code. Users should not edit it directly.
  • bar-defaults.json is the Omarchy-owned default layout and module settings.
  • widgets/ holds first-party widgets — modular, interactive components shipped with Omarchy.
  • common/ holds shared QML helpers (buttons, sliders, popup cards).
  • User overrides live in ~/.config/omarchy/bar.json and are merged over defaults at runtime.
  • omarchy-style-bar-position updates only the user override file.

Customizing

The bar reads ~/.local/share/omarchy/default/quickshell/bar/bar-defaults.json, then deep-merges ~/.config/omarchy/bar.json on top of it. Each layout.{left,center,right} entry is an object: at minimum { "id": "<widget>" }, plus any inline settings the widget reads.

Launch the visual editor with omarchy launch bar-settings (or run omarchy-launch-bar-settings) to reorder widgets, add/remove them, and tweak per-widget options without editing JSON by hand.

Example bar.json:

{
  "position": "top",
  "centerAnchor": "calendar",
  "layout": {
    "left": [
      { "id": "omarchy" },
      { "id": "spacer", "size": 12 },
      { "id": "workspacesPro" }
    ],
    "center": [
      { "id": "media" },
      { "id": "calendar", "format": "HH:mm" }
    ],
    "right": [
      { "id": "systemStats" },
      { "id": "audioPanel" },
      { "id": "battery" },
      { "id": "controlCenter" },
      { "id": "powerMenu" }
    ]
  }
}

centerAnchor pins one center module to the exact horizontal/vertical center and flanks others around it. Set to an empty string to disable anchoring (the center list is centered as a group).

Module catalogue

First-party interactive widgets (in widgets/)

Name What it does Interactions
media MPRIS now-playing — scrolling track + artist, cover-art popup left = play/pause · middle = next · scroll = prev/next · right = popup
audioPanel Volume icon + popup with master slider, output-device picker, per-app mixer left = popup · right = mute · middle = audio TUI · scroll = volume
networkPanel Wi-Fi/Ethernet icon + popup with Wi-Fi scan, signal, connect left = popup · right = nmtui
bluetoothPanel Bluetooth icon + popup with device list, connect/disconnect, battery left = popup · right = toggle radio · middle = bluetoothctl TUI
calendar Clock + popup with month-grid calendar left = popup · right = tz selector
notificationCenter Bell with badge + popup with recent notifications, DND toggle left = popup · right = toggle DND
brightness Brightness slider + scroll scroll = adjust · left = popup · middle = reset to 80%
powerProfile Current power profile + popup picker left = popup
systemStats Inline CPU + memory sparklines, popup with detail left = popup · right = terminal
weatherFlyout Weather icon + popup with forecast left = popup · right = full notification
workspacesPro Animated focus indicator that slides between workspaces left = focus · right = move window · scroll = cycle
powerMenu Power icon → popup with lock/suspend/log out/reboot/shutdown left = popup
idleInhibitor Coffee-cup that toggles omarchy-toggle-idle left = toggle
microphone Mic icon + scroll volume left = mute toggle · middle = audio TUI · scroll = source volume

Built-in legacy modules (in shell.qml)

omarchy, workspaces, clock, weather, update, voxtype, screenRecording, idle, notifications, tray, bluetooth, network, audio, cpu, battery.

These remain available — set them in layout to use them instead of the richer widget versions.

Orientation

All widgets work in top, bottom, left, and right positions. Popups anchor on the side opposite the bar edge, sliding into the workspace. Vertical bars use 28px width; widgets that show text fall back to compact icon-only forms (e.g. media hides its scrolling label).

Custom user modules

The schema accepts arbitrary module ids that you provide. Set type to command for shell-driven output or qml for a custom QML widget.

Command module:

{
  "layout": {
    "right": [
      { "id": "tray" },
      { "id": "vpn", "type": "command", "exec": "~/.config/omarchy/bar/scripts/vpn-status", "interval": 5, "tooltip": "VPN", "onClick": "nm-connection-editor" },
      { "id": "audioPanel" }
    ]
  }
}

The command may print plain text or Waybar-style JSON, for example:

{"text":"󰌆","tooltip":"Work VPN","class":"active"}

QML module:

{
  "layout": {
    "right": [
      { "id": "gpu", "type": "qml" },
      { "id": "audioPanel" }
    ]
  }
}

Then create ~/.config/omarchy/bar/modules/gpu.qml. If you want to store it elsewhere, add a source path.

Custom QML modules should be an Item with implicitWidth and implicitHeight. They may optionally define these properties, which the bar fills after loading:

import QtQuick

Item {
  property var bar
  property string moduleName
  property var settings

  implicitWidth: 28
  implicitHeight: bar ? bar.barSize : 26

  Text {
    anchors.centerIn: parent
    text: "GPU"
    color: bar ? bar.foreground : "white"
    font.family: bar ? bar.fontFamily : "monospace"
    font.pixelSize: 12
  }

  MouseArea {
    anchors.fill: parent
    onClicked: if (bar) bar.run("omarchy-launch-or-focus-tui btop")
  }
}

Bar properties available to widgets

Widgets receive bar (the shell root), moduleName (string), and settings (object) injected at load time. The bar exposes:

  • bar.foreground, bar.background, bar.urgent — theme colors (live-updated)
  • bar.fontFamily — current monospace family
  • bar.position"top" | "bottom" | "left" | "right"
  • bar.vertical — boolean shortcut
  • bar.barSize — 26 horizontal / 28 vertical
  • bar.run(command) — fire-and-forget bash exec
  • bar.shellQuote(value) — safe shell-quote a string
  • bar.showTooltip(target, text) / bar.hideTooltip(target) — shared tooltip popup
  • bar.requestPopout(owner) / bar.releasePopout(owner) — one-popup-at-a-time coordinator

Drop new widgets into widgets/<name>.qml, add the name to the firstPartyWidgets registry in shell.qml, and reference it by name in any layout list.