Skip to content

Shell (Quickshell)

Omarchy 4 replaces Waybar with a single long-running Quickshell process, omarchy-shell. That one process hosts the top bar, the notification daemon, the on-screen display, the launcher, and the settings panel. Restarting “the shell” restarts all of them together.

These dotfiles do not fork the shell. They extend it in two supported ways: a generated shell.json that lays out the bar, and a small set of user plugins that the bar loads as extra widgets.

Two things drive the bar, and neither is hand-edited live:

  • ~/.config/omarchy/shell.json is generated, not stowed. dot renders it from Omarchy’s shipped default and inserts the personal modules. The generator is dot/src/lib/omarchyShellConfig.ts (mergeOmarchyShellConfig). The live file is mode 0600 and tracked by neither dotfiles repo.
  • Bar plugins live under omarchy/.config/omarchy/plugins/<id>/ in this repo and stow to ~/.config/omarchy/plugins/<id>/. Each plugin is a manifest.json plus an entry-point QML file.

To change the bar, edit the generator (then rebuild dot) or edit a plugin’s QML, never the live shell.json.

dot stow regenerates shell.json for the active host, starting from Omarchy’s default and adding personal modules around the stock ones (“add, not remove”). The generator owns widget sections and ordering so desktop and laptop stay aligned; rearranging widgets through Quattro is reset on the next stow. The merge is idempotent: it only rewrites the file when the rendered content changes.

Per-host differences:

  • Bar position: bottom on laptop, top on every other host.
  • Idle timers: screensaver at 2.5 minutes and lock at 5 minutes on laptop; screensaver at 30 minutes and lock at 60 minutes on every other host.
  • Home Assistant sensors: temperature, CO2, doorbell, and VOC entities differ per host (desktop vs laptop).

Layout changes applied on top of the default bar:

  • Left: Omarchy’s persistent workspaces widget is swapped for timmo.workspaces, then a calendar module is appended.
  • Centre: the clock stays as the centre anchor (the stock config gear only renders next to a centred clock), the weather is pulled out, personal status widgets are inserted before the system-update group, and the doorbell trigger goes last. Centre widgets get revealOnHover, so a class-hidden module fades in dimmed when the centre cluster is hovered.
  • Right: the Home Assistant sensors are inserted before the default tray cluster, and weather moves after the personal widgets immediately before the stock network widget.

The personal status widgets read from bar-agnostic scripts, dot JSON output, and Home Assistant. See Bar Integrations for the --bar-json commands behind the git and notification cells.

The generated config starts from Omarchy Quattro’s shipped shell.json and modifies that layout rather than replacing it wholesale.

No stock widget is removed without a replacement.

omarchy.workspaces is replaced in place by timmo.workspaces. The stock widget keeps persistent workspace slots visible; the replacement shows only workspaces that currently exist, displays the focused workspace number at full opacity, and dims the others.

omarchy.weather moves from the centre section to the right section after the personal widgets and immediately before omarchy.network. The original stock entry and implementation are preserved.

No other stock widget changes section. omarchy.system-update remains in the centre after the added status widgets, while the complete stock tray cluster remains on the right in its original order.

SectionAdded widgets
LeftCalendar
Centre, before omarchy.system-updateTime check, in-call state, NAS activity, GitHub notifications, repository diff status, GitHub workflow status, package updates, Twitch notifications
Centre, after omarchy.system-updateDoorbell
Right, before omarchy.trayHeating, CO₂ alert, rain, temperature
Right, laptop onlyVOC alert, dining-room temperature

The centre additions use revealOnHover: status cells hidden in their normal inactive state appear dimmed while the centre cluster is hovered. Attention and active states remain visible according to each widget’s class rules.

These stock widgets retain their implementations and stay in their original sections:

  • Left: omarchy.menu.
  • Centre: omarchy.indicators, omarchy.clock, omarchy.keyboard-layout, and omarchy.system-update.
  • Right: omarchy.tray, omarchy.agents, omarchy.bluetooth, omarchy.network, omarchy.audio, omarchy.monitor, and omarchy.power.

The stock clock formats, opaque bar, config version, plugin list, and omarchy.clock centre anchor are also preserved.

SettingStock QuattroDesktopLaptop
Bar positionTopTopBottom
Screensaver2.5 minutes30 minutes2.5 minutes
Lock5 minutes60 minutes5 minutes

Home Assistant entity IDs and the doorbell popup monitor and size also vary by host. The laptop adds the VOC and dining-room temperature widgets listed above; the desktop omits them.

A plugin is a folder with manifest.json (schema version 1, an id like timmo.<name>, its kinds, and entry-point QML) plus the QML itself. A bar widget extends BarWidget, reads per-instance settings from shell.json via setting(name, fallback), and uses WidgetButton for clickable cells.

PluginKindWhat it does
timmo.commandbar-widgetRuns a shell command on an interval and renders its status-bar JSON (text / tooltip / class). The Waybar custom/* equivalent.
timmo.stream-commandbar-widgetRuns a long-running command that streams status-bar JSON lines and renders the latest line (for watchers like ha-watch-singleton).
timmo.workspacesbar-widgetWorkspace numbers without persistent workspaces: only existing workspaces show, the focused one at full opacity and the rest dimmed.

timmo.command and timmo.stream-command both support classColors (class-name to colour), hideClasses, onClick / onClickRight, and revealOnHover, so the generator can style and wire every cell without bespoke QML per module.

ChangeAction
shell.json layout or settings, existing modules onlyHot-reloads on save, nothing to run
New plugin addedomarchy shell shell rescanPlugins, then the hot-reload picks it up
User plugin QML editedHot-reloads on save, nothing to run
Omarchy’s first-party shell QML edited, or hot-reload failsomarchy restart shell (full restart)

dot update bakes this in: it regenerates shell.json and reloads the running shell only when the rendered config changed. A standalone dot stow regenerates the file but does not reload.