mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
PluginPanelSlot: improved reliability and fixes potential race condition.
This commit is contained in:
@@ -108,6 +108,9 @@ SmartPanel {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clear any stale pluginInstance before loading new content
|
||||
root.pluginInstance = null;
|
||||
|
||||
var pluginDir = PluginRegistry.getPluginDir(pluginId);
|
||||
var panelPath = pluginDir + "/" + plugin.manifest.entryPoints.panel;
|
||||
|
||||
@@ -118,25 +121,23 @@ SmartPanel {
|
||||
var component = Qt.createComponent("file://" + panelPath + "?v=" + loadVersion);
|
||||
|
||||
if (component.status === Component.Ready) {
|
||||
// Get plugin API
|
||||
var api = PluginService.getPluginAPI(pluginId);
|
||||
|
||||
// Activate loader and set component simultaneously
|
||||
root.contentLoader.active = true;
|
||||
root.contentLoader.sourceComponent = component;
|
||||
|
||||
// Immediately inject API (before any bindings evaluate)
|
||||
if (root.contentLoader.item) {
|
||||
if (root.contentLoader.item.hasOwnProperty("pluginApi")) {
|
||||
root.contentLoader.item.pluginApi = api;
|
||||
finalizePluginLoad(pluginId, component);
|
||||
return true;
|
||||
} else if (component.status === Component.Loading) {
|
||||
// Handle async component loading - wait for it to be ready
|
||||
Logger.d("PluginPanelSlot", "Component loading asynchronously for:", pluginId);
|
||||
component.statusChanged.connect(function () {
|
||||
if (component.status === Component.Ready) {
|
||||
finalizePluginLoad(pluginId, component);
|
||||
// Force SmartPanel to recalculate position now that content is ready
|
||||
if (root.isPanelVisible) {
|
||||
root.setPosition();
|
||||
}
|
||||
} else if (component.status === Component.Error) {
|
||||
PluginService.recordPluginError(pluginId, "panel", component.errorString());
|
||||
}
|
||||
|
||||
root.pluginInstance = root.contentLoader.item;
|
||||
root.currentPluginId = pluginId;
|
||||
|
||||
Logger.i("PluginPanelSlot", "Panel loaded for:", pluginId);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true; // Will be loaded asynchronously
|
||||
} else if (component.status === Component.Error) {
|
||||
PluginService.recordPluginError(pluginId, "panel", component.errorString());
|
||||
return false;
|
||||
@@ -145,6 +146,30 @@ SmartPanel {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Helper function to finalize plugin content loading
|
||||
function finalizePluginLoad(pluginId, component) {
|
||||
// Get plugin API
|
||||
var api = PluginService.getPluginAPI(pluginId);
|
||||
|
||||
// Activate loader and set component simultaneously
|
||||
root.contentLoader.active = true;
|
||||
root.contentLoader.sourceComponent = component;
|
||||
|
||||
// Immediately inject API (before any bindings evaluate)
|
||||
if (root.contentLoader.item) {
|
||||
if (root.contentLoader.item.hasOwnProperty("pluginApi")) {
|
||||
root.contentLoader.item.pluginApi = api;
|
||||
}
|
||||
|
||||
root.pluginInstance = root.contentLoader.item;
|
||||
root.currentPluginId = pluginId;
|
||||
|
||||
Logger.i("PluginPanelSlot", "Panel loaded for:", pluginId);
|
||||
} else {
|
||||
Logger.e("PluginPanelSlot", "Failed to get loader item for:", pluginId);
|
||||
}
|
||||
}
|
||||
|
||||
// Unload current plugin panel
|
||||
function unloadPluginPanel() {
|
||||
if (root.currentPluginId === "") {
|
||||
@@ -185,5 +210,8 @@ SmartPanel {
|
||||
Logger.d("PluginPanelSlot", "Cleared panelOpenScreen for", root.currentPluginId);
|
||||
}
|
||||
}
|
||||
// Clear stale references when panel closes (content is destroyed by SmartPanel)
|
||||
root.pluginInstance = null;
|
||||
root.contentLoader = null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user