Merge lp:~zsombi/ubuntu-ui-toolkit/layouts-fix1280359 into lp:ubuntu-ui-toolkit

Proposed by Zsombor Egri
Status: Merged
Approved by: Florian Boucault
Approved revision: 939
Merged at revision: 943
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/layouts-fix1280359
Merge into: lp:ubuntu-ui-toolkit
Diff against target: 345 lines (+260/-1)
8 files modified
modules/Ubuntu/Layouts/plugin/ullayouts.cpp (+16/-0)
modules/Ubuntu/Layouts/plugin/ullayouts.h (+2/-0)
modules/Ubuntu/Layouts/plugin/ullayouts_p.h (+1/-0)
tests/unit_x11/tst_layouts/DialerCrash.qml (+55/-0)
tests/unit_x11/tst_layouts/ExcludedItemDeleted.qml (+67/-0)
tests/unit_x11/tst_layouts/ItemInstanceAsProperty.qml (+63/-0)
tests/unit_x11/tst_layouts/tst_layouts.cpp (+52/-0)
tests/unit_x11/tst_layouts/tst_layouts.pro (+4/-1)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/layouts-fix1280359
Reviewer Review Type Date Requested Status
Florian Boucault (community) Approve
PS Jenkins bot continuous-integration Approve
Nekhelesh Ramananthan (community) testing Approve
Review via email: mp+206930@code.launchpad.net

Commit message

Item instances set as property values were excluded from layouting, causing segfaults when re-layouting was performed or when the component got deleted due to or during re-layouting.

Description of the change

Item instances set as property values were excluded from layouting, causing segfaults when re-layouting was performed or when the component got deleted due to or during re-layouting.

To post a comment you must log in.
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

I confirm that with this re-layouting works as expected without any crashes for the clock app.

review: Approve (testing)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Florian Boucault (fboucault) wrote :

