Avoid a crash on Kwin decoration KCM teardown

Summary:
As described in https://bugreports.qt.io/browse/QTBUG-57714  exposing a
QWidget as a context item to QtQuick can crash. Especially as the
engine's context property gets deleted whilst deleting the parent item.

This patch reworks the code so that the models are exposed to QML
directly rather than going through a QWidget.

CCBUG: 373628

Test Plan:
Pressing back whilst in the decoration KCM used to crash every time, now it doesn't.
I still have the buttons.

Reviewers: #plasma, graesslin

Reviewed By: #plasma, graesslin

Subscribers: graesslin, cfeck, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D4533
icc-effect-5.14.5
David Edmundson 2017-02-10 10:52:48 +01:00
parent c2bc7d4d04
commit 29179f115c
3 changed files with 7 additions and 26 deletions

View File

@ -100,7 +100,10 @@ ConfigurationModule::ConfigurationModule(QWidget *parent, const QVariantList &ar
m_quickView->rootContext()->setContextProperty(QStringLiteral("decorationsModel"), m_proxyModel); m_quickView->rootContext()->setContextProperty(QStringLiteral("decorationsModel"), m_proxyModel);
updateColors(); updateColors();
m_quickView->rootContext()->setContextProperty("_borderSizesIndex", 3); // 3 is normal m_quickView->rootContext()->setContextProperty("_borderSizesIndex", 3); // 3 is normal
m_quickView->rootContext()->setContextProperty("configurationModule", this); m_quickView->rootContext()->setContextProperty("leftButtons", m_leftButtons);
m_quickView->rootContext()->setContextProperty("rightButtons", m_rightButtons);
m_quickView->rootContext()->setContextProperty("availableButtons", m_availableButtons);
m_quickView->rootContext()->setContextProperty("titleFont", QFontDatabase::systemFont(QFontDatabase::TitleFont)); m_quickView->rootContext()->setContextProperty("titleFont", QFontDatabase::systemFont(QFontDatabase::TitleFont));
m_quickView->setResizeMode(QQuickView::SizeRootObjectToView); m_quickView->setResizeMode(QQuickView::SizeRootObjectToView);
m_quickView->setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/kcm_kwindecoration/main.qml")))); m_quickView->setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/kcm_kwindecoration/main.qml"))));
@ -406,21 +409,6 @@ void ConfigurationModule::showKNS(const QString &config)
delete downloadDialog; delete downloadDialog;
} }
QAbstractItemModel *ConfigurationModule::leftButtons() const
{
return m_leftButtons;
}
QAbstractItemModel *ConfigurationModule::rightButtons() const
{
return m_rightButtons;
}
QAbstractItemModel *ConfigurationModule::availableButtons() const
{
return m_availableButtons;
}
bool ConfigurationModule::eventFilter(QObject *watched, QEvent *e) bool ConfigurationModule::eventFilter(QObject *watched, QEvent *e)
{ {
if (watched != m_ui) { if (watched != m_ui) {

View File

@ -47,17 +47,10 @@ public:
class ConfigurationModule : public KCModule class ConfigurationModule : public KCModule
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QAbstractItemModel* leftButtons READ leftButtons CONSTANT)
Q_PROPERTY(QAbstractItemModel* rightButtons READ rightButtons CONSTANT)
Q_PROPERTY(QAbstractItemModel* availableButtons READ availableButtons CONSTANT)
public: public:
explicit ConfigurationModule(QWidget *parent = nullptr, const QVariantList &args = QVariantList()); explicit ConfigurationModule(QWidget *parent = nullptr, const QVariantList &args = QVariantList());
virtual ~ConfigurationModule(); virtual ~ConfigurationModule();
QAbstractItemModel *leftButtons() const;
QAbstractItemModel *rightButtons() const;
QAbstractItemModel *availableButtons() const;
bool eventFilter(QObject *watched, QEvent *e) override; bool eventFilter(QObject *watched, QEvent *e) override;
public Q_SLOTS: public Q_SLOTS:

View File

@ -63,7 +63,7 @@ Item {
id: leftButtonsView id: leftButtonsView
anchors.left: parent.left; anchors.left: parent.left;
height: buttonPreviewRow.height height: buttonPreviewRow.height
model: configurationModule.leftButtons model: leftButtons
key: "decoButtonLeft" key: "decoButtonLeft"
} }
Item { Item {
@ -81,7 +81,7 @@ Item {
id: rightButtonsView id: rightButtonsView
anchors.right: parent.right; anchors.right: parent.right;
height: buttonPreviewRow.height height: buttonPreviewRow.height
model: configurationModule.rightButtons model: rightButtons
key: "decoButtonRight" key: "decoButtonRight"
} }
DropArea { DropArea {
@ -144,7 +144,7 @@ Item {
GridView { GridView {
id: availableGrid id: availableGrid
Layout.fillWidth: true Layout.fillWidth: true
model: configurationModule.availableButtons model: availableButtons
interactive: false interactive: false
cellWidth: iconLabel.implicitWidth cellWidth: iconLabel.implicitWidth
cellHeight: units.iconSizes.small + iCannotBelieveIDoThis.implicitHeight + 4*units.smallSpacing cellHeight: units.iconSizes.small + iCannotBelieveIDoThis.implicitHeight + 4*units.smallSpacing