How to Configure a Custom QML Widget for the Bar in Omarchy

To configure a custom QML widget for the bar in Omarchy, declare a plugin manifest with "kinds": ["bar-widget"], implement a QML Item that accepts the injected bar, moduleName, and settings properties, and place it using the omarchy bar put command.

Omarchy’s desktop shell renders its status bar through Quickshell, loading modular widgets dynamically at runtime. When you configure a custom QML widget for the bar in Omarchy, you create a plugin that the BarWidgetRegistry (defined in shell/shell.qml) summons into the active bar layout. This guide covers the exact manifest format, QML implementation requirements, and placement workflows derived from the Omarchy source code.

Understanding the Bar Widget Architecture

Omarchy manages bar widgets through two primary registry components that handle discovery and placement persistence.

BarWidgetRegistry (shell/shell.qml, lines 19-24) maintains a live registry of all enabled bar widgets, exposing the summonBarWidget(id) method that the active bar uses to instantiate widgets. When a widget is summoned, the runtime injects three critical properties into your QML root Item:

  • bar: Provides access to styling tokens (foreground, background, urgent) and helper methods like run(cmd)
  • moduleName: The unique identifier string from the manifest
  • settings: A JavaScript object containing user-defined configuration values

PluginRegistry (shell/services/PluginRegistry.qml, lines 455-475) handles the IPC commands that persist widget placement in ~/.config/omarchy/shell.json. This service implements putBarWidget, moveBarWidget, and setBarWidget, allowing runtime configuration without manual file editing.

Step 1: Create the Plugin Manifest

Every custom widget begins with a manifest.json file that declares the plugin type and entry point. The manifest must specify "kinds": ["bar-widget"] and map the entryPoints.barWidget key to your QML file.

Create the following structure in either a standalone git repository or inside ~/.config/omarchy/plugins/<your-id>/:

{
  "schemaVersion": 1,
  "id": "my.org.gpu-widget",
  "name": "GPU Meter",
  "version": "0.1.0",
  "author": "Your Name",
  "description": "Shows GPU usage on the bar",
  "kinds": ["bar-widget"],
  "entryPoints": { "barWidget": "Widget.qml" }
}

The id field must be globally unique (reverse-DNS notation recommended). The entryPoints.barWidget value is a relative path from the manifest directory to your QML implementation file.

Step 2: Implement the QML Widget

The QML implementation file receives the three injected properties mentioned above and must be placed at the path specified in your manifest. Here is a complete implementation that displays GPU utilization using the bar.run() helper:

Item {
  // Injected by the runtime
  property var bar
  property string moduleName
  property var settings

  // Internal state
  property int usage: 0

  Text {
    id: label
    color: bar.foreground
    text: "GPU: " + usage + "%"
    anchors.centerIn: parent
  }

  function updateUsage() {
    bar.run("nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader")
      .then(function(out) {
        usage = parseInt(out.trim())
      })
      .catch(function(err) { 
        console.warn(moduleName, "error:", err) 
      })
  }

  Timer {
    interval: settings.refreshInterval || 5000
    running: true
    repeat: true
    onTriggered: updateUsage()
  }

  Component.onCompleted: updateUsage()
}

The bar object exposes the shell’s styling palette and the run(cmd) method, which returns a Promise resolving to the command’s stdout. According to the documentation in docs/omarchy-shell.md (lines 91-100), you can access additional bar properties like bar.height and bar.scale to adapt your widget dimensions.

Step 3: Enable and Place the Widget

After creating the manifest and QML file, register the widget with Omarchy’s plugin system and add it to the bar layout.

Enable the plugin:

omarchy plugin add https://github.com/yourname/omarchy-gpu-widget.git
omarchy plugin enable my.org.gpu-widget

Place the widget in the desired bar section:


# Add to the right side of the bar

omarchy bar put my.org.gpu-widget --section right

Adjust positioning later using the move command:

omarchy bar move my.org.gpu-widget --section left --index 1

These commands update ~/.config/omarchy/shell.json immediately, and the BarWidgetRegistry reloads the layout without requiring a full session restart.

Configuring Widget Settings at Runtime

You can store configuration data via the setBarWidget IPC command and retrieve it through the injected settings property.

Set a custom value:

omarchy bar set my.org.gpu-widget refreshInterval 10000

Access the value in your QML:

property int refreshInterval: settings.refreshInterval || 5000

The settings object persists in shell.json alongside the widget’s placement metadata, managed by the PluginRegistry service.

Summary

  • Manifest declaration: Create a manifest.json with "kinds": ["bar-widget"] and an entryPoints.barWidget key pointing to your QML file.
  • Runtime properties: Your QML root item receives bar, moduleName, and settings automatically from the BarWidgetRegistry in shell/shell.qml.
  • Shell integration: Use omarchy plugin enable <id> to register the widget, then omarchy bar put <id> --section <left|center|right> to place it.
  • Dynamic configuration: Store user preferences via omarchy bar set and access them through the settings property without restarting the shell.

Frequently Asked Questions

What properties does Omarchy inject into custom QML bar widgets?

Omarchy injects three properties into every bar widget’s root QML Item: bar (providing styling tokens and the run() method), moduleName (the widget’s unique identifier), and settings (user-defined configuration values). These are provided by the BarWidgetRegistry when it summons the widget into the active bar.

Where does Omarchy store the position of custom bar widgets?

Widget placement is persisted in ~/.config/omarchy/shell.json by the PluginRegistry service (shell/services/PluginRegistry.qml, lines 455-475). You can modify this file directly or use the omarchy bar put and omarchy bar move commands to update positions programmatically.

Can I execute shell commands from within a QML bar widget?

Yes. Use the bar.run(cmd) method, which returns a JavaScript Promise that resolves with the command’s stdout string. This allows you to poll system status, read files, or interact with external utilities directly from your QML logic.

How do I update a widget's settings without restarting Omarchy?

Use the CLI command omarchy bar set <widget-id> <key> <value>. This updates the settings object in shell.json immediately. Your QML code should bind to the settings property or watch for changes using property observers to react to configuration updates in real time.

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 →