looks great to me!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'modules/Ubuntu/Layouts/plugin/ullayouts.cpp'
2--- modules/Ubuntu/Layouts/plugin/ullayouts.cpp 2013-06-26 11:06:39 +0000
3+++ modules/Ubuntu/Layouts/plugin/ullayouts.cpp 2014-02-18 13:41:01 +0000
4@@ -200,6 +200,11 @@
5 .addChange(new PropertyChange(item, "enabled", activate));
6 }
7
8+// remove the deleted item from the excluded ones
9+void ULLayoutsPrivate::_q_removeExcludedItem(QObject *excludedItem)
10+{
11+ excludedFromLayout.removeAll(static_cast<QQuickItem*>(excludedItem));
12+}
13
14 /*
15 * Validates the declared conditional layouts by checking whether they have name
16@@ -256,6 +261,12 @@
17 // check if the item's parent is included in the layout
18 QQuickItem *pl = item->parentItem();
19 marker = 0;
20+ if (!pl && item->parent()) {
21+ // this may be an item instance assigned to a property
22+ // like "property var anItem: Item {}"
23+ // in which case we must get the parent object of it, not the parent item
24+ pl = qobject_cast<QQuickItem*>(item->parent());
25+ }
26 while (pl) {
27 marker = qobject_cast<ULLayoutsAttached*>(
28 qmlAttachedPropertiesObject<ULLayouts>(pl, false));
29@@ -267,6 +278,9 @@
30 if (!marker || (marker && marker->item().isEmpty())) {
31 // remember theese so we hide them once we switch away from default layout
32 excludedFromLayout << item;
33+ // and make sure we remove the item from excluded ones in case the item is destroyed
34+ QObject::connect(item, SIGNAL(destroyed(QObject*)),
35+ q, SLOT(_q_removeExcludedItem(QObject*)));
36 }
37 }
38 }
39@@ -632,3 +646,5 @@
40 &ULLayoutsPrivate::at_layout,
41 &ULLayoutsPrivate::clear_layouts);
42 }
43+
44+#include "moc_ullayouts.cpp"
45
46=== modified file 'modules/Ubuntu/Layouts/plugin/ullayouts.h'
47--- modules/Ubuntu/Layouts/plugin/ullayouts.h 2013-06-24 13:33:31 +0000
48+++ modules/Ubuntu/Layouts/plugin/ullayouts.h 2014-02-18 13:41:01 +0000
49@@ -77,6 +77,8 @@
50 friend class ULConditionalLayout;
51 Q_DECLARE_PRIVATE(ULLayouts)
52 QScopedPointer<ULLayoutsPrivate> d_ptr;
53+
54+ Q_PRIVATE_SLOT(d_func(), void _q_removeExcludedItem(QObject*))
55 };
56
57 QML_DECLARE_TYPE(ULLayouts)
58
59=== modified file 'modules/Ubuntu/Layouts/plugin/ullayouts_p.h'
60--- modules/Ubuntu/Layouts/plugin/ullayouts_p.h 2013-06-25 13:42:22 +0000
61+++ modules/Ubuntu/Layouts/plugin/ullayouts_p.h 2014-02-18 13:41:01 +0000
62@@ -33,6 +33,7 @@
63
64 ULLayoutsPrivate(ULLayouts *qq);
65
66+ void _q_removeExcludedItem(QObject *excludedItem);
67 void validateConditionalLayouts();
68 void getLaidOutItems();
69 void updateLayout();
70
71=== added file 'tests/unit_x11/tst_layouts/DialerCrash.qml'
72--- tests/unit_x11/tst_layouts/DialerCrash.qml 1970-01-01 00:00:00 +0000
73+++ tests/unit_x11/tst_layouts/DialerCrash.qml 2014-02-18 13:41:01 +0000
74@@ -0,0 +1,55 @@
75+/*
76+ * Copyright 2014 Canonical Ltd.
77+ *
78+ * This program is free software; you can redistribute it and/or modify
79+ * it under the terms of the GNU Lesser General Public License as published by
80+ * the Free Software Foundation; version 3.
81+ *
82+ * This program is distributed in the hope that it will be useful,
83+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
84+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
85+ * GNU Lesser General Public License for more details.
86+ *
87+ * You should have received a copy of the GNU Lesser General Public License
88+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
89+ */
90+
91+import QtQuick 2.0
92+import Ubuntu.Components 0.1
93+import Ubuntu.Components.Pickers 0.1
94+import Ubuntu.Layouts 0.1
95+
96+MainView {
97+ width: units.gu(40)
98+ height: units.gu(71)
99+ backgroundColor: "#A55263"
100+
101+ property bool wide: true
102+
103+ Layouts {
104+ objectName: "layoutManager"
105+ layouts: [
106+ ConditionalLayout {
107+ name: "wideAspect"
108+ when: wide
109+
110+ ItemLayout {
111+ item: "object1"
112+ }
113+ },
114+
115+ ConditionalLayout {
116+ name: "regularAspect"
117+ when: !wide
118+
119+ ItemLayout {
120+ item: "object2"
121+ }
122+ }
123+ ]
124+
125+ Dialer {
126+ Layouts.item: "object1"
127+ }
128+ }
129+}
130
131=== added file 'tests/unit_x11/tst_layouts/ExcludedItemDeleted.qml'
132--- tests/unit_x11/tst_layouts/ExcludedItemDeleted.qml 1970-01-01 00:00:00 +0000
133+++ tests/unit_x11/tst_layouts/ExcludedItemDeleted.qml 2014-02-18 13:41:01 +0000
134@@ -0,0 +1,67 @@
135+/*
136+ * Copyright 2014 Canonical Ltd.
137+ *
138+ * This program is free software; you can redistribute it and/or modify
139+ * it under the terms of the GNU Lesser General Public License as published by
140+ * the Free Software Foundation; version 3.
141+ *
142+ * This program is distributed in the hope that it will be useful,
143+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
144+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
145+ * GNU Lesser General Public License for more details.
146+ *
147+ * You should have received a copy of the GNU Lesser General Public License
148+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
149+ */
150+
151+import QtQuick 2.0
152+import Ubuntu.Components 0.1
153+import Ubuntu.Layouts 0.1
154+
155+Item {
156+ property bool wide: true
157+ width: units.gu(40)
158+ height: units.gu(71)
159+
160+ function changeLayout() {
161+ loader2.sourceComponent = undefined; wide = false
162+ }
163+
164+ Layouts {
165+ objectName: "layoutManager"
166+ layouts: [
167+ ConditionalLayout {
168+ name: "wideAspect"
169+ when: wide
170+
171+ ItemLayout {
172+ item: "object1"
173+ }
174+ },
175+ ConditionalLayout {
176+ name: "regularAspect"
177+ when: !wide
178+
179+ ItemLayout {
180+ item: "object1"
181+ anchors.left: parent.left
182+ }
183+ }
184+ ]
185+
186+ Column {
187+ Loader {
188+ Layouts.item: "object1"
189+ id: loader
190+ sourceComponent: ShaderEffectSource {
191+ sourceItem: Item {
192+ }
193+ }
194+ }
195+ Loader {
196+ id: loader2
197+ sourceComponent: Item{}
198+ }
199+ }
200+ }
201+}
202
203=== added file 'tests/unit_x11/tst_layouts/ItemInstanceAsProperty.qml'
204--- tests/unit_x11/tst_layouts/ItemInstanceAsProperty.qml 1970-01-01 00:00:00 +0000
205+++ tests/unit_x11/tst_layouts/ItemInstanceAsProperty.qml 2014-02-18 13:41:01 +0000
206@@ -0,0 +1,63 @@
207+/*
208+ * Copyright 2014 Canonical Ltd.
209+ *
210+ * This program is free software; you can redistribute it and/or modify
211+ * it under the terms of the GNU Lesser General Public License as published by
212+ * the Free Software Foundation; version 3.
213+ *
214+ * This program is distributed in the hope that it will be useful,
215+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
216+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
217+ * GNU Lesser General Public License for more details.
218+ *
219+ * You should have received a copy of the GNU Lesser General Public License
220+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
221+ */
222+
223+import QtQuick 2.0
224+import Ubuntu.Components 0.1
225+import Ubuntu.Layouts 0.1
226+
227+Item {
228+ property bool wide: true
229+ width: units.gu(40)
230+ height: units.gu(71)
231+
232+ function changeLayout() {
233+ loader.sourceComponent = undefined; wide = false
234+ }
235+
236+ Layouts {
237+ objectName: "layoutManager"
238+ layouts: [
239+ ConditionalLayout {
240+ name: "wideAspect"
241+ when: wide
242+
243+ ItemLayout {
244+ item: "object1"
245+ }
246+ },
247+ ConditionalLayout {
248+ name: "regularAspect"
249+ when: !wide
250+
251+ ItemLayout {
252+ item: "object2"
253+ anchors.left: parent.left
254+ }
255+ }
256+ ]
257+
258+ Item {
259+ Layouts.item: "object1"
260+ Loader {
261+ id: loader
262+ sourceComponent: ShaderEffectSource {
263+ sourceItem: Item {
264+ }
265+ }
266+ }
267+ }
268+ }
269+}
270
271=== modified file 'tests/unit_x11/tst_layouts/tst_layouts.cpp'
272--- tests/unit_x11/tst_layouts/tst_layouts.cpp 2014-01-27 07:54:14 +0000
273+++ tests/unit_x11/tst_layouts/tst_layouts.cpp 2014-02-18 13:41:01 +0000
274@@ -897,6 +897,58 @@
275 QCOMPARE(anchors->margins(), 20.0);
276 }
277
278+ // the following tests guard bug #1280359
279+ void testCase_ItemInstanceAsProperty()
280+ {
281+ QScopedPointer<QQuickView> view(loadTest("ItemInstanceAsProperty.qml"));
282+ QVERIFY(view);
283+ QQuickItem *root = view->rootObject();
284+ QVERIFY(root);
285+
286+ QQuickItem *layout = testItem(root, "layoutManager");
287+ QVERIFY(layout);
288+ QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
289+
290+ // invoke layout change
291+ view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "changeLayout");
292+ layoutChangeSpy.wait();
293+ QCOMPARE(layoutChangeSpy.count(), 1);
294+ }
295+
296+ void testCase_DialerCrash()
297+ {
298+ QScopedPointer<QQuickView> view(loadTest("DialerCrash.qml"));
299+ QVERIFY(view);
300+ QQuickItem *root = view->rootObject();
301+ QVERIFY(root);
302+
303+ QQuickItem *layout = testItem(root, "layoutManager");
304+ QVERIFY(layout);
305+ QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
306+
307+ // invoke layout change
308+ view->rootObject()->setProperty("wide", false);
309+ layoutChangeSpy.wait();
310+ QCOMPARE(layoutChangeSpy.count(), 1);
311+ }
312+
313+ void testCase_ExcludedItemDeleted()
314+ {
315+ QScopedPointer<QQuickView> view(loadTest("ExcludedItemDeleted.qml"));
316+ QVERIFY(view);
317+ QQuickItem *root = view->rootObject();
318+ QVERIFY(root);
319+
320+ QQuickItem *layout = testItem(root, "layoutManager");
321+ QVERIFY(layout);
322+ QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
323+
324+ // invoke layout change
325+ view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "changeLayout");
326+ layoutChangeSpy.wait();
327+ QCOMPARE(layoutChangeSpy.count(), 1);
328+ }
329+
330 };
331
332 QTEST_MAIN(tst_Layouts)
333
334=== modified file 'tests/unit_x11/tst_layouts/tst_layouts.pro'
335--- tests/unit_x11/tst_layouts/tst_layouts.pro 2013-12-02 13:48:53 +0000
336+++ tests/unit_x11/tst_layouts/tst_layouts.pro 2014-02-18 13:41:01 +0000
337@@ -34,4 +34,7 @@
338 AnchorRight.qml \
339 AnchorTop.qml \
340 AnchorBottom.qml \
341- AnchorAll.qml
342+ AnchorAll.qml \
343+ ItemInstanceAsProperty.qml \
344+ DialerCrash.qml \
345+ ExcludedItemDeleted.qml

Subscribers

People subscribed via source and target branches

to status/vote changes: