Skip to content

Bar Plugins

Velle Sinclair edited this page Aug 26, 2026 · 4 revisions

Bar Plugins

The bar takes third-party widgets, in Omarchy's shell-plugin format.

Why that format

Omarchy's desktop is a single long-lived quickshell process in which the bar, the panels and the overlays are all plugins. SynapseOS's bar is quickshell too.

That makes their format the only one already describing "a QML widget you can drop into a quickshell bar" — so synui reads it, rather than growing an incompatible directory layout for the same idea. A widget written once can load on either desktop.


Using them

Bar Plugins in the start menu, or synui-plugins gui — browse, install and turn widgets on in a window. synui-plugins tui is the same list in the terminal with arrow keys. And the command line:

synui-plugins browse                # widgets you can install, and where from
synui-plugins browse tetris         # …narrowed; every word has to match
synui-plugins refresh               # fetch the community list now
synui-plugins add omarchy.spacer    # install one of them
synui-plugins add <git-url>         # install a plugin repository
synui-plugins list                  # what is installed, and why anything is refused
synui-plugins synapse.uptime on     # turn one on
synui-plugins remove <id>           # delete one you installed
synui-plugins order a b c           # the order they sit in on the bar
synui-plugins check                 # whether what is installed can actually draw
synui-plugins tui                   # …in the terminal
synui-plugins gui                   # …in a window
synui-plugins scan                  # the TSV the window and the bar read

add takes a catalogue id or a git URL. A catalogue id is one widget out of a repository that holds many, so it is a partial + sparse checkout of that path rather than a clone of somebody's whole desktop — and the repository's LICENSE comes with it.

remove only deletes out of ~/.config/synui/plugins. The other two search paths are Omarchy's and the package's — turn those off instead.

  synapse.uptime          off  How long this machine has been up
  needs.hypr              unsupported — needs Hyprland (synui is not Hyprland)

Everything is off until you ask for it: a plugin is third-party code running inside the bar's own process. Turning one on writes ~/.config/synui/plugins.state, which the bar watches — no reload, no logout.

Where they live

Searched in this order:

~/.config/omarchy/plugins/ Omarchy's own. omarchy plugin add <git-url> clones here, so a plugin installed that way is found without copying it
~/.config/synui/plugins/ yours
/usr/share/synui/plugins/ shipped with synui

Writing one

A plugin is a directory with a manifest.json and some QML.

{
  "schemaVersion": 1,
  "id": "example.uptime",
  "name": "Uptime",
  "version": "1.0.0",
  "kinds": ["bar-widget"],
  "entryPoints": { "barWidget": "Uptime.qml" },
  "barWidget": { "displayName": "Uptime", "category": "System",
                 "allowMultiple": false }
}

kinds is hyphenated and entryPoints is camelCase. The kind is bar-widget; its entry point is barWidget. That asymmetry is Omarchy's spelling, and getting it wrong is the likeliest reason a hand-written manifest lists but loads nothing.

Root the QML at BarWidget and you are handed the contract Omarchy documents:

import QtQuick
import qs.Ui

BarWidget {
    id: root
    implicitWidth: 40
    implicitHeight: root.barSize
    Text { anchors.centerIn: parent; text: "hi" }
}
bar the host bar
moduleName this plugin's manifest id, filled in by the host
settings per-widget overrides — empty on synui today
vertical is the bar a column (false: synui's bar is a strip)
barSize the bar's thickness in pixels
broadcast(m) run method m on every instance — one per screen
setting(n, f) one settings value, with a fallback

Set implicitWidth. The bar lays widgets out by it, and one that leaves it at 0 is loaded, running and invisible.

/usr/share/synui/plugins/synapse.uptime/ is the worked example — heavily commented, shipped off, and the thing to copy.


Running Omarchy's own widgets

Their widgets root at BarWidget, import qs.Commons for theming, and several import Quickshell.Hyprland. The first two are provided here; the third cannot be.

module what you get
qs.Ui 27 types — BarWidget and WidgetButton, BarIconButton, the whole Panel family, Button, Toggle, TextField, Dropdown, ConfirmDialog and the rest
qs.Commons Style, Color, Util, Border — the same names, over SynapseOS's own theme

Of the eight bar widgets Omarchy ships:

Spacer, Active window, Indicators, Microphone, System update run
Keyboard layout, Workspaces refused — Quickshell.Hyprland talks to a compositor socket synui does not have
Tray needs a PopupCard this desktop does not implement (and synui has its own tray)

…but their own eight are a small part of it. browse reaches around nine hundred community widgets, from the registry at omarchyplugins.com — cached under ~/.cache/synui/plugins, refreshed when it is a week old, or now with synui-plugins refresh. Two dozen of them are games (Tetris, Snake, Minesweeper, 2048, Wordle, solitaire) and they have a category of their own, since that is most of what somebody opens a widget browser hoping to find.

Everything in that registry is somebody else's claim about somebody else's desktop, so whether a widget can run here is answered at install time rather than in the listing.

Why the qs.Ui list above is 27 types and not two. It was two, and most of the nine hundred are written against a module with thirty-odd — so they went on, reported themselves enabled, and drew nothing at all. A QML property that does not resolve is not an error, it is zero: a widget sizing itself against a type that is not there comes out zero-wide. Measured across 40 of the most-installed community widgets: 9 of 40 resolved before, 39 of 40 do now.

A plugin is more than a button

Half of them put their behaviour in a panel that opens under the bar widget, or in a background service. Both are hosted, and the service is mounted once per session rather than once per monitor — otherwise a widget keeping a score would run three simulations racing over one best score on a three-monitor desk.

Turning them on and off from the bar

The bar's own right-click menu has a Plugins section: a checkbox per plugin, and arrows to move one up or down the strip. synui-plugins order is the same thing from a terminal.

synui-plugins browse                # what you can install
synui-plugins add omarchy.spacer    # one widget, straight out of their repo

qs.Commons is a shim, not a copy, and that is a design decision rather than a licence one. Omarchy is MIT, so vendoring their 23 KB Style.qml would be perfectly legal — and it carries their spacing scale, their font tokens and their palette, so a widget would come out looking like a piece of Omarchy sitting on SynapseOS. What a widget actually asks Style is "how big is body text here", which this desktop already answers. Same names, synui's answers — so an Omarchy widget picks up your font, your spacing and your ink.

What is still refused

Refusals happen before the bar sees the plugin, with the import named, and synui-plugins <id> on refuses too — a state file claiming a plugin is enabled with nothing on screen is the failure the whole check exists to prevent.

The check asks the filesystem: quickshell resolves import qs.Foo to <shell root>/Foo, so qs.Commons became hostable the moment the shim existed, with no rule to edit.

Anything that gets past it is loaded in its own Loader, so a syntax error or a type that will not resolve costs that one widget rather than the bar. The failure is logged with the plugin's id.

See also

Clone this wiki locally