summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/PluginService.qml
diff options
context:
space:
mode:
authorNippy <nippy@rp1.hu>2026-05-09 13:33:09 +0200
committerNippy <nippy@rp1.hu>2026-05-09 13:33:09 +0200
commita2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5 (patch)
tree1a8769217f84bfe9d6216fafaadaf8cdd876d457 /raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/PluginService.qml
parent34b9c34f982b2596cfa9e368a2d7f74e9a17477c (diff)
downloadRaveOS-PKGBUILD-a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5.tar.gz
RaveOS-PKGBUILD-a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5.zip
raveos update
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/PluginService.qml')
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/PluginService.qml876
1 files changed, 0 insertions, 876 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/PluginService.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/PluginService.qml
deleted file mode 100644
index 03f9be6..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/PluginService.qml
+++ /dev/null
@@ -1,876 +0,0 @@
-pragma Singleton
-pragma ComponentBehavior: Bound
-
-import QtCore
-import QtQuick
-import Qt.labs.folderlistmodel
-import Quickshell
-import qs.Common
-import qs.Services
-
-Singleton {
- id: root
-
- property var availablePlugins: ({})
- property var loadedPlugins: ({})
- property var pluginWidgetComponents: ({})
- property var pluginDaemonComponents: ({})
- property var pluginLauncherComponents: ({})
- property var pluginDesktopComponents: ({})
- property var availablePluginsList: []
- property string pluginDirectory: {
- var configDir = StandardPaths.writableLocation(StandardPaths.ConfigLocation);
- var configDirStr = configDir.toString();
- if (configDirStr.startsWith("file://")) {
- configDirStr = configDirStr.substring(7);
- }
- return configDirStr + "/DankMaterialShell/plugins";
- }
- property string systemPluginDirectory: "/etc/xdg/quickshell/dms-plugins"
-
- property var knownManifests: ({})
- property var pathToPluginId: ({})
- property var pluginInstances: ({})
- property var globalVars: ({})
-
- property var _stateCache: ({})
- property var _stateLoaded: ({})
- property var _stateWriters: ({})
- property var _stateDirtyPlugins: ({})
- property bool _stateDirCreated: false
-
- signal pluginLoaded(string pluginId)
- signal pluginUnloaded(string pluginId)
- signal pluginLoadFailed(string pluginId, string error)
- signal pluginDataChanged(string pluginId)
- signal pluginStateChanged(string pluginId)
- signal pluginListUpdated
- signal globalVarChanged(string pluginId, string varName)
- signal requestLauncherUpdate(string pluginId)
-
- Timer {
- id: resyncDebounce
- interval: 120
- repeat: false
- onTriggered: resyncAll()
- }
-
- Timer {
- id: _stateWriteTimer
- interval: 150
- repeat: false
- onTriggered: root._flushDirtyStates()
- }
-
- Component.onCompleted: {
- userWatcher.folder = Paths.toFileUrl(root.pluginDirectory);
- systemWatcher.folder = Paths.toFileUrl(root.systemPluginDirectory);
- Qt.callLater(resyncAll);
- }
-
- FolderListModel {
- id: userWatcher
- showDirs: true
- showFiles: false
- showDotAndDotDot: false
-
- onCountChanged: resyncDebounce.restart()
- onStatusChanged: {
- if (status === FolderListModel.Ready)
- resyncDebounce.restart();
- }
- }
-
- FolderListModel {
- id: systemWatcher
- showDirs: true
- showFiles: false
- showDotAndDotDot: false
-
- onCountChanged: resyncDebounce.restart()
- onStatusChanged: {
- if (status === FolderListModel.Ready)
- resyncDebounce.restart();
- }
- }
-
- function snapshotModel(model, sourceTag) {
- const out = [];
- const n = model.count;
- const baseDir = sourceTag === "user" ? pluginDirectory : systemPluginDirectory;
- for (let i = 0; i < n; i++) {
- let dirPath = model.get(i, "filePath");
- if (dirPath.startsWith("file://")) {
- dirPath = dirPath.substring(7);
- }
- if (!dirPath.startsWith(baseDir)) {
- continue;
- }
- const manifestPath = dirPath + "/plugin.json";
- out.push({
- path: manifestPath,
- source: sourceTag
- });
- }
- return out;
- }
-
- function resyncAll() {
- const userList = snapshotModel(userWatcher, "user");
- const sysList = snapshotModel(systemWatcher, "system");
- const seenPaths = {};
-
- function consider(entry) {
- const key = entry.path;
- seenPaths[key] = true;
- const prev = knownManifests[key];
- if (!prev) {
- loadPluginManifestFile(entry.path, entry.source, Date.now());
- }
- }
- for (let i = 0; i < userList.length; i++)
- consider(userList[i]);
- for (let i = 0; i < sysList.length; i++)
- consider(sysList[i]);
-
- const removed = [];
- for (const path in knownManifests) {
- if (!seenPaths[path])
- removed.push(path);
- }
- if (removed.length) {
- removed.forEach(function (path) {
- const pid = pathToPluginId[path];
- if (pid) {
- unregisterPluginByPath(path, pid);
- }
- delete knownManifests[path];
- delete pathToPluginId[path];
- });
- _updateAvailablePluginsList();
- pluginListUpdated();
- }
- }
-
- function loadPluginManifestFile(manifestPathNoScheme, sourceTag, mtimeEpochMs) {
- const manifestId = "m_" + Math.random().toString(36).slice(2);
- const qml = `
- import QtQuick
- import Quickshell.Io
- FileView {
- id: fv
- property string absPath: ""
- onLoaded: {
- try {
- let raw = text()
- if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1)
- const manifest = JSON.parse(raw)
- root._onManifestParsed(absPath, manifest, "${sourceTag}", ${mtimeEpochMs})
- } catch (e) {
- console.error("PluginService: bad manifest", absPath, e.message)
- knownManifests[absPath] = { mtime: ${mtimeEpochMs}, source: "${sourceTag}", bad: true }
- }
- fv.destroy()
- }
- onLoadFailed: (err) => {
- console.warn("PluginService: manifest load failed", absPath, err)
- fv.destroy()
- }
- }
- `;
-
- const loader = Qt.createQmlObject(qml, root, "mf_" + manifestId);
- loader.absPath = manifestPathNoScheme;
- loader.path = manifestPathNoScheme;
- }
-
- function _onManifestParsed(absPath, manifest, sourceTag, mtimeEpochMs) {
- if (!manifest || !manifest.id || !manifest.name || !manifest.component) {
- console.error("PluginService: invalid manifest fields:", absPath);
- knownManifests[absPath] = {
- mtime: mtimeEpochMs,
- source: sourceTag,
- bad: true
- };
- return;
- }
-
- const dir = absPath.substring(0, absPath.lastIndexOf('/'));
- let comp = manifest.component;
- if (comp.startsWith("./"))
- comp = comp.slice(2);
- let settings = manifest.settings;
- if (settings && settings.startsWith("./"))
- settings = settings.slice(2);
-
- const info = {};
- for (const k in manifest)
- info[k] = manifest[k];
-
- let perms = manifest.permissions;
- if (typeof perms === "string") {
- perms = perms.split(/\s*,\s*/);
- }
- if (!Array.isArray(perms)) {
- perms = [];
- }
- info.permissions = perms.map(p => String(p).trim());
-
- info.manifestPath = absPath;
- info.pluginDirectory = dir;
- info.componentPath = dir + "/" + comp;
- info.settingsPath = settings ? (dir + "/" + settings) : null;
- info.loaded = isPluginLoaded(manifest.id);
- info.type = manifest.type || "widget";
- info.source = sourceTag;
- info.requires_dms = manifest.requires_dms || null;
-
- const existing = availablePlugins[manifest.id];
- const shouldReplace = (!existing) || (existing && existing.source === "system" && sourceTag === "user");
-
- if (shouldReplace) {
- if (existing && existing.loaded && existing.source !== sourceTag) {
- unloadPlugin(manifest.id);
- }
- const newMap = Object.assign({}, availablePlugins);
- newMap[manifest.id] = info;
- availablePlugins = newMap;
- pathToPluginId[absPath] = manifest.id;
- knownManifests[absPath] = {
- mtime: mtimeEpochMs,
- source: sourceTag
- };
- _updateAvailablePluginsList();
- pluginListUpdated();
- const enabled = info.type === "desktop" || SettingsData.getPluginSetting(manifest.id, "enabled", false);
- if (enabled && !info.loaded)
- loadPlugin(manifest.id);
- } else {
- knownManifests[absPath] = {
- mtime: mtimeEpochMs,
- source: sourceTag,
- shadowedBy: existing.source
- };
- pathToPluginId[absPath] = manifest.id;
- }
- }
-
- function unregisterPluginByPath(absPath, pluginId) {
- const current = availablePlugins[pluginId];
- if (current && current.manifestPath === absPath) {
- if (current.loaded)
- unloadPlugin(pluginId);
- const newMap = Object.assign({}, availablePlugins);
- delete newMap[pluginId];
- availablePlugins = newMap;
- }
- }
-
- function loadPlugin(pluginId, bustCache) {
- const plugin = availablePlugins[pluginId];
- if (!plugin) {
- console.error("PluginService: Plugin not found:", pluginId);
- pluginLoadFailed(pluginId, "Plugin not found");
- return false;
- }
-
- if (plugin.loaded) {
- return true;
- }
-
- const isDaemon = plugin.type === "daemon";
- const isLauncher = plugin.type === "launcher" || (plugin.capabilities && plugin.capabilities.includes("launcher"));
- const isDesktop = plugin.type === "desktop";
-
- const prevInstance = pluginInstances[pluginId];
- if (prevInstance) {
- prevInstance.destroy();
- const newInstances = Object.assign({}, pluginInstances);
- delete newInstances[pluginId];
- pluginInstances = newInstances;
- }
-
- try {
- let url = "file://" + plugin.componentPath;
- if (bustCache)
- url += "?t=" + Date.now();
- const comp = Qt.createComponent(url, Component.PreferSynchronous);
- if (comp.status === Component.Error) {
- console.error("PluginService: component error", pluginId, comp.errorString());
- pluginLoadFailed(pluginId, comp.errorString());
- return false;
- }
-
- if (isDaemon) {
- const newDaemons = Object.assign({}, pluginDaemonComponents);
- newDaemons[pluginId] = comp;
- pluginDaemonComponents = newDaemons;
- } else if (isLauncher) {
- const instance = comp.createObject(root, {
- "pluginService": root
- });
- if (!instance) {
- console.error("PluginService: failed to instantiate plugin:", pluginId, comp.errorString());
- pluginLoadFailed(pluginId, comp.errorString());
- return false;
- }
- const newInstances = Object.assign({}, pluginInstances);
- newInstances[pluginId] = instance;
- pluginInstances = newInstances;
-
- const newLaunchers = Object.assign({}, pluginLauncherComponents);
- newLaunchers[pluginId] = comp;
- pluginLauncherComponents = newLaunchers;
- } else if (isDesktop) {
- const newDesktop = Object.assign({}, pluginDesktopComponents);
- newDesktop[pluginId] = comp;
- pluginDesktopComponents = newDesktop;
- } else {
- const newComponents = Object.assign({}, pluginWidgetComponents);
- newComponents[pluginId] = comp;
- pluginWidgetComponents = newComponents;
- }
-
- plugin.loaded = true;
- const newLoaded = Object.assign({}, loadedPlugins);
- newLoaded[pluginId] = plugin;
- loadedPlugins = newLoaded;
-
- pluginLoaded(pluginId);
- return true;
- } catch (e) {
- console.error("PluginService: Error loading plugin:", pluginId, e.message);
- pluginLoadFailed(pluginId, e.message);
- return false;
- }
- }
-
- function unloadPlugin(pluginId) {
- const plugin = loadedPlugins[pluginId];
- if (!plugin) {
- console.warn("PluginService: Plugin not loaded:", pluginId);
- return false;
- }
-
- try {
- const isDaemon = plugin.type === "daemon";
- const isLauncher = plugin.type === "launcher" || (plugin.capabilities && plugin.capabilities.includes("launcher"));
- const isDesktop = plugin.type === "desktop";
-
- const instance = pluginInstances[pluginId];
- if (instance) {
- instance.destroy();
- const newInstances = Object.assign({}, pluginInstances);
- delete newInstances[pluginId];
- pluginInstances = newInstances;
- }
-
- if (isDaemon && pluginDaemonComponents[pluginId]) {
- const newDaemons = Object.assign({}, pluginDaemonComponents);
- delete newDaemons[pluginId];
- pluginDaemonComponents = newDaemons;
- } else if (isLauncher && pluginLauncherComponents[pluginId]) {
- const newLaunchers = Object.assign({}, pluginLauncherComponents);
- delete newLaunchers[pluginId];
- pluginLauncherComponents = newLaunchers;
- } else if (isDesktop && pluginDesktopComponents[pluginId]) {
- const newDesktop = Object.assign({}, pluginDesktopComponents);
- delete newDesktop[pluginId];
- pluginDesktopComponents = newDesktop;
- } else if (pluginWidgetComponents[pluginId]) {
- const newComponents = Object.assign({}, pluginWidgetComponents);
- delete newComponents[pluginId];
- pluginWidgetComponents = newComponents;
- }
-
- plugin.loaded = false;
- const newLoaded = Object.assign({}, loadedPlugins);
- delete newLoaded[pluginId];
- loadedPlugins = newLoaded;
-
- _cleanupPluginStateWriter(pluginId);
- pluginUnloaded(pluginId);
- return true;
- } catch (error) {
- console.error("PluginService: Error unloading plugin:", pluginId, "Error:", error.message);
- return false;
- }
- }
-
- function getWidgetComponents() {
- return pluginWidgetComponents;
- }
-
- function getDaemonComponents() {
- return pluginDaemonComponents;
- }
-
- function getDesktopComponents() {
- return pluginDesktopComponents;
- }
-
- function getAvailablePlugins() {
- return availablePluginsList;
- }
-
- function _updateAvailablePluginsList() {
- const result = [];
- for (const key in availablePlugins) {
- result.push(availablePlugins[key]);
- }
- availablePluginsList = result;
- }
-
- function getPluginVariants(pluginId) {
- const plugin = availablePlugins[pluginId];
- if (!plugin) {
- return [];
- }
- const variants = SettingsData.getPluginSetting(pluginId, "variants", []);
- return variants;
- }
-
- function getAllPluginVariants() {
- const result = [];
- for (const pluginId in availablePlugins) {
- const plugin = availablePlugins[pluginId];
- if (plugin.type !== "widget") {
- continue;
- }
- const variants = getPluginVariants(pluginId);
- if (variants.length === 0) {
- result.push({
- pluginId: pluginId,
- variantId: null,
- fullId: pluginId,
- name: plugin.name,
- icon: plugin.icon || "extension",
- description: plugin.description || "Plugin widget",
- loaded: plugin.loaded
- });
- } else {
- for (let i = 0; i < variants.length; i++) {
- const variant = variants[i];
- result.push({
- pluginId: pluginId,
- variantId: variant.id,
- fullId: pluginId + ":" + variant.id,
- name: plugin.name + " - " + variant.name,
- icon: variant.icon || plugin.icon || "extension",
- description: variant.description || plugin.description || "Plugin widget variant",
- loaded: plugin.loaded
- });
- }
- }
- }
- return result;
- }
-
- function createPluginVariant(pluginId, variantName, variantConfig) {
- const variants = getPluginVariants(pluginId);
- const variantId = "variant_" + Date.now();
- const newVariant = Object.assign({}, variantConfig, {
- id: variantId,
- name: variantName
- });
- variants.push(newVariant);
- SettingsData.setPluginSetting(pluginId, "variants", variants);
- pluginDataChanged(pluginId);
- return variantId;
- }
-
- function removePluginVariant(pluginId, variantId) {
- const variants = getPluginVariants(pluginId);
- const newVariants = variants.filter(function (v) {
- return v.id !== variantId;
- });
- SettingsData.setPluginSetting(pluginId, "variants", newVariants);
-
- const fullId = pluginId + ":" + variantId;
- removeWidgetFromDankBar(fullId);
-
- pluginDataChanged(pluginId);
- }
-
- function removeWidgetFromDankBar(widgetId) {
- function filterWidget(widget) {
- const id = typeof widget === "string" ? widget : widget.id;
- return id !== widgetId;
- }
-
- const defaultBar = SettingsData.barConfigs[0] || SettingsData.getBarConfig("default");
- if (!defaultBar)
- return;
- const leftWidgets = defaultBar.leftWidgets || [];
- const centerWidgets = defaultBar.centerWidgets || [];
- const rightWidgets = defaultBar.rightWidgets || [];
-
- const newLeft = leftWidgets.filter(filterWidget);
- const newCenter = centerWidgets.filter(filterWidget);
- const newRight = rightWidgets.filter(filterWidget);
-
- if (newLeft.length !== leftWidgets.length) {
- SettingsData.setDankBarLeftWidgets(newLeft);
- }
- if (newCenter.length !== centerWidgets.length) {
- SettingsData.setDankBarCenterWidgets(newCenter);
- }
- if (newRight.length !== rightWidgets.length) {
- SettingsData.setDankBarRightWidgets(newRight);
- }
- }
-
- function updatePluginVariant(pluginId, variantId, variantConfig) {
- const variants = getPluginVariants(pluginId);
- for (let i = 0; i < variants.length; i++) {
- if (variants[i].id === variantId) {
- variants[i] = Object.assign({}, variants[i], variantConfig);
- break;
- }
- }
- SettingsData.setPluginSetting(pluginId, "variants", variants);
- pluginDataChanged(pluginId);
- }
-
- function getPluginVariantData(pluginId, variantId) {
- const variants = getPluginVariants(pluginId);
- for (let i = 0; i < variants.length; i++) {
- if (variants[i].id === variantId) {
- return variants[i];
- }
- }
- return null;
- }
-
- function getLoadedPlugins() {
- const result = [];
- for (const key in loadedPlugins) {
- result.push(loadedPlugins[key]);
- }
- return result;
- }
-
- function isPluginLoaded(pluginId) {
- return loadedPlugins[pluginId] !== undefined;
- }
-
- function enablePlugin(pluginId) {
- SettingsData.setPluginSetting(pluginId, "enabled", true);
- return loadPlugin(pluginId);
- }
-
- function disablePlugin(pluginId) {
- SettingsData.setPluginSetting(pluginId, "enabled", false);
- return unloadPlugin(pluginId);
- }
-
- function reloadPlugin(pluginId) {
- if (isPluginLoaded(pluginId))
- unloadPlugin(pluginId);
- return loadPlugin(pluginId, true);
- }
-
- function togglePlugin(pluginId) {
- let instance = pluginInstances[pluginId];
-
- // Lazy instantiate daemon plugins on first toggle
- // This respects the daemon lifecycle (not instantiated on load)
- // while supporting toggle functionality for slideout-capable daemons
- if (!instance && pluginDaemonComponents[pluginId]) {
- const comp = pluginDaemonComponents[pluginId];
- const newInstance = comp.createObject(root, {
- "pluginId": pluginId,
- "pluginService": root
- });
- if (newInstance) {
- const newInstances = Object.assign({}, pluginInstances);
- newInstances[pluginId] = newInstance;
- pluginInstances = newInstances;
- instance = newInstance;
- }
- }
-
- if (instance && typeof instance.toggle === "function") {
- instance.toggle();
- return true;
- }
- return false;
- }
-
- function savePluginData(pluginId, key, value) {
- SettingsData.setPluginSetting(pluginId, key, value);
- pluginDataChanged(pluginId);
- return true;
- }
-
- function loadPluginData(pluginId, key, defaultValue) {
- return SettingsData.getPluginSetting(pluginId, key, defaultValue);
- }
-
- function getPluginPath(pluginId) {
- const plugin = availablePlugins[pluginId];
- if (!plugin)
- return "";
- return plugin.pluginDirectory || "";
- }
-
- function saveAllPluginSettings() {
- SettingsData.savePluginSettings();
- }
-
- function getPluginStatePath(pluginId) {
- return Paths.strip(Paths.state) + "/plugins/" + pluginId + "_state.json";
- }
-
- function loadPluginState(pluginId, key, defaultValue) {
- if (!_stateLoaded[pluginId])
- _loadStateFromDisk(pluginId);
- const state = _stateCache[pluginId];
- if (!state)
- return defaultValue;
- return state[key] !== undefined ? state[key] : defaultValue;
- }
-
- function savePluginState(pluginId, key, value) {
- if (!_stateLoaded[pluginId])
- _loadStateFromDisk(pluginId);
- if (!_stateCache[pluginId])
- _stateCache[pluginId] = {};
- _stateCache[pluginId][key] = value;
- _stateDirtyPlugins[pluginId] = true;
- _stateWriteTimer.restart();
- pluginStateChanged(pluginId);
- }
-
- function clearPluginState(pluginId) {
- _stateCache[pluginId] = {};
- _stateLoaded[pluginId] = true;
- _flushStateToDisk(pluginId);
- pluginStateChanged(pluginId);
- }
-
- function removePluginStateKey(pluginId, key) {
- if (!_stateCache[pluginId])
- return;
- delete _stateCache[pluginId][key];
- _stateDirtyPlugins[pluginId] = true;
- _stateWriteTimer.restart();
- pluginStateChanged(pluginId);
- }
-
- function _ensureStateDir() {
- if (_stateDirCreated)
- return;
- _stateDirCreated = true;
- Paths.mkdir(Paths.state + "/plugins");
- }
-
- function _loadStateFromDisk(pluginId) {
- _stateLoaded[pluginId] = true;
- _ensureStateDir();
- const path = getPluginStatePath(pluginId);
- const escapedPath = path.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
- try {
- const qml = 'import QtQuick; import Quickshell.Io; FileView { path: "' + escapedPath + '"; blockLoading: true; blockWrites: true; atomicWrites: true }';
- const fv = Qt.createQmlObject(qml, root, "sf_" + pluginId);
- const raw = fv.text();
- if (raw && raw.trim()) {
- _stateCache[pluginId] = JSON.parse(raw);
- } else {
- _stateCache[pluginId] = {};
- }
- _stateWriters[pluginId] = fv;
- } catch (e) {
- _stateCache[pluginId] = {};
- }
- }
-
- function _flushStateToDisk(pluginId) {
- _ensureStateDir();
- const content = JSON.stringify(_stateCache[pluginId] || {}, null, 2);
- if (_stateWriters[pluginId]) {
- _stateWriters[pluginId].setText(content);
- return;
- }
- const path = getPluginStatePath(pluginId);
- const escapedPath = path.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
- try {
- const qml = 'import QtQuick; import Quickshell.Io; FileView { path: "' + escapedPath + '"; blockWrites: true; atomicWrites: true }';
- const fv = Qt.createQmlObject(qml, root, "sw_" + pluginId);
- _stateWriters[pluginId] = fv;
- fv.loaded.connect(function () {
- fv.setText(content);
- });
- fv.loadFailed.connect(function () {
- fv.setText(content);
- });
- } catch (e) {
- console.warn("PluginService: Failed to write state for", pluginId, e.message);
- }
- }
-
- function _flushDirtyStates() {
- const dirty = _stateDirtyPlugins;
- _stateDirtyPlugins = {};
- for (const pluginId in dirty)
- _flushStateToDisk(pluginId);
- }
-
- function _cleanupPluginStateWriter(pluginId) {
- if (!_stateWriters[pluginId])
- return;
- _stateWriters[pluginId].destroy();
- delete _stateWriters[pluginId];
- }
-
- function scanPlugins() {
- const userUrl = Paths.toFileUrl(root.pluginDirectory);
- const systemUrl = Paths.toFileUrl(root.systemPluginDirectory);
- userWatcher.folder = "";
- userWatcher.folder = userUrl;
- systemWatcher.folder = "";
- systemWatcher.folder = systemUrl;
- resyncDebounce.restart();
- }
-
- function forceRescanPlugin(pluginId) {
- const plugin = availablePlugins[pluginId];
- if (plugin && plugin.manifestPath) {
- const manifestPath = plugin.manifestPath;
- const source = plugin.source || "user";
- delete knownManifests[manifestPath];
- const newMap = Object.assign({}, availablePlugins);
- delete newMap[pluginId];
- availablePlugins = newMap;
- loadPluginManifestFile(manifestPath, source, Date.now());
- }
- }
-
- function createPluginDirectory() {
- const mkdirProcess = Qt.createComponent("data:text/plain,import Quickshell.Io; Process { }");
- if (mkdirProcess.status === Component.Ready) {
- const process = mkdirProcess.createObject(root);
- process.command = ["mkdir", "-p", pluginDirectory];
- process.exited.connect(function (exitCode) {
- if (exitCode !== 0) {
- console.error("PluginService: Failed to create plugin directory, exit code:", exitCode);
- }
- process.destroy();
- });
- process.running = true;
- return true;
- } else {
- console.error("PluginService: Failed to create mkdir process");
- return false;
- }
- }
-
- // Launcher plugin helper functions
- function getLauncherPlugins() {
- const launchers = {};
-
- // Check plugins that have launcher components
- for (const pluginId in pluginLauncherComponents) {
- const plugin = availablePlugins[pluginId];
- if (plugin && plugin.loaded) {
- launchers[pluginId] = plugin;
- }
- }
- return launchers;
- }
-
- function getLauncherPlugin(pluginId) {
- const plugin = availablePlugins[pluginId];
- if (plugin && plugin.loaded && pluginLauncherComponents[pluginId]) {
- return plugin;
- }
- return null;
- }
-
- function getPluginTrigger(pluginId) {
- const plugin = getLauncherPlugin(pluginId);
- if (plugin) {
- // Check if noTrigger is set (always active mode)
- const noTrigger = SettingsData.getPluginSetting(pluginId, "noTrigger", false);
- if (noTrigger) {
- return "";
- }
- // Otherwise load the custom trigger, defaulting to plugin manifest trigger
- const customTrigger = SettingsData.getPluginSetting(pluginId, "trigger", plugin.trigger || "!");
- return customTrigger;
- }
- return null;
- }
-
- function getAllPluginTriggers() {
- const triggers = {};
- const launchers = getLauncherPlugins();
-
- for (const pluginId in launchers) {
- const trigger = getPluginTrigger(pluginId);
- if (trigger && trigger.trim() !== "") {
- triggers[trigger] = pluginId;
- }
- }
- return triggers;
- }
-
- function getPluginsWithEmptyTrigger() {
- const plugins = [];
- const launchers = getLauncherPlugins();
-
- for (const pluginId in launchers) {
- const trigger = getPluginTrigger(pluginId);
- if (!trigger || trigger.trim() === "") {
- plugins.push(pluginId);
- }
- }
- return plugins;
- }
-
- function getPluginViewPreference(pluginId) {
- const plugin = availablePlugins[pluginId];
- if (!plugin)
- return null;
-
- return {
- mode: plugin.viewMode || null,
- enforced: plugin.viewModeEnforced === true
- };
- }
-
- function getGlobalVar(pluginId, varName, defaultValue) {
- if (globalVars[pluginId] && varName in globalVars[pluginId]) {
- return globalVars[pluginId][varName];
- }
- return defaultValue;
- }
-
- function setGlobalVar(pluginId, varName, value) {
- const newGlobals = Object.assign({}, globalVars);
- if (!newGlobals[pluginId]) {
- newGlobals[pluginId] = {};
- }
- newGlobals[pluginId] = Object.assign({}, newGlobals[pluginId]);
- newGlobals[pluginId][varName] = value;
- globalVars = newGlobals;
- globalVarChanged(pluginId, varName);
- }
-
- function checkPluginCompatibility(requiresDms) {
- if (!requiresDms)
- return true;
- return SystemUpdateService.checkVersionRequirement(requiresDms, SystemUpdateService.getParsedShellVersion());
- }
-
- function getIncompatiblePlugins() {
- const result = [];
- for (const pluginId in availablePlugins) {
- const plugin = availablePlugins[pluginId];
- if (plugin.loaded && plugin.requires_dms && !checkPluginCompatibility(plugin.requires_dms)) {
- result.push(plugin);
- }
- }
- return result;
- }
-}