https://bugs.kde.org/show_bug.cgi?id=443317
Bug ID: 443317 Summary: plasmashell crashes after toggle the "Show Background" on applet Product: plasmashell Version: 5.22.4 Platform: unspecified OS: Linux Status: REPORTED Severity: normal Priority: NOR Component: Multi-screen support Assignee: aleix...@kde.org Reporter: nullptrn...@basealt.ru CC: plasma-b...@kde.org Target Milestone: 1.0 SUMMARY Reproduces with any applet which have the `PlasmaCore.Types.ShadowBackground` in `backgroundHints` at least one time after launch. STEPS TO REPRODUCE 1. Add a second display 2. Add an applet which can have the `ShadowBackground` in `backgroundHints` of the root `Item` (possibly any applet with the `PlasmaCore.Types.ConfigurableBackground` background hint, e.g. digital-clock, fuzzy-clock, timer, weather, etc.) 3. Turn off the "Show Background" toggle (if it is enabled) and move the applet to another display (pay attention for glitches/garbage in place of an applet's appearance). 4. Toggle the "Show Background" again (maybe many times) and enjoy the plasmashell crash. OBSERVED RESULT The crash. EXPECTED RESULT No crash. SOFTWARE/OS VERSIONS Tested on X11 KDE Plasma Version: 5.11.4/5.22.4 Qt Version: 5.15.2 The crash occurs due to some asserts in `qtdeclarative/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp` or due to segfault (if asserts are not included into lib). Backtrace/debugging scenegraph's sources cannot say anything about a real conditions of the crash (only say that something in the scenegraph definitely broken at the moment of the crash). After the third step (in "Steps to reproduce") plasmashell prints something interesting to stderr/stdout: > QQuickItem: Cannot use same item on different windows at the same time. > ShaderEffectSource: sourceItem and ShaderEffectSource must both be children > of the same window. The first warning may be found in the qtdeclarative/src/quick/items/qquickitem.cpp: void QQuickItemPrivate::refWindow(QQuickWindow *c) { // An item needs a window if it is referenced by another item which has a window. // Typically the item is referenced by a parent, but can also be referenced by a // ShaderEffect or ShaderEffectSource. 'windowRefCount' counts how many items with // a window is referencing this item. When the reference count goes from zero to one, // or one to zero, the window of this item is updated and propagated to the children. // As long as the reference count stays above zero, the window is unchanged. // refWindow() increments the reference count. // derefWindow() decrements the reference count. Q_Q(QQuickItem); Q_ASSERT((window != nullptr) == (windowRefCount > 0)); Q_ASSERT(c); if (++windowRefCount > 1) { if (c != window) qWarning("QQuickItem: Cannot use same item on different windows at the same time."); return; // Window already set. } The possible reason of the crash becomes clear with help of this comment. While the applet is moving to another display, it removes the reference to the old `parentItem` (and its window) and starts to reference the other `parentItem`/window (so the applet's item do `unrefWindow(); refWindow(newWindow);`). It works while the applet's item is referenced only by `parentItem`, but fails in case of `ShaderEffect`/`ShaderEffectSource` which may also referencing this item (this is our case, we got item with `ShadowBackground` hint). The early return under these circumstances leads to buggy behavior: glitches instead of applet's elements and eventually the crash (somewhere in `qsgbatchrenderer.cpp`). This patch proves the assumptions: diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 67c4611d9e..f42484912b 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2696,8 +2696,14 @@ void QQuickItem::setParentItem(QQuickItem *parentItem) QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this); } } - if (parentWindow) + if (parentWindow) { + if (d->windowRefCount > 0 && d->window != parentWindow) { + qWarning() << "WORKAROUND"; + d->windowRefCount = 1; + d->derefWindow(); + } d->refWindow(parentWindow); + } } d->dirty(QQuickItemPrivate::ParentChanged); This handles the problem situation and calls derefWindow() before refWindow(). There will be no more crashes after this patch, but I doubt this solves the problem correctly. I don't know exactly what is to blame for this bug (is this the QtQuick flaw or is Plasma doing something wrong?). -- You are receiving this mail because: You are watching all bug changes.