commit d674ede6e5f22281fa2461546ddc25ff5f3a7015 Author: Kai Uwe Broulik Date: Tue Jan 3 09:38:50 2017 +0100 [Panel Containment] Explicitly bind visible on both the container and the applet While trying to fix a random plasmashell crash I was getting fairly often (and I hoped was fixed by David's last spacer fix) I found that the cause was actually in virtual desktop pager. The virtual desktop pager is hidden when there's just one desktop and it will not update its models in this case to save resources. Back when I added this I already noticed that sometimes the pager (usually after one "open and close panelcontroller" cycle) still thought it was visible. It was even weirder than that, I found out that on teardown it suddenly thought it became visible. This had it populate its model which in turn spawned QML items, all of this whilst the panel was already in the process of destroying its children, leading to a crash. Differential Revision: https://phabricator.kde.org/D3897 diff --git a/containments/panel/contents/ui/main.qml b/containments/panel/contents/ui/main.qml index e9afa86..5bb5283 100644 --- a/containments/panel/contents/ui/main.qml +++ b/containments/panel/contents/ui/main.qml @@ -54,20 +54,27 @@ DragDrop.DropArea { //BEGIN functions function addApplet(applet, x, y) { + // don't show applet if it choses to be hidden but still make it + // accessible in the panelcontroller + // Due to the nature of how "visible" propagates in QML, we need to + // explicitly set it on the container (so the Layout ignores it) + // as well as the applet (so it reliably knows about), otherwise it can + // happen that an applet erroneously thinks it's visible, or suddenly + // starts thinking that way on teardown (virtual desktop pager) + // leading to crashes + var visibleBinding = Qt.binding(function() { + return applet.status !== PlasmaCore.Types.HiddenStatus || (!plasmoid.immutable && plasmoid.userConfiguring); + }) + var container = appletContainerComponent.createObject(root, { applet: applet, - - // don't show applet if it choses to be hidden but still make it - // accessible in the panelcontroller - visible: Qt.binding(function() { - return applet.status !== PlasmaCore.Types.HiddenStatus || (!plasmoid.immutable && plasmoid.userConfiguring) - }) + visible: visibleBinding }); applet.parent = container; applet.anchors.fill = container; - applet.visible = true; + applet.visible = visibleBinding; // Is there a DND placeholder? Replace it! if (dndSpacer.parent === currentLayout) {