mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
loadPackage + setPath can produce an invalid package if the shell package is missing. Guard with isValid() to avoid passing a bad package to setKPackage. Add the QML_SINGLETON factory that the QML engine requires for proper singleton instantiation.
112 lines
2.8 KiB
C++
112 lines
2.8 KiB
C++
// SPDX-FileCopyrightText: 2026 Marco Allegretti
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
#include "applethost.h"
|
|
|
|
#include <Plasma/Containment>
|
|
#include <Plasma/Corona>
|
|
#include <Plasma/PluginLoader>
|
|
#include <PlasmaQuick/AppletQuickItem>
|
|
|
|
#include <KPackage/Package>
|
|
#include <KPackage/PackageLoader>
|
|
|
|
#include <QDebug>
|
|
|
|
using namespace Qt::StringLiterals;
|
|
|
|
// Minimal Corona to host applets outside the shell's own containment tree.
|
|
class AppletHost::HostCorona : public Plasma::Corona
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit HostCorona(QObject *parent = nullptr)
|
|
: Plasma::Corona(parent)
|
|
{
|
|
KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(u"Plasma/Shell"_s);
|
|
pkg.setPath(u"org.kde.plasma.mobile"_s);
|
|
if (!pkg.isValid()) {
|
|
qWarning() << "AppletHost: failed to load plasma shell package org.kde.plasma.mobile";
|
|
return;
|
|
}
|
|
setKPackage(pkg);
|
|
}
|
|
|
|
QRect screenGeometry(int id) const override
|
|
{
|
|
Q_UNUSED(id);
|
|
return {0, 0, 400, 600};
|
|
}
|
|
|
|
void loadDefaultLayout() override
|
|
{
|
|
}
|
|
};
|
|
|
|
AppletHost::AppletHost(QObject *parent)
|
|
: QObject(parent)
|
|
{
|
|
}
|
|
|
|
AppletHost::~AppletHost() = default;
|
|
|
|
void AppletHost::ensureCorona()
|
|
{
|
|
if (m_corona)
|
|
return;
|
|
|
|
m_corona = new HostCorona(this);
|
|
|
|
m_containment = m_corona->createContainment(u"null"_s);
|
|
if (m_containment) {
|
|
m_containment->setFormFactor(Plasma::Types::Application);
|
|
}
|
|
}
|
|
|
|
QQuickItem *AppletHost::fullRepresentationFor(const QString &pluginId)
|
|
{
|
|
auto it = m_items.constFind(pluginId);
|
|
if (it != m_items.constEnd()) {
|
|
auto *item = *it;
|
|
return item ? item->fullRepresentationItem() : nullptr;
|
|
}
|
|
|
|
ensureCorona();
|
|
if (!m_containment) {
|
|
qWarning() << "AppletHost: failed to create containment";
|
|
return nullptr;
|
|
}
|
|
|
|
auto *applet = Plasma::PluginLoader::self()->loadApplet(pluginId, 0);
|
|
if (!applet) {
|
|
qWarning() << "AppletHost: failed to load applet" << pluginId;
|
|
m_items.insert(pluginId, nullptr);
|
|
return nullptr;
|
|
}
|
|
|
|
m_containment->addApplet(applet);
|
|
auto *item = PlasmaQuick::AppletQuickItem::itemForApplet(applet);
|
|
m_items.insert(pluginId, item);
|
|
|
|
if (!item) {
|
|
qWarning() << "AppletHost: no AppletQuickItem for" << pluginId;
|
|
return nullptr;
|
|
}
|
|
|
|
item->setPreloadFullRepresentation(true);
|
|
|
|
auto *fullRepItem = item->fullRepresentationItem();
|
|
if (!fullRepItem) {
|
|
connect(
|
|
item,
|
|
&PlasmaQuick::AppletQuickItem::fullRepresentationItemChanged,
|
|
this,
|
|
[this, pluginId]() {
|
|
Q_EMIT appletReady(pluginId);
|
|
},
|
|
static_cast<Qt::ConnectionType>(Qt::AutoConnection | Qt::SingleShotConnection));
|
|
}
|
|
return fullRepItem;
|
|
}
|
|
|
|
#include "applethost.moc"
|