mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-01 20:28:16 +02:00
Move first-party bar widget catalog out of Bar
This commit is contained in:
@@ -298,73 +298,7 @@ Item {
|
||||
return source ? Util.fileUrl(source) : ""
|
||||
}
|
||||
|
||||
// First-party modules are registered with the BarWidgetRegistry at startup.
|
||||
// Each entry maps a module id to its display metadata; the QML source is
|
||||
// loaded asynchronously via Qt.createComponent.
|
||||
readonly property var firstPartyWidgetMetadata: ({
|
||||
"omarchy": { displayName: "Omarchy menu", description: "Launches the Omarchy menu", category: "Compositor", allowMultiple: false },
|
||||
"workspaces": { displayName: "Workspaces", description: "Workspace number indicators", category: "Compositor", allowMultiple: false },
|
||||
"media": { displayName: "Media", description: "MPRIS now-playing with playback controls", category: "Media", allowMultiple: false },
|
||||
"audioPanel": { displayName: "Audio", description: "Volume slider, output picker, per-app mixer", category: "Audio", allowMultiple: false, sourceDir: "../panels", sourceName: "Audio" },
|
||||
"monitorPanel": { displayName: "Display", description: "Brightness slider and laptop display controls", category: "System", allowMultiple: false, sourceDir: "../panels", sourceName: "Monitor" },
|
||||
"networkPanel": { displayName: "Network", description: "Wi-Fi list and connection state", category: "Network", allowMultiple: false, sourceDir: "../panels", sourceName: "Network" },
|
||||
"powerPanel": { displayName: "Power", description: "Battery, power profile, and system stats", category: "System", allowMultiple: false, sourceDir: "../panels", sourceName: "Power" },
|
||||
"bluetoothPanel": { displayName: "Bluetooth", description: "Bluetooth device list with connect/disconnect", category: "Network", allowMultiple: false, sourceDir: "../panels", sourceName: "Bluetooth" },
|
||||
"daytime": { displayName: "Daytime", description: "Day/time label with date tooltip", category: "Time", allowMultiple: false, settingsForm: "daytimeSettings" },
|
||||
"notificationCenter": { displayName: "Notification center", description: "Recent notifications + DND", category: "Status", allowMultiple: false },
|
||||
"systemStats": { displayName: "System stats", description: "CPU icon — hover for graphs, click to open btop", category: "System", allowMultiple: false },
|
||||
"weather": { displayName: "Weather", description: "Weather pill with detail popup", category: "Info", allowMultiple: false, settingsForm: "weatherSettings" },
|
||||
"microphone": { displayName: "Microphone", description: "Mic input state and mute toggle", category: "Audio", allowMultiple: false },
|
||||
"activeWindow": { displayName: "Active window", description: "Title of the focused window", category: "Compositor", allowMultiple: false },
|
||||
"keyboardLayout": { displayName: "Keyboard layout", description: "Current xkb layout, click cycles", category: "Compositor", allowMultiple: false },
|
||||
"lockKeys": { displayName: "Lock keys", description: "Caps / Num / Scroll lock indicators", category: "System", allowMultiple: false },
|
||||
"spacer": { displayName: "Spacer", description: "Configurable blank space", category: "Layout", allowMultiple: true, settingsForm: "spacerSettings" }
|
||||
})
|
||||
|
||||
property var registeredFirstPartyComponents: ({})
|
||||
|
||||
Component.onCompleted: {
|
||||
registerFirstPartyWidgets()
|
||||
applyBarConfig()
|
||||
}
|
||||
|
||||
function registerFirstPartyWidgets() {
|
||||
var ids = Object.keys(firstPartyWidgetMetadata)
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
var id = ids[i]
|
||||
if (barWidgetRegistry.has(id)) continue
|
||||
registerOneFirstPartyWidget(id)
|
||||
}
|
||||
}
|
||||
|
||||
function registerOneFirstPartyWidget(id) {
|
||||
var meta = firstPartyWidgetMetadata[id] || {}
|
||||
var sourceDir = meta.sourceDir || "widgets"
|
||||
var sourceName = meta.sourceName || id
|
||||
var url = Qt.resolvedUrl(sourceDir + "/" + sourceName + ".qml")
|
||||
var enrichedMeta = {
|
||||
displayName: meta.displayName || id,
|
||||
description: meta.description || "",
|
||||
category: meta.category || "Misc",
|
||||
allowMultiple: meta.allowMultiple === true,
|
||||
settingsForm: meta.settingsForm || "",
|
||||
source: "first-party"
|
||||
}
|
||||
var comp = Qt.createComponent(url, Component.Asynchronous)
|
||||
function finalize() {
|
||||
if (comp.status === Component.Ready) {
|
||||
barWidgetRegistry.register(id, comp, enrichedMeta)
|
||||
var next = ({})
|
||||
for (var k in registeredFirstPartyComponents) next[k] = registeredFirstPartyComponents[k]
|
||||
next[id] = comp
|
||||
registeredFirstPartyComponents = next
|
||||
} else if (comp.status === Component.Error) {
|
||||
console.warn("first-party widget " + id + " failed to load: " + comp.errorString())
|
||||
}
|
||||
}
|
||||
if (comp.status === Component.Loading) comp.statusChanged.connect(finalize)
|
||||
else finalize()
|
||||
}
|
||||
Component.onCompleted: applyBarConfig()
|
||||
|
||||
function run(command) {
|
||||
if (!command) return
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
required property var barWidgetRegistry
|
||||
|
||||
readonly property var metadata: ({
|
||||
"omarchy": { displayName: "Omarchy menu", description: "Launches the Omarchy menu", category: "Compositor", allowMultiple: false },
|
||||
"workspaces": { displayName: "Workspaces", description: "Workspace number indicators", category: "Compositor", allowMultiple: false },
|
||||
"media": { displayName: "Media", description: "MPRIS now-playing with playback controls", category: "Media", allowMultiple: false },
|
||||
"audioPanel": { displayName: "Audio", description: "Volume slider, output picker, per-app mixer", category: "Audio", allowMultiple: false, sourceDir: "../panels", sourceName: "Audio" },
|
||||
"monitorPanel": { displayName: "Display", description: "Brightness slider and laptop display controls", category: "System", allowMultiple: false, sourceDir: "../panels", sourceName: "Monitor" },
|
||||
"networkPanel": { displayName: "Network", description: "Wi-Fi list and connection state", category: "Network", allowMultiple: false, sourceDir: "../panels", sourceName: "Network" },
|
||||
"powerPanel": { displayName: "Power", description: "Battery, power profile, and system stats", category: "System", allowMultiple: false, sourceDir: "../panels", sourceName: "Power" },
|
||||
"bluetoothPanel": { displayName: "Bluetooth", description: "Bluetooth device list with connect/disconnect", category: "Network", allowMultiple: false, sourceDir: "../panels", sourceName: "Bluetooth" },
|
||||
"daytime": { displayName: "Daytime", description: "Day/time label with date tooltip", category: "Time", allowMultiple: false, settingsForm: "daytimeSettings" },
|
||||
"notificationCenter": { displayName: "Notification center", description: "Recent notifications + DND", category: "Status", allowMultiple: false },
|
||||
"systemStats": { displayName: "System stats", description: "CPU icon — hover for graphs, click to open btop", category: "System", allowMultiple: false },
|
||||
"weather": { displayName: "Weather", description: "Weather pill with detail popup", category: "Info", allowMultiple: false, settingsForm: "weatherSettings" },
|
||||
"microphone": { displayName: "Microphone", description: "Mic input state and mute toggle", category: "Audio", allowMultiple: false },
|
||||
"activeWindow": { displayName: "Active window", description: "Title of the focused window", category: "Compositor", allowMultiple: false },
|
||||
"keyboardLayout": { displayName: "Keyboard layout", description: "Current xkb layout, click cycles", category: "Compositor", allowMultiple: false },
|
||||
"lockKeys": { displayName: "Lock keys", description: "Caps / Num / Scroll lock indicators", category: "System", allowMultiple: false },
|
||||
"spacer": { displayName: "Spacer", description: "Configurable blank space", category: "Layout", allowMultiple: true, settingsForm: "spacerSettings" }
|
||||
})
|
||||
|
||||
property var registeredComponents: ({})
|
||||
|
||||
Component.onCompleted: registerWidgets()
|
||||
|
||||
function registerWidgets() {
|
||||
var ids = Object.keys(metadata)
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
var id = ids[i]
|
||||
if (barWidgetRegistry.has(id)) continue
|
||||
registerOne(id)
|
||||
}
|
||||
}
|
||||
|
||||
function registerOne(id) {
|
||||
var meta = metadata[id] || {}
|
||||
var sourceDir = meta.sourceDir || "widgets"
|
||||
var sourceName = meta.sourceName || id
|
||||
var url = Qt.resolvedUrl(sourceDir + "/" + sourceName + ".qml")
|
||||
var enrichedMeta = {
|
||||
displayName: meta.displayName || id,
|
||||
description: meta.description || "",
|
||||
category: meta.category || "Misc",
|
||||
allowMultiple: meta.allowMultiple === true,
|
||||
settingsForm: meta.settingsForm || "",
|
||||
source: "first-party"
|
||||
}
|
||||
var comp = Qt.createComponent(url, Component.Asynchronous)
|
||||
function finalize() {
|
||||
if (comp.status === Component.Ready) {
|
||||
barWidgetRegistry.register(id, comp, enrichedMeta)
|
||||
var next = ({})
|
||||
for (var k in registeredComponents) next[k] = registeredComponents[k]
|
||||
next[id] = comp
|
||||
registeredComponents = next
|
||||
} else if (comp.status === Component.Error) {
|
||||
console.warn("first-party widget " + id + " failed to load: " + comp.errorString())
|
||||
}
|
||||
}
|
||||
if (comp.status === Component.Loading) comp.statusChanged.connect(finalize)
|
||||
else finalize()
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,9 @@ ShellRoot {
|
||||
// own empty copies.
|
||||
property PluginRegistry pluginRegistry: PluginRegistry { }
|
||||
property BarWidgetRegistry barWidgetRegistry: BarWidgetRegistry { }
|
||||
property FirstPartyWidgets firstPartyWidgets: FirstPartyWidgets {
|
||||
barWidgetRegistry: shell.barWidgetRegistry
|
||||
}
|
||||
|
||||
property string home: Quickshell.env("HOME")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user