Unify config into shell.json and add Noctalia plugin support

This commit is contained in:
Ryan Hughes
2026-05-14 02:21:48 -04:00
parent 5c0f5669c9
commit bcbe12b075
49 changed files with 2178 additions and 350 deletions
@@ -0,0 +1,80 @@
pragma Singleton
import QtQuick
// Noctalia compat shim. Plugin bar widgets call into BarService for
// registration bookkeeping and to ask the host where their tooltip should
// pop. We track the bar reference (set by the host at startup) and expose
// the helpers plugins actually use.
QtObject {
id: root
// Wired by omarchy-shell's Bar.qml on construction so we can reach back
// for things like position and the tooltip popup.
property var bar: null
// Plugins read this when computing their own layout-revision markers.
property int widgetsRevision: 0
// Bookkeeping for plugin widgets. Not consulted by Omarchy itself; some
// plugins call lookupWidget() to coordinate across instances.
property var registered: ({})
function registerWidget(screen, section, widgetId, index, item) {
var key = (screen && screen.name ? screen.name : "_") + ":" + section + ":" + widgetId + ":" + index
var next = {}
for (var k in registered) next[k] = registered[k]
next[key] = { screen: screen, section: section, widgetId: widgetId, index: index, item: item }
registered = next
widgetsRevision++
}
function unregisterWidget(screen, section, widgetId, index) {
var key = (screen && screen.name ? screen.name : "_") + ":" + section + ":" + widgetId + ":" + index
if (!registered[key]) return
var next = {}
for (var k in registered) if (k !== key) next[k] = registered[k]
registered = next
widgetsRevision++
}
// Plugins occasionally search for a sibling widget by id. We do a linear
// scan since the registry is small in practice.
function lookupWidget(widgetId) {
for (var k in registered) {
if (registered[k].widgetId === widgetId) return registered[k]
}
return undefined
}
// Translate the bar's edge to a tooltip direction string. Noctalia expects
// strings; the Omarchy bar drives its own tooltip popup off bar.position.
function getTooltipDirection(screenName) {
var pos = bar ? bar.position : "top"
if (pos === "top") return "down"
if (pos === "bottom") return "up"
if (pos === "left") return "right"
if (pos === "right") return "left"
return "down"
}
function getPillDirection(item) {
var pos = bar ? bar.position : "top"
return pos === "left" || pos === "right" ? "horizontal" : "vertical"
}
// Forward into the omarchy-shell host. Most Noctalia widgets call this
// from a right-click handler.
function openWidgetSettings(screen, section, sectionWidgetIndex, widgetId, widgetSettings) {
if (bar && bar.shell && typeof bar.shell.summon === "function") {
bar.shell.summon("omarchy.bar-settings",
JSON.stringify({ focusWidgetId: widgetId, section: section, index: sectionWidgetIndex }))
}
}
function openPluginSettings(screen, manifest) {
if (bar && bar.shell && typeof bar.shell.summon === "function") {
bar.shell.summon("omarchy.bar-settings",
JSON.stringify({ focusPluginId: manifest ? manifest.id : "" }))
}
}
}
@@ -0,0 +1,34 @@
pragma Singleton
import QtQuick
// Noctalia compat shim. Plugins use this for context menus and to reach
// the host's panels. We forward into the omarchy-shell host where there's
// a matching surface, and log a warning for anything we don't ship in v1.
QtObject {
id: root
property var bar: null
property var shell: null
// Plugins call this on right-click with a Menu component. The Noctalia
// implementation parents the menu to the screen's overlay; we simply
// call `open()` on whatever the plugin passes — most plugin context menus
// are plain QtQuick `Menu` items that know how to show themselves.
function showContextMenu(menu, item, screen) {
if (!menu) return
if (typeof menu.popup === "function") menu.popup()
else if (typeof menu.open === "function") menu.open()
}
function closeContextMenu(screen) {
// No-op; the Menu / PopupWindow closes itself on outside click.
}
function openLauncherWithSearch(screen, prefix) {
console.warn("PanelService.openLauncherWithSearch is not supported in the Omarchy compat layer")
}
function getPanel(name, screen) {
return null
}
}
@@ -0,0 +1,25 @@
pragma Singleton
import QtQuick
// Noctalia compat shim. Their plugins call TooltipService.show(item, text)
// on hover; we route that into the Omarchy bar's shared tooltip popup.
QtObject {
id: root
// Wired by Bar.qml on construction.
property var bar: null
function show(item, text, direction) {
if (!bar || !item) return
if (typeof bar.showTooltip === "function") {
bar.showTooltip(item, text || "")
}
}
function hide(item) {
if (!bar) return
if (typeof bar.hideTooltip === "function") {
bar.hideTooltip(item || null)
}
}
}
@@ -0,0 +1,4 @@
module qs.Services.UI
singleton BarService 1.0 BarService.qml
singleton TooltipService 1.0 TooltipService.qml
singleton PanelService 1.0 PanelService.qml