How Bar Widgets Are Implemented and Configured in Omarchy's shell.json

Omarchy's top-bar uses a manifest-driven registry system where shell/services/BarWidgetRegistry.qml manages widget state and config/omarchy/shell.json declares the default layout, allowing declarative configuration of widget placement and options.

Omarchy organizes its desktop interface through a flexible plugin architecture centered on bar widgets. The system separates concerns between a runtime registry that tracks widget state and a JSON configuration file that defines initial placement and visual properties. This design enables both static configuration through shell.json and dynamic manipulation via the registry's QML API.

The Bar Widget Registry

The BarWidgetRegistry.qml service located at shell/services/BarWidgetRegistry.qml serves as the central authority for bar widget management. This registry maintains a map of all installed bar-widget manifests and exposes methods for runtime manipulation.

The registry provides three core functions for widget manipulation:

  • putBarWidget(id, placement) – Adds a widget to the specified section
  • moveBarWidget(id, placement) – Relocates an existing widget
  • setBarWidget(id, key, value, selector) – Updates widget-specific configuration options

When a widget is first added, the registry determines its default section through defaultBarWidgetSection(manifest), which returns left, center, or right based on the widget's manifest declaration. The registry mirrors its state to the UI layer through Bar.qml, which provides summonBarWidget, hideBarWidget, and isBarWidgetOpen functions to control visibility.

Configuring Bar Widgets via shell.json

The config/omarchy/shell.json file declares the static bar configuration under the top-level bar object. This file controls both global bar properties and the specific widget layout.

Layout Structure

The layout sub-object within the bar configuration defines three ordered arrays: left, center, and right. These arrays determine widget positioning from left to right in each section:

{
  "bar": {
    "position": "top",
    "transparent": false,
    "centerAnchor": "omarchy.clock",
    "layout": {
      "left": [
        { "id": "omarchy.menu" },
        { "id": "omarchy.workspaces" }
      ],
      "center": [
        { "id": "omarchy.indicators" },
        { "id": "omarchy.clock" },
        { "id": "omarchy.keyboard-layout" }
      ],
      "right": [
        { "id": "omarchy.tray" },
        { "id": "omarchy.network" },
        { "id": "omarchy.power" }
      ]
    }
  }
}

Widget-Specific Configuration Options

Individual widgets accept optional configuration fields passed directly to their QML components. The clock widget (omarchy.clock) demonstrates the most common pattern, supporting format, formatAlt, and verticalFormat strings:

{
  "id": "omarchy.clock",
  "format": "dddd HH:mm",
  "formatAlt": "d MMMM 'W'ww yyyy",
  "verticalFormat": "HH\n—\nmm"
}

Each widget entry requires at minimum an id field matching the plugin's manifest ID.

Widget Implementation Architecture

Concrete widget implementations reside in shell/plugins/bar/widgets/ as QML files extending the base BarWidget component. Files such as Workspaces.qml, Tray.qml, and SystemUpdate.qml implement the specific UI and logic for their respective functions.

The Bar.qml component at shell/plugins/bar/Bar.qml renders the actual bar interface. It queries the registry to determine which widgets to instantiate and handles the visual arrangement according to the left, center, and right sections defined in the configuration.

Managing Widgets Programmatically

While shell.json provides the initial state, the registry API enables runtime modifications through QML JavaScript calls.

To add a new widget to the left section:

shell.pluginRegistry.putBarWidget("omarchy.new-widget", { section: "left" })

To move an existing widget to a different section:

shell.pluginRegistry.moveBarWidget("omarchy.clock", { section: "right" })

To update a widget's configuration option, such as changing the clock format:

shell.pluginRegistry.setBarWidget(
    "omarchy.clock",
    "format",
    JSON.stringify("HH:mm:ss"),
    "{}"
)

To enable or disable widgets entirely:

// Enable a third-party widget
shell.pluginRegistry.setEnabled("third-party.widget", true)

// Disable the built-in bar (reverts to built-in fallback)
shell.pluginRegistry.setEnabled("omarchy.bar", false)

Summary

  • shell/services/BarWidgetRegistry.qml manages the runtime state of all bar widgets, providing methods to add, move, and configure widgets programmatically.
  • config/omarchy/shell.json declares the default layout through a bar.layout object with left, center, and right arrays, plus widget-specific options like format and formatAlt.
  • Widget implementations live in shell/plugins/bar/widgets/ and extend the BarWidget base component, with the Bar.qml view handling visual rendering.
  • The registry determines default widget sections via defaultBarWidgetSection() and exposes API functions including putBarWidget(), moveBarWidget(), and setBarWidget().

Frequently Asked Questions

How do I add a custom widget to the left side of the bar?

Call shell.pluginRegistry.putBarWidget("your.widget.id", { section: "left" }) from QML JavaScript, or add an entry with "id": "your.widget.id" to the layout.left array in config/omarchy/shell.json. The widget must be installed in shell/plugins/bar/widgets/ and registered in the plugin manifest.

What configuration options are available for the clock widget?

According to the source configuration in shell.json, the omarchy.clock widget accepts format (primary display), formatAlt (alternative display), and verticalFormat (vertical bar layout) strings using Qt time format patterns. These values pass directly to the widget's QML implementation.

Can I disable the built-in bar entirely using the registry?

Yes. Call shell.pluginRegistry.setEnabled("omarchy.bar", false) to disable the built-in bar component. This reverts the shell to a fallback state without the top-bar interface. You can re-enable it by passing true to the same function.

Where are widget implementations stored in the source code?

Individual widget QML files reside in shell/plugins/bar/widgets/ within the repository. For example, Workspaces.qml implements omarchy.workspaces, Tray.qml implements omarchy.tray, and SystemUpdate.qml implements omarchy.system-update. Each extends the BarWidget base component defined in the shell framework.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →