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 sectionmoveBarWidget(id, placement)– Relocates an existing widgetsetBarWidget(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.qmlmanages the runtime state of all bar widgets, providing methods to add, move, and configure widgets programmatically.config/omarchy/shell.jsondeclares the default layout through abar.layoutobject withleft,center, andrightarrays, plus widget-specific options likeformatandformatAlt.- Widget implementations live in
shell/plugins/bar/widgets/and extend theBarWidgetbase component, with theBar.qmlview handling visual rendering. - The registry determines default widget sections via
defaultBarWidgetSection()and exposes API functions includingputBarWidget(),moveBarWidget(), andsetBarWidget().
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →