Files
arthur-os/default/quickshell/omarchy-shell/plugins
Ryan Hughes a960d2b1bf Move omarchy-menu data and dispatch into the shell
omarchy-menu used to spawn an 821-line bash bin on every keybind: 11 jq
invocations against omarchy-menu.jsonc, mktemp dance, summon, poll. The
shell waited ~235ms (keybind to visible) before painting the first row.

The bar plugin host is already a persistent process with the menu plugin
loaded (keepLoaded: true) — it just wasn't allowed to own the menu data.
Now it does:

  - parseMenuJsonc / normalizeItem ports the bash bin's jq pipeline to
    JS: strip // comments + trailing commas, infer parent from dotted
    ids, dedupe keyword tokens across id/aliases/keywords, fill defaults.
  - Two FileViews with watchChanges: true on the default and user
    extension JSONCs. Edit either file and the in-memory item map
    refreshes without a restart.
  - IpcHandler exposes menu.summon(initialMenu) / refresh() / close() /
    ping(). summon resolves aliases the way the old bash route_target
    did, including the leaf-alias-is-an-action shortcut.
  - Action dispatch is now direct: when summoned via IPC (no selection
    or done file), Quickshell.execDetached(['bash','-lc', action]) runs
    the action and the menu closes. The legacy tempfile dance is kept
    only for the duration of the migration window.
  - provider sub-menus (fonts, power-profiles) are inline: tab-delimited
    bash one-liner per provider, parsed by mergeProviderRows.
  - when:/checked: bash expressions are batched into one Process at
    shell startup (and again whenever the JSONCs change). The menu
    opens instantly; visibility/check marks settle within ~50ms.

Measured: keybind-to-visible via the new IPC path is ~30ms (was ~235ms).
The bash bin still works for now and is removed in the next commit.
2026-05-14 17:39:04 -04:00
..

First-party plugins

These plugins ship with Omarchy and are loaded by the shell at startup. They use the same manifest.json contract as third-party plugins; the only difference is that the shell flags them with __isFirstParty: true so they cannot be disabled.

User-installed plugins live alongside these conceptually but on disk under ~/.config/omarchy/plugins/<plugin-id>/ rather than in this directory.

Plugin id kinds activation entry point
Bar omarchy.bar bar persistent bar/Bar.qml
Settings omarchy.settings panel on-demand settings/SettingsPanel.qml
Image picker omarchy.image-picker overlay on-demand image-picker/ImagePicker.qml
Omarchy menu omarchy.menu menu on-demand menu/Menu.qml

Bar

The status bar. Mounted at startup, lives forever. Layout lives in the top-level bar: subtree of ~/.config/omarchy/shell.json (with the shell providing shell-defaults.json when the user has no file). Owns the bar IPC target for refresh hooks fired by indicator scripts. See bar/README.md for the widget catalogue and customization schema.

Bar settings

Visual editor for the entire shell config. Summoned by omarchy-shell-ipc shell summon omarchy.settings "{}" (which is what omarchy launch settings ultimately calls). Provides:

  • per-section add/move/remove/edit of bar widget entries
  • a separate "Other plugins" section for panels, overlays, services, and menus (entries that live in plugins[] rather than the bar layout)
  • a Plugin Manager tab listing every discovered plugin with its manifest
  • a dynamic settings form driven by each widget's manifest schema, that writes inline back to the corresponding shell.json entry

Image picker

Fullscreen image-grid selector overlay. Used by omarchy-menu-images (wallpaper picker) and omarchy-theme-switcher (theme picker) and any other caller that wants to present a directory of images with previews.

Two ways to drive it:

  • Shell-level summon: omarchy-shell-ipc shell summon omarchy.image-picker '<jsonPayload>'. The payload can carry imageDirs, imageRows, selectedImage, selectionFile, doneFile, colorsFile, colorsRaw, showLabels, filterable. Best for in-shell callers that already speak JSON.
  • Direct IPC target: omarchy-shell-ipc image-selector open <imageDirs> <imageRowsB64> <selectedImage> <selectionFile> <doneFile> <colorsFile> <colorsRawB64> <showLabels> <filterable>. Positional args; imageRowsB64 and colorsRawB64 are base64-encoded so embedded newlines / tabs survive the bash argv handoff. This is what omarchy-menu-images uses.

The selection round-trip remains file-based: callers create a selection_file and done_file (both mktemp), pass the paths, and poll done_file for existence. The plugin writes the chosen path into selection_file and touches done_file when it's done. cancel IPC clears it without writing a selection.

The plugin has keepLoaded: true so the layer-shell window survives between summons within a single shell session.

Omarchy menu

Quickshell-powered replacement for the legacy Walker-driven omarchy-menu. The menu UI lives in menu/Menu.qml as a first-party menu plugin and is summoned through the shell (omarchy-shell-ipc shell summon omarchy.menu ...), so it shares the long-running omarchy-shell process instead of starting a second Quickshell instance.

The menu definition lives outside the shell host code:

  • defaults: default/omarchy/omarchy-menu.jsonc
  • user extensions: ~/.config/omarchy/extensions/omarchy-menu.jsonc

bin/omarchy-menu still owns the Bash action helpers and dynamic providers; it builds the menu JSON, summons omarchy.menu, waits for the selection, and runs the selected action.

Coming soon

  • omarchy.theme-switcher — folds theme switching into the shell.