File 0001-Revert-System-for-nested-containments.patch of Package libplasma6
From aa94f60c81e51424abb8c373c09d84dc0722bb55 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Kettunen?= <bjorn.kettunen@thaodan.de>
Date: Wed, 19 Nov 2025 22:32:28 +0200
Subject: [PATCH] Revert "System for nested containments"
This reverts commit 3ad38c1677df6e466d29c51594168aebb5c47c89.
---
src/plasma/applet.cpp | 26 +++++++-------------
src/plasma/containment.cpp | 36 +++++++++++++---------------
src/plasma/private/applet_p.cpp | 30 +++++++++++++----------
src/plasma/private/containment_p.cpp | 6 +++++
src/plasmaquick/appletquickitem.cpp | 2 +-
src/plasmaquick/configview.cpp | 15 ++++++++----
6 files changed, 61 insertions(+), 54 deletions(-)
diff --git a/src/plasma/applet.cpp b/src/plasma/applet.cpp
index 2ed8c9ff6..f32c2e6d8 100644
--- a/src/plasma/applet.cpp
+++ b/src/plasma/applet.cpp
@@ -714,17 +714,7 @@ Types::FormFactor Applet::formFactor() const
return Plasma::Types::Planar;
}
- // Let's try to return the higher level formfactor in case of
- // nested containments.
- // c->containment() is guaranteed to exist except during teardown.
- // if c is a toplevel containment,
- // c == c->containment() else if is a nested one, it will be containment's
- // containment
- Containment *topC = c->containment();
- if (topC) {
- return topC->d->formFactor;
- }
- return c->d->formFactor;
+ return c ? c->d->formFactor : Plasma::Types::Planar;
}
Types::ContainmentDisplayHints Applet::containmentDisplayHints() const
@@ -737,7 +727,7 @@ Types::ContainmentDisplayHints Applet::containmentDisplayHints() const
Containment *Applet::containment() const
{
Containment *c = qobject_cast<Containment *>(const_cast<Applet *>(this));
- if (c && c->isContainment() && c->containmentType() != Containment::CustomEmbedded) {
+ if (c && c->isContainment()) {
return c;
} else {
c = nullptr;
@@ -929,12 +919,14 @@ void Applet::timerEvent(QTimerEvent *event)
bool Applet::isContainment() const
{
- // normal "acting as a containment" condition
- const Containment *cont = qobject_cast<const Containment *>(this);
- if (!cont) {
- return false;
+ // HACK: this is a special case for the systray
+ // containment in an applet that is not a containment
+ Applet *pa = qobject_cast<Applet *>(parent());
+ if (pa && !pa->isContainment()) {
+ return true;
}
- return qobject_cast<Corona *>(parent()) || cont->containmentType() == Containment::CustomEmbedded;
+ // normal "acting as a containment" condition
+ return qobject_cast<const Containment *>(this) && qobject_cast<Corona *>(parent());
}
QString Applet::translationDomain() const
diff --git a/src/plasma/containment.cpp b/src/plasma/containment.cpp
index 74d2520e0..eed9bba0a 100644
--- a/src/plasma/containment.cpp
+++ b/src/plasma/containment.cpp
@@ -121,6 +121,13 @@ void Containment::init()
setInternalAction(QStringLiteral("lock widgets"), lockDesktopAction);
}
}
+
+ // HACK: this is valid only in the systray case
+ connect(this, &Containment::configureRequested, this, [this](Plasma::Applet *a) {
+ if (Plasma::Applet *p = qobject_cast<Plasma::Applet *>(parent())) {
+ Q_EMIT p->containment()->configureRequested(a);
+ }
+ });
}
// helper function for sorting the list of applets
@@ -282,9 +289,12 @@ Plasma::Containment::Type Containment::containmentType() const
Corona *Containment::corona() const
{
- // We are not sure where the corona parent is in the hierarchy,
- // because of nested containment, those of type CustomEmbedded
- // will have containment->containment->corona
+ // We are not sure where the corona parent is in the hyerarchy, because of... the systray.
+ // We are iterating over the parent tree here rather than casting the parent
+ // to applet then asking ofr its containment and corona, as this might break during
+ // teardown, as this can be invoked during dtor of one of the ancestors,
+ // see https://bugs.kde.org/show_bug.cgi?id=477067 where it happens during destruction
+ // of the panel (containment of the applet that contains the systray containment)
for (auto candidate = parent(); candidate; candidate = candidate->parent()) {
if (auto c = qobject_cast<Corona *>(candidate)) {
return c;
@@ -368,6 +378,7 @@ void Containment::addApplet(Applet *applet, const QRectF &geometryHint)
// qCDebug(LOG_PLASMA) << "already have this applet!";
}
#endif
+
Containment *currentContainment = applet->containment();
if (currentContainment && currentContainment != this) {
@@ -405,10 +416,6 @@ void Containment::addApplet(Applet *applet, const QRectF &geometryHint)
applet->setParent(this);
}
- Containment *asCont = qobject_cast<Containment *>(applet);
- if (asCont && asCont->containmentType() == Containment::CustomEmbedded) {
- asCont->init();
- }
// make sure the applets are sorted by id
const auto position = std::lower_bound(d->applets.begin(), d->applets.end(), applet, [](Plasma::Applet *a1, Plasma::Applet *a2) {
return a1->id() < a2->id();
@@ -428,15 +435,11 @@ void Containment::addApplet(Applet *applet, const QRectF &geometryHint)
if (!currentContainment) {
const bool isNew = applet->d->mainConfigGroup()->entryMap().isEmpty();
- // If the applet is a nested containment restore even if new, to
- // have the same behavior of Corona::addContainment
- if (!isNew || applet->isContainment()) {
+ if (!isNew) {
applet->restore(*applet->d->mainConfigGroup());
}
- if (!asCont || asCont->containmentType() != Containment::CustomEmbedded) {
- applet->init();
- }
+ applet->init();
if (isNew) {
applet->save(*applet->d->mainConfigGroup());
@@ -468,9 +471,7 @@ QList<Applet *> Containment::applets() const
int Containment::screen() const
{
Q_ASSERT(corona());
- if (Containment *pc = qobject_cast<Containment *>(parent()); pc && isContainment()) {
- return pc->screen();
- } else if (Corona *c = corona()) {
+ if (Corona *c = corona()) {
return c->screenForContainment(this);
} else {
return -1;
@@ -479,9 +480,6 @@ int Containment::screen() const
int Containment::lastScreen() const
{
- if (Containment *pc = qobject_cast<Containment *>(parent()); pc) {
- return pc->lastScreen();
- }
return d->lastScreen;
}
diff --git a/src/plasma/private/applet_p.cpp b/src/plasma/private/applet_p.cpp
index 4b3c9ec97..4242b4eca 100644
--- a/src/plasma/private/applet_p.cpp
+++ b/src/plasma/private/applet_p.cpp
@@ -208,6 +208,16 @@ void AppletPrivate::setDestroyed(bool destroyed)
for (Applet *a : lstApplets) {
a->d->setDestroyed(destroyed);
}
+ } else {
+ const auto children = q->children();
+ for (QObject *child : children) {
+ // Some non-containment applets can have another applet as child to
+ // emulate nested containments, such as the systray and grouping plasmoid
+ Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(child);
+ if (applet) {
+ applet->d->setDestroyed(destroyed);
+ }
+ }
}
Q_EMIT q->configNeedsSaving();
}
@@ -423,18 +433,12 @@ void AppletPrivate::propagateConfigChanged()
void AppletPrivate::setUiReady()
{
- // If we a re a containment, call setUiReady
- Containment *thisContainment = qobject_cast<Containment *>(q);
- if (thisContainment && thisContainment->isContainment()) {
- thisContainment->d->setUiReady();
- }
-
- // If we are inside a containment, call appletLoaded on the containment
- // Note that q->containment() might be a different containment
- // also for a containment as is possible to have nested containments, such as the systemtray
- Containment *parentContainment = q->containment();
- if (parentContainment && parentContainment != thisContainment) {
- parentContainment->d->appletLoaded(q);
+ // am i the containment?
+ Containment *c = qobject_cast<Containment *>(q);
+ if (c && c->isContainment()) {
+ c->d->setUiReady();
+ } else if (Containment *cc = q->containment()) {
+ cc->d->appletLoaded(q);
}
}
@@ -486,7 +490,7 @@ KConfigGroup *AppletPrivate::mainConfigGroup()
parentApplet = qobject_cast<Plasma::Applet *>(c->parent());
}
- if (q->isContainment() && static_cast<Containment *>(q)->containmentType() != Containment::CustomEmbedded) {
+ if (q->isContainment()) {
Corona *corona = static_cast<Containment *>(q)->corona();
KConfigGroup containmentConfig;
// qCDebug(LOG_PLASMA) << "got a corona, baby?" << (QObject*)corona << (QObject*)q;
diff --git a/src/plasma/private/containment_p.cpp b/src/plasma/private/containment_p.cpp
index b9fa81e0d..82dc5b0be 100644
--- a/src/plasma/private/containment_p.cpp
+++ b/src/plasma/private/containment_p.cpp
@@ -34,6 +34,12 @@ ContainmentPrivate::ContainmentPrivate(Containment *c)
, uiReady(false)
, appletsUiReady(false)
{
+ // if the parent is an applet (i.e we are the systray)
+ // we want to follow screen changed signals from the parent's containment
+ auto appletParent = qobject_cast<Plasma::Applet *>(c->parent());
+ if (appletParent) {
+ QObject::connect(appletParent->containment(), &Containment::screenChanged, c, &Containment::screenChanged);
+ }
activityInfo = new KActivities::Info(activityId, q);
QObject::connect(activityInfo, &KActivities::Info::nameChanged, q, &Containment::activityNameChanged);
}
diff --git a/src/plasmaquick/appletquickitem.cpp b/src/plasmaquick/appletquickitem.cpp
index c9f5c9074..7ac69a221 100644
--- a/src/plasmaquick/appletquickitem.cpp
+++ b/src/plasmaquick/appletquickitem.cpp
@@ -630,7 +630,7 @@ AppletQuickItem *AppletQuickItem::itemForApplet(Plasma::Applet *applet)
qmlObject->completeInitialization();
// A normal applet has UI ready as soon as is loaded, a containment, only when also the wallpaper is loaded
- if (!pc || !pc->isContainment() || pc->containmentType() == Plasma::Containment::CustomEmbedded) {
+ if (!pc || !pc->isContainment()) {
applet->updateConstraints(Plasma::Applet::UiReadyConstraint);
applet->flushPendingConstraintsEvents();
}
diff --git a/src/plasmaquick/configview.cpp b/src/plasmaquick/configview.cpp
index 7760a796f..eb37594e3 100644
--- a/src/plasmaquick/configview.cpp
+++ b/src/plasmaquick/configview.cpp
@@ -96,11 +96,18 @@ void ConfigViewPrivate::init()
q->setColor(Qt::transparent);
updateTitle();
- if (!applet.data()->containment()->corona()->kPackage().isValid()) {
- qCWarning(LOG_PLASMAQUICK) << "Invalid home screen package";
+ // systray case
+ if (!applet.data()->containment()->corona()) {
+ Plasma::Applet *a = qobject_cast<Plasma::Applet *>(applet.data()->containment()->parent());
+ if (a) {
+ corona = a->containment()->corona();
+ }
+ } else {
+ if (!applet.data()->containment()->corona()->kPackage().isValid()) {
+ qCWarning(LOG_PLASMAQUICK) << "Invalid home screen package";
+ }
+ corona = applet.data()->containment()->corona();
}
- corona = applet.data()->containment()->corona();
-
if (!corona) {
qCWarning(LOG_PLASMAQUICK) << "Cannot find a Corona, this should never happen!";
return;
--
2.51.1