Skip to content

Third-party menu plugins receive a null appLibrary, so a cloned menu silently has no applications #12014

Description

@kurenn

This report has been rewritten. The original version claimed the menu never rendered; that was a measurement error on my part, and the correction is in a comment below. The bug below is the real one, reproduced against stock Omarchy with no third-party menu code involved.

What happens

A third-party plugin that declares "kinds": ["menu"] is handed a capability-scoped shell whose appLibrary is null, while the other capabilities on the same object are populated.

shell/plugins/menu/Menu.qml opens mergeAppRows() with:

function mergeAppRows() {
  if (!root.appLibrary) return

So a third-party or cloned menu has no applications at all — nothing in the Apps submenu, nothing in app search — and nothing is logged to say why. The stock menu is unaffected, because pluginShellFor() returns the shell itself for a first-party manifest.

This matters more than it might sound, because a menu plugin that clones omarchy.menu replaces it: omarchy.menu goes into disabledPlugins, so there is no second menu still listing the user's apps.

Minimal reproduction

No third-party menu is needed. This probe plugin is enough — drop it in ~/.config/omarchy/plugins/zz.probe.applibrary/:

manifest.json:

{
  "schemaVersion": 1,
  "id": "zz.probe.applibrary",
  "name": "AppLibrary Probe",
  "version": "1.0.0",
  "kinds": ["menu"],
  "keepLoaded": true,
  "entryPoints": { "menu": "Menu.qml" }
}

Menu.qml:

import QtQuick

Item {
  id: root
  property string omarchyPath: ""
  property var shell: null
  property var manifest: null
  property bool opened: false

  function open(payloadJson) { root.opened = true }
  function close() { root.opened = false }

  onShellChanged: {
    console.warn("PROBE shell=" + (root.shell ? "yes" : "null")
      + " pluginId=" + (root.shell ? root.shell.pluginId : "-")
      + " appLibrary=" + (root.shell && root.shell.appLibrary ? "PRESENT" : "NULL")
      + " bar=" + (root.shell && root.shell.bar ? "PRESENT" : "NULL")
      + " barConfig=" + (root.shell && root.shell.barConfig ? "PRESENT" : "NULL"))
  }
}

Then omarchy plugin enable zz.probe.applibrary and omarchy restart shell. The log shows:

WARN qml: PROBE shell=yes pluginId=zz.probe.applibrary appLibrary=NULL bar=PRESENT barConfig=PRESENT

pluginId, bar, and barConfig all arrive correctly on the same object, so the scoped API is constructed and alive. Only appLibrary is null.

Why this looks unintended

The plumbing to provide it is all present and appears to be meant to fire for exactly this case:

  • services/PluginAppLibraryApi.qml exists as a detached app-library capability, documented as being "for third-party menus"
  • pluginAppLibraryFor(cacheKey, pluginId) builds one
  • createScopedPluginShell() passes it in conditionally:
    appLibrary: shell.manifestHasKind(manifest, "menu")
      ? shell.pluginAppLibraryFor(cacheKey, key) : null,
  • pluginShellCapabilityProfile() even carries a "menu" / "no-menu" dimension so the cached facade is rebuilt when that changes

I could not work out from reading the source why the result is null for a manifest whose kinds contains menu. computePanelEntries() has already matched the same manifest on the same array to give the plugin its menu entry point, so manifestHasKind(manifest, "menu") should be true by then. No QML error is logged at creation. I'm reporting the reproduction rather than guessing at a patch.

Corroboration

The author of omarchy-menu-calculator-plugin hit this independently and shipped a workaround in 2ffacdd, rebuilding the capability inside the plugin from DesktopEntries plus the shell's own AppSearch.js, hidden-entries.sh, and launcher.hides. Their swap is conditional on the host providing nothing, so a fix here takes the capability back automatically.

Secondary ask

Whatever the cause, mergeAppRows() returning silently is what made this expensive to track down. A menu with no application library is never intentional, so a single warning naming the plugin would turn "my apps disappeared" into something searchable.

System details

Omarchy 4.0.3-1 (stable)
Kernel 7.2.3-arch1-3
CPU AMD Ryzen 7 5825U with Radeon Graphics
GPU AMD/ATI Barcelo (rev c1)
Hyprland v0.56.2
quickshell 0.3.1-1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions