mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
PluginSystem: panel opening
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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 = "";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user