on xenial help sign in
merge prereq
644acbaMichael Zanetti
qml/Stages/ApplicationWindow.qml+25−9
@@ -121,15 +121,12 @@ FocusScope {
121
121
122 property bool surfaceOldEnoughToBeResized: false
122 property bool surfaceOldEnoughToBeResized: false
123
123
124− property var focusedSurface: {
125− if (promptSurfacesRepeater.count == 0) {
124+ property Item focusedSurface: promptSurfacesRepeater.count === 0 ? surfaceContainer
126− return surfaceContainer;
127− } else {
128− return promptSurfacesRepeater.itemAt(promptSurfacesRepeater.count - 1);
125+ : promptSurfacesRepeater.first
129− }
130− }
131 onFocusedSurfaceChanged: {
126 onFocusedSurfaceChanged: {
127+ if (focusedSurface) {
132− focusedSurface.focus = true;
128+ focusedSurface.focus = true;
129+ }
133 }
130 }
134 }
131 }
135
132
@@ -158,6 +155,7 @@ FocusScope {
158 objectName: "screenshotImage"
155 objectName: "screenshotImage"
159 anchors.fill: parent
156 anchors.fill: parent
160 antialiasing: !root.interactive
157 antialiasing: !root.interactive
158+ z: 1
161
159
162 function take() {
160 function take() {
163 // Save memory by using a half-resolution (thus quarter size) screenshot.
161 // Save memory by using a half-resolution (thus quarter size) screenshot.
@@ -175,6 +173,7 @@ FocusScope {
175 visible: active
173 visible: active
176 active: false
174 active: false
177 anchors.fill: parent
175 anchors.fill: parent
176+ z: screenshotImage.z + 1
178 sourceComponent: Component {
177 sourceComponent: Component {
179 Splash {
178 Splash {
180 id: splash
179 id: splash
@@ -191,6 +190,7 @@ FocusScope {
191
190
192 SurfaceContainer {
191 SurfaceContainer {
193 id: surfaceContainer
192 id: surfaceContainer
193+ z: splashLoader.z + 1
194 requestedWidth: root.requestedWidth
194 requestedWidth: root.requestedWidth
195 requestedHeight: root.requestedHeight
195 requestedHeight: root.requestedHeight
196 surfaceOrientationAngle: application && application.rotatesWindowContents ? root.surfaceOrientationAngle : 0
196 surfaceOrientationAngle: application && application.rotatesWindowContents ? root.surfaceOrientationAngle : 0
@@ -208,12 +208,28 @@ FocusScope {
208 }
208 }
209 }
209 }
210 delegate: SurfaceContainer {
210 delegate: SurfaceContainer {
211+ id: promptSurfaceContainer
211− interactive: index == (promptSurfacesRepeater.count - 1) && root.interactive
212+ interactive: index === 0 && root.interactive
212 surface: model.surface
213 surface: model.surface
213 width: root.width
214 width: root.width
214 height: root.height
215 height: root.height
215 isPromptSurface: true
216 isPromptSurface: true
217+ z: surfaceContainer.z + (promptSurfacesRepeater.count - index)
218+ property int index: model.index
219+ onIndexChanged: updateFirst()
220+ Component.onCompleted: updateFirst()
221+ function updateFirst() {
222+ if (index === 0) {
223+ promptSurfacesRepeater.first = promptSurfaceContainer;
224+ }
225+ }
226+ }
227+ onCountChanged: {
228+ if (count === 0) {
229+ first = null;
230+ }
216 }
231 }
232+ property Item first: null
217 }
233 }
218
234
219 // SurfaceContainer size drives ApplicationWindow size
235 // SurfaceContainer size drives ApplicationWindow size
tests/mocks/Unity/Application/MirSurfaceListModel.cpp+11−1
@@ -72,6 +72,16 @@ void MirSurfaceListModel::appendSurface(MirSurface *surface)
72 }
72 }
73}
73}
74
74
75+void MirSurfaceListModel::prependSurface(MirSurface *surface)
76+{
77+ beginInsertRows(QModelIndex(), 0, 0);
78+ m_surfaceList.prepend(surface);
79+ connectSurface(surface);
80+ endInsertRows();
81+ Q_EMIT countChanged(m_surfaceList.count());
82+ Q_EMIT firstChanged();
83+}
84+
75void MirSurfaceListModel::connectSurface(MirSurface *surface)
85void MirSurfaceListModel::connectSurface(MirSurface *surface)
76{
86{
77 connect(surface, &MirSurface::raiseRequested, this, [this, surface](){ this->raise(surface); });
87 connect(surface, &MirSurface::raiseRequested, this, [this, surface](){ this->raise(surface); });
@@ -143,7 +153,7 @@ MirSurfaceInterface *MirSurfaceListModel::createSurface()
143 Mir::RestoredState,
153 Mir::RestoredState,
144 screenshotUrl);
154 screenshotUrl);
145
155
146− appendSurface(surface);
156+ prependSurface(surface);
147
157
148 return surface;
158 return surface;
149}
159}
tests/mocks/Unity/Application/MirSurfaceListModel.h+1
@@ -49,6 +49,7 @@ public:
49 Q_INVOKABLE unity::shell::application::MirSurfaceInterface *createSurface();
49 Q_INVOKABLE unity::shell::application::MirSurfaceInterface *createSurface();
50
50
51private:
51private:
52+ void prependSurface(MirSurface *surface);
52 void raise(MirSurface *surface);
53 void raise(MirSurface *surface);
53 void moveSurface(int from, int to);
54 void moveSurface(int from, int to);
54 void connectSurface(MirSurface *surface);
55 void connectSurface(MirSurface *surface);
tests/qmltests/Stages/ApplicationCheckBox.qml+1−1
@@ -156,7 +156,7 @@ Column {
156 width: height
156 width: height
157 height: promptsLabel.height * 0.7
157 height: promptsLabel.height * 0.7
158 anchors.verticalCenter: parent.verticalCenter
158 anchors.verticalCenter: parent.verticalCenter
159− onClicked: d.application.promptSurfaceList.get(d.application.promptSurfaceList.count - 1).close()
159+ onClicked: d.application.promptSurfaceList.get(0).close()
160 enabled: d.application && d.application.promptSurfaceList.count > 0
160 enabled: d.application && d.application.promptSurfaceList.count > 0
161 Label { text: "➖"; anchors.centerIn: parent; enabled: parent.enabled }
161 Label { text: "➖"; anchors.centerIn: parent; enabled: parent.enabled }
162 }
162 }
tests/qmltests/Stages/tst_ApplicationWindow.qml+39−9
@@ -106,7 +106,7 @@ Rectangle {
106 enabled: parent.promptSurfaceList !== null && parent.promptSurfaceList.count > 0
106 enabled: parent.promptSurfaceList !== null && parent.promptSurfaceList.count > 0
107 activeFocusOnPress: false
107 activeFocusOnPress: false
108 text: "Remove"
108 text: "Remove"
109− onClicked: { parent.promptSurfaceList.get(parent.promptSurfaceList.count - 1).close(); }
109+ onClicked: { parent.promptSurfaceList.get(0).close(); }
110 }
110 }
111
111
112 Button {
112 Button {
@@ -449,20 +449,21 @@ Rectangle {
449 for (i = 0; i < 3; i++) {
449 for (i = 0; i < 3; i++) {
450 promptSurfaceList.createSurface();
450 promptSurfaceList.createSurface();
451 compare(promptSurfaces.count, i+1);
451 compare(promptSurfaces.count, i+1);
452− waitUntilSurfaceContainerStopsAnimating(promptSurfaces.itemAt(promptSurfaces.count - 1));
452+ waitUntilSurfaceContainerStopsAnimating(promptSurfaces.itemAt(0));
453 }
453 }
454
454
455− for (i = 2; i >= 0; --i) {
455+ for (i = 3; i > 0; --i) {
456− var promptSurface = promptSurfaceList.get(i);
456+ var promptSurface = promptSurfaceList.get(0);
457 compare(promptSurface.activeFocus, true);
457 compare(promptSurface.activeFocus, true);
458
458
459 promptSurface.close();
459 promptSurface.close();
460+ promptSurface = null;
460− tryCompareFunction(function() { return promptSurfaces.count; }, i);
461+ tryCompareFunction(function() { return promptSurfaces.count; }, i-1);
461
462
462− if (i > 0) {
463+ if (promptSurfaces.count > 0) {
463− // active focus should have gone to the yongest remaining sibling
464+ // active focus should have gone to the new head of the list
464− var previousPromptSurface = promptSurfaceList.get(i-1);
465+ promptSurface = promptSurfaceList.get(0);
465− tryCompare(previousPromptSurface, "activeFocus", true);
466+ tryCompare(promptSurface, "activeFocus", true);
466 } else {
467 } else {
467 // active focus should have gone to the application surface
468 // active focus should have gone to the application surface
468 tryCompare(applicationWindow.surface, "activeFocus", true);
469 tryCompare(applicationWindow.surface, "activeFocus", true);
@@ -498,5 +499,34 @@ Rectangle {
498 delegate.surface.close();
499 delegate.surface.close();
499 tryCompare(promptSurfaces, "count", 0);
500 tryCompare(promptSurfaces, "count", 0);
500 }
501 }
502+
503+ // Check that the z value of SurfaceContainers for prompt surfaces go from highest
504+ // for index 0 to lowest for the last index in the prompt surface list.
505+ // Regression test for https://bugs.launchpad.net/bugs/1586219
506+ function test_promptSurfacesZOrdering() {
507+ var promptSurfaceList = root.fakeApplication.promptSurfaceList;
508+ var promptSurfaces = testCase.findChild(applicationWindow, "promptSurfacesRepeater");
509+
510+ promptSurfaceList.createSurface();
511+
512+ for (var i = 2; i <= 3; i++) {
513+ promptSurfaceList.createSurface();
514+ tryCompare(promptSurfaces, "count", i);
515+ waitUntilSurfaceContainerStopsAnimating(promptSurfaces.itemAt(0));
516+
517+ for (var j = 1; j < promptSurfaces.count; j++) {
518+ var delegate = promptSurfaces.itemAt(j);
519+ var previousDelegate = promptSurfaces.itemAt(j-1);
520+ verify(previousDelegate.z > delegate.z);
521+ }
522+ }
523+
524+ // clean up
525+ while (promptSurfaceList.count > 0) {
526+ var currentCount = promptSurfaceList.count;
527+ promptSurfaceList.get(0).close();
528+ tryCompare(promptSurfaceList, "count", currentCount - 1);
529+ }
530+ }
501 }
531 }
502}
532}