PluginSystem: panel opening

This commit is contained in:
ItsLemmy
2025-11-30 21:04:52 -05:00
parent c31c56ff48
commit 3f830d0c73
3 changed files with 109 additions and 17 deletions
+12
View File
@@ -1,6 +1,7 @@
import QtQuick
import Quickshell
import qs.Commons
import qs.Services.Noctalia
import qs.Services.UI
Item {
@@ -58,6 +59,17 @@ Item {
});
}
// Inject plugin API for plugin widgets
if (BarWidgetRegistry.isPluginWidget(widgetId)) {
var pluginId = widgetId.replace("plugin:", "");
var api = PluginService.getPluginAPI(pluginId);
if (api && item.hasOwnProperty("pluginApi")) {
// Inject API into widget
item.pluginApi = api;
Logger.d("BarWidgetLoader", "Injected plugin API for", widgetId);
}
}
// Register this widget instance with BarService
BarService.registerWidget(widgetScreen.name, section, widgetId, sectionIndex, item);
+22 -8
View File
@@ -20,6 +20,9 @@ SmartPanel {
// Plugin instance
property var pluginInstance: null
// Reference to the plugin content loader (set when panel content is created)
property var contentLoader: null
// Panel content is dynamically loaded
panelContent: Component {
Item {
@@ -50,6 +53,9 @@ SmartPanel {
}
Component.onCompleted: {
// Store reference to the loader so loadPluginPanel can access it
root.contentLoader = pluginContentLoader;
// Load plugin panel content if assigned
if (root.currentPluginId !== "") {
root.loadPluginPanel(root.currentPluginId);
@@ -76,6 +82,12 @@ SmartPanel {
return false;
}
// Check if loader is available
if (!root.contentLoader) {
Logger.e("PluginPanelSlot", "Content loader not available yet");
return false;
}
var pluginDir = PluginRegistry.getPluginDir(pluginId);
var panelPath = pluginDir + "/" + plugin.manifest.entryPoints.panel;
@@ -89,16 +101,16 @@ SmartPanel {
var api = PluginService.getPluginAPI(pluginId);
// Create instance with API
pluginContentLoader.active = true;
pluginContentLoader.sourceComponent = component;
root.contentLoader.active = true;
root.contentLoader.sourceComponent = component;
if (pluginContentLoader.item) {
if (root.contentLoader.item) {
// Inject plugin API
if (pluginContentLoader.item.hasOwnProperty("pluginApi")) {
pluginContentLoader.item.pluginApi = api;
if (root.contentLoader.item.hasOwnProperty("pluginApi")) {
root.contentLoader.item.pluginApi = api;
}
root.pluginInstance = pluginContentLoader.item;
root.pluginInstance = root.contentLoader.item;
root.currentPluginId = pluginId;
Logger.i("PluginPanelSlot", "Panel loaded for:", pluginId);
@@ -120,8 +132,10 @@ SmartPanel {
Logger.i("PluginPanelSlot", "Unloading panel from slot", root.slotNumber);
pluginContentLoader.active = false;
pluginContentLoader.sourceComponent = null;
if (root.contentLoader) {
root.contentLoader.active = false;
root.contentLoader.sourceComponent = null;
}
root.pluginInstance = null;
root.currentPluginId = "";
}
+75 -9
View File
@@ -316,9 +316,9 @@ Singleton {
var pluginApi = createPluginAPI(pluginId, manifest);
// Load main component if provides bar widget
if (manifest.provides.barWidget && manifest.entryPoints.main) {
var mainPath = pluginDir + "/" + manifest.entryPoints.main;
var component = Qt.createComponent("file://" + mainPath);
if (manifest.provides.barWidget && manifest.entryPoints.barWidget) {
var path = pluginDir + "/" + manifest.entryPoints.barWidget;
var component = Qt.createComponent("file://" + path);
if (component.status === Component.Ready) {
// Don't instantiate yet - BarWidgetRegistry will do that
@@ -406,14 +406,26 @@ Singleton {
savePluginSettings(pluginId, api.pluginSettings);
};
api.openPanel = function (panelId) {
// TODO: Implement panel opening
Logger.d("PluginAPI", "openPanel:", panelId);
api.openPanel = function (screen) {
// Open this plugin's panel on the specified screen
if (!screen) {
Logger.w("PluginAPI", "No screen available for opening panel");
return false;
}
return openPluginPanel(pluginId, screen);
};
api.closePanel = function () {
// TODO: Implement panel closing
Logger.d("PluginAPI", "closePanel");
api.closePanel = function (screen) {
// Close this plugin's panel (find which slot it's in and close it)
for (var slotNum = 1; slotNum <= 2; slotNum++) {
var panelName = "pluginPanel" + slotNum;
var panel = PanelService.getPanel(panelName, screen);
if (panel && panel.currentPluginId === pluginId) {
panel.close();
return true;
}
}
return false;
};
api.showToast = function (message) {
@@ -546,4 +558,58 @@ Singleton {
function isPluginLoaded(pluginId) {
return !!root.loadedPlugins[pluginId];
}
// Open a plugin's panel (finds a free slot and loads the panel)
function openPluginPanel(pluginId, screen) {
if (!isPluginLoaded(pluginId)) {
Logger.w("PluginService", "Cannot open panel: plugin not loaded:", pluginId);
return false;
}
var plugin = root.loadedPlugins[pluginId];
if (!plugin || !plugin.manifest || !plugin.manifest.provides.panel) {
Logger.w("PluginService", "Plugin does not provide a panel:", pluginId);
return false;
}
// Try to find the plugin panel slot (pluginPanel1 or pluginPanel2)
// Try slot 1 first, then slot 2
for (var slotNum = 1; slotNum <= 2; slotNum++) {
var panelName = "pluginPanel" + slotNum;
var panel = PanelService.getPanel(panelName, screen);
if (panel) {
// If this slot is already showing this plugin's panel, toggle it
if (panel.currentPluginId === pluginId) {
panel.toggle();
return true;
}
// If this slot is empty, use it
if (panel.currentPluginId === "") {
// Open the panel first so the loader gets created
panel.open();
// Wait a brief moment for the panel to be fully created
Qt.callLater(function () {
panel.loadPluginPanel(pluginId);
});
return true;
}
}
}
// If both slots are occupied, use slot 1 (replace existing)
var panel1 = PanelService.getPanel("pluginPanel1", screen);
if (panel1) {
panel1.unloadPluginPanel();
panel1.open();
Qt.callLater(function () {
panel1.loadPluginPanel(pluginId);
});
return true;
}
Logger.e("PluginService", "Failed to find plugin panel slot");
return false;
}
}