mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-02 04:37:49 +02:00
115 lines
4.8 KiB
QML
115 lines
4.8 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
|
|
// Builds the `pluginApi` QtObject that Noctalia plugins expect. The host
|
|
// (omarchy-shell or the bar) calls create() once per plugin and caches the
|
|
// returned object so the same handle is reused across the plugin's bar
|
|
// widget, panel, settings form, etc.
|
|
Item {
|
|
// create(pluginId, manifest, settingsProvider, hostBridge) -> QtObject
|
|
//
|
|
// settingsProvider: function() that returns the plugin's current settings
|
|
// merged with defaults. Called fresh on every read so the plugin always
|
|
// sees the live shell.json entry, not a stale snapshot from when create()
|
|
// was first called.
|
|
// hostBridge: object with these methods (all optional):
|
|
// - persistSettings(pluginId, settings): write back to shell.json via
|
|
// the shell's updateEntryInline helper.
|
|
// - openPanel(pluginId, screen, buttonItem): summon the plugin's panel
|
|
// entry point through the shell's plugin host.
|
|
// - closePanel(pluginId, screen): hide a previously-summoned panel.
|
|
// - currentScreen(): return the screen the plugin should anchor to.
|
|
// togglePanel is provided by the factory itself and routes through the
|
|
// open/closePanel bridge methods. Main.qml service instances are wired
|
|
// separately by the shell and set on api.mainInstance once instantiated.
|
|
function create(pluginId, manifest, settingsProvider, hostBridge) {
|
|
var api = pluginApiFactory.createObject(null, {
|
|
pluginId: pluginId,
|
|
pluginDir: manifest && manifest.__sourceDir ? manifest.__sourceDir : "",
|
|
manifest: manifest || ({}),
|
|
_settingsProvider: settingsProvider || (function() { return {} }),
|
|
_hostBridge: hostBridge || ({})
|
|
})
|
|
return api
|
|
}
|
|
|
|
Component {
|
|
id: pluginApiFactory
|
|
|
|
QtObject {
|
|
id: api
|
|
|
|
property string pluginId: ""
|
|
property string pluginDir: ""
|
|
property var manifest: ({})
|
|
property var _settingsProvider
|
|
property var _hostBridge: ({})
|
|
property var mainInstance: null
|
|
|
|
// Writable because Noctalia Settings.qml components commonly stage edits
|
|
// with `pluginApi.pluginSettings = ...; pluginApi.saveSettings()`.
|
|
// The initial binding resolves shell.json + defaults; assignment during
|
|
// save intentionally replaces it with the staged value to persist.
|
|
property var pluginSettings: _settingsProvider ? _settingsProvider() : ({})
|
|
|
|
property var panelOpenScreen: null
|
|
property var panelAnchorItem: null
|
|
property var ipcHandlers: ({})
|
|
|
|
// Noctalia i18n surface — v1 returns the key as-is.
|
|
readonly property string currentLanguage: "en"
|
|
readonly property var pluginTranslations: ({})
|
|
readonly property var pluginFallbackTranslations: ({})
|
|
readonly property int translationVersion: 0
|
|
|
|
function tr(key, interp) { return String(key === undefined ? "" : key) }
|
|
function trp(key, count, interp) { return String(key === undefined ? "" : key) }
|
|
function hasTranslation(key) { return false }
|
|
|
|
function saveSettings(settings) {
|
|
if (settings !== undefined) pluginSettings = settings
|
|
if (_hostBridge && typeof _hostBridge.persistSettings === "function")
|
|
_hostBridge.persistSettings(pluginId, pluginSettings)
|
|
// Re-read after persisting so mainInstance/bar widgets see the
|
|
// canonical merged settings (defaults + saved overrides) immediately.
|
|
if (_settingsProvider) pluginSettings = _settingsProvider()
|
|
if (mainInstance && typeof mainInstance.refresh === "function") mainInstance.refresh()
|
|
}
|
|
|
|
function openPanel(screen, buttonItem) {
|
|
panelOpenScreen = screen || true
|
|
panelAnchorItem = buttonItem || null
|
|
if (_hostBridge && _hostBridge.tooltipService && typeof _hostBridge.tooltipService.hide === "function")
|
|
_hostBridge.tooltipService.hide(buttonItem)
|
|
if (_hostBridge && typeof _hostBridge.openPanel === "function")
|
|
_hostBridge.openPanel(pluginId, screen, buttonItem)
|
|
}
|
|
|
|
function closePanel(screen) {
|
|
panelOpenScreen = null
|
|
panelAnchorItem = null
|
|
if (_hostBridge && typeof _hostBridge.closePanel === "function")
|
|
_hostBridge.closePanel(pluginId, screen)
|
|
}
|
|
|
|
function togglePanel(screen, buttonItem) {
|
|
if (panelOpenScreen) closePanel(screen)
|
|
else openPanel(screen, buttonItem)
|
|
}
|
|
|
|
function withCurrentScreen(cb) {
|
|
if (typeof cb !== "function") return
|
|
var s = (_hostBridge && typeof _hostBridge.currentScreen === "function")
|
|
? _hostBridge.currentScreen() : null
|
|
cb(s)
|
|
}
|
|
|
|
function openLauncher(screen) {
|
|
console.warn("pluginApi.openLauncher is not supported in the Omarchy compat layer (plugin=" + pluginId + ")")
|
|
}
|
|
function closeLauncher(screen) { /* no-op */ }
|
|
function toggleLauncher(screen) { openLauncher(screen) }
|
|
}
|
|
}
|
|
}
|