on xenial help sign in
Fix temp scopes opening temp scopes, correctly close previously opened temp scope with its preview Fixes: #1410337
fb8bb42Andrea Cimitan
debian/control+2−2
@@ -27,7 +27,7 @@ Build-Depends: cmake,
27 libqmenumodel-dev (>= 0.2.9),
27 libqmenumodel-dev (>= 0.2.9),
28 libqt5xmlpatterns5-dev,
28 libqt5xmlpatterns5-dev,
29 libsystemsettings-dev,
29 libsystemsettings-dev,
30− libunity-api-dev (>= 7.95),
30+ libunity-api-dev (>= 7.96),
31 libusermetricsoutput1-dev,
31 libusermetricsoutput1-dev,
32 libxcb1-dev,
32 libxcb1-dev,
33 pkg-config,
33 pkg-config,
@@ -126,7 +126,7 @@ Depends: qml-module-qtquick-layouts,
126 unity-application-impl-4,
126 unity-application-impl-4,
127 unity-notifications-impl-3,
127 unity-notifications-impl-3,
128 unity-plugin-scopes | unity-scopes-impl,
128 unity-plugin-scopes | unity-scopes-impl,
129− unity-scopes-impl-4,
129+ unity-scopes-impl-6,
130 unity8-fake-env | unity-application-impl,
130 unity8-fake-env | unity-application-impl,
131 ${misc:Depends},
131 ${misc:Depends},
132Breaks: unity8 (<< 7.86),
132Breaks: unity8 (<< 7.86),
qml/Dash/Dash.qml+6−8
@@ -122,7 +122,6 @@ Showable {
122 dash.setCurrentScope(scopeId, true, false);
122 dash.setCurrentScope(scopeId, true, false);
123 }
123 }
124 onOpenScope: {
124 onOpenScope: {
125− scopeItem.scopeThatOpenedScope = currentScope;
126 scopeItem.scope = scope;
125 scopeItem.scope = scope;
127 x = -width;
126 x = -width;
128 }
127 }
@@ -130,7 +129,7 @@ Showable {
130 UbuntuNumberAnimation {
129 UbuntuNumberAnimation {
131 onRunningChanged: {
130 onRunningChanged: {
132 if (!running && dashContent.x == 0) {
131 if (!running && dashContent.x == 0) {
133− scopeItem.scopeThatOpenedScope.closeScope(scopeItem.scope);
132+ scopes.closeScope(scopeItem.scope);
134 scopeItem.scope = null;
133 scopeItem.scope = null;
135 }
134 }
136 }
135 }
@@ -187,7 +186,6 @@ Showable {
187 onOpenScope: {
186 onOpenScope: {
188 bottomEdgeController.enableAnimation = true;
187 bottomEdgeController.enableAnimation = true;
189 bottomEdgeController.progress = 0;
188 bottomEdgeController.progress = 0;
190− scopeItem.scopeThatOpenedScope = scopesList.scope;
191 scopeItem.scope = scope;
189 scopeItem.scope = scope;
192 dashContent.x = -dashContent.width;
190 dashContent.x = -dashContent.width;
193 }
191 }
@@ -199,8 +197,7 @@ Showable {
199 }
197 }
200 }
198 }
201
199
202− DashBackground
200+ DashBackground {
203− {
204 anchors.fill: scopeItem
201 anchors.fill: scopeItem
205 visible: scopeItem.visible
202 visible: scopeItem.visible
206 }
203 }
@@ -209,8 +206,6 @@ Showable {
209 id: scopeItem
206 id: scopeItem
210 objectName: "dashTempScopeItem"
207 objectName: "dashTempScopeItem"
211
208
212− property var scopeThatOpenedScope: null
213−
214 x: dashContent.x + width
209 x: dashContent.x + width
215 y: dashContent.y
210 y: dashContent.y
216 width: parent.width
211 width: parent.width
@@ -229,7 +224,10 @@ Showable {
229 dashContent.gotoScope(scopeId);
224 dashContent.gotoScope(scopeId);
230 }
225 }
231 onOpenScope: {
226 onOpenScope: {
232− dashContent.openScope(scope);
227+ scopeItem.closePreview();
228+ var oldScope = scopeItem.scope;
229+ scopeItem.scope = scope;
230+ scopes.closeScope(oldScope);
233 }
231 }
234 }
232 }
235 }
233 }
qml/Dash/DashContent.qml+1−2
@@ -84,8 +84,7 @@ Item {
84
84
85 set_current_index = undefined;
85 set_current_index = undefined;
86
86
87− if (dashContentList.count > index)
87+ if (dashContentList.count > index) {
88− {
89 dashContentList.currentIndex = index
88 dashContentList.currentIndex = index
90
89
91 if (reset) {
90 if (reset) {
tests/mocks/Unity/CMakeLists.txt+1−1
@@ -6,7 +6,7 @@ add_subdirectory(Notifications)
6add_subdirectory(DashCommunicator)
6add_subdirectory(DashCommunicator)
7
7
8pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
8pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
9−pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=5)
9+pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=6)
10
10
11include_directories(
11include_directories(
12 ${CMAKE_CURRENT_BINARY_DIR}
12 ${CMAKE_CURRENT_BINARY_DIR}
tests/mocks/Unity/fake_previewmodel.cpp+15−1
@@ -22,18 +22,23 @@
22#include "fake_previewmodel.h"
22#include "fake_previewmodel.h"
23
23
24// local
24// local
25+#include "fake_scope.h"
26+#include "fake_scopes.h"
25#include "fake_previewwidgetmodel.h"
27#include "fake_previewwidgetmodel.h"
26
28
27// Qt
29// Qt
28#include <QDebug>
30#include <QDebug>
29
31
30−PreviewModel::PreviewModel(QObject* parent)
32+PreviewModel::PreviewModel(QObject* parent, Scope* scope)
31 : unity::shell::scopes::PreviewModelInterface(parent)
33 : unity::shell::scopes::PreviewModelInterface(parent)
32 , m_loaded(true)
34 , m_loaded(true)
35+ , m_scope(scope)
33{
36{
34 // we have one column by default
37 // we have one column by default
35 PreviewWidgetModel* columnModel = new PreviewWidgetModel(this);
38 PreviewWidgetModel* columnModel = new PreviewWidgetModel(this);
36 m_previewWidgetModels.append(columnModel);
39 m_previewWidgetModels.append(columnModel);
40+ connect(this, SIGNAL(triggered(QString const&, QString const&, QVariantMap const&)),
41+ this, SLOT(triggeredSlot(QString const&, QString const&, QVariantMap const&)));
37}
42}
38
43
39void PreviewModel::setWidgetColumnCount(int count)
44void PreviewModel::setWidgetColumnCount(int count)
@@ -80,3 +85,12 @@ void PreviewModel::setLoaded(bool loaded)
80 Q_EMIT loadedChanged();
85 Q_EMIT loadedChanged();
81 }
86 }
82}
87}
88+
89+void PreviewModel::triggeredSlot(QString const&, QString const&, QVariantMap const&) {
90+ if (m_scope) {
91+ Scopes *scopes = dynamic_cast<Scopes*>(m_scope->parent());
92+ Scope* scope = scopes->getScopeFromAll("MockScope9");
93+ scopes->addTempScope(scope);
94+ Q_EMIT m_scope->openScope(scope);
95+ }
96+}
tests/mocks/Unity/fake_previewmodel.h+7−1
@@ -25,12 +25,14 @@
25
25
26class PreviewWidgetModel;
26class PreviewWidgetModel;
27
27
28+class Scope;
29+
28class PreviewModel : public unity::shell::scopes::PreviewModelInterface
30class PreviewModel : public unity::shell::scopes::PreviewModelInterface
29{
31{
30 Q_OBJECT
32 Q_OBJECT
31
33
32public:
34public:
33− explicit PreviewModel(QObject* parent = 0);
35+ explicit PreviewModel(QObject* parent = 0, Scope* scope = 0);
34
36
35 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
37 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
36 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
38 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
@@ -42,9 +44,13 @@ public:
42
44
43 Q_INVOKABLE void setLoaded(bool); // Only available for testing
45 Q_INVOKABLE void setLoaded(bool); // Only available for testing
44
46
47+private Q_SLOTS:
48+ void triggeredSlot(QString const&, QString const&, QVariantMap const&);
49+
45private:
50private:
46 QList<PreviewWidgetModel*> m_previewWidgetModels;
51 QList<PreviewWidgetModel*> m_previewWidgetModels;
47 bool m_loaded;
52 bool m_loaded;
53+ Scope* m_scope;
48};
54};
49
55
50Q_DECLARE_METATYPE(PreviewModel*)
56Q_DECLARE_METATYPE(PreviewModel*)
tests/mocks/Unity/fake_previewstack.cpp+2−2
@@ -21,10 +21,10 @@
21#include "fake_previewmodel.h"
21#include "fake_previewmodel.h"
22#include "fake_scope.h"
22#include "fake_scope.h"
23
23
24−PreviewStack::PreviewStack(QObject* parent)
24+PreviewStack::PreviewStack(QObject* parent, Scope *scope)
25 : unity::shell::scopes::PreviewStackInterface(parent)
25 : unity::shell::scopes::PreviewStackInterface(parent)
26{
26{
27− m_previews << new PreviewModel(this);
27+ m_previews << new PreviewModel(this, scope);
28}
28}
29
29
30PreviewStack::~PreviewStack()
30PreviewStack::~PreviewStack()
tests/mocks/Unity/fake_previewstack.h+3−1
@@ -25,12 +25,14 @@
25
25
26class PreviewModel;
26class PreviewModel;
27
27
28+class Scope;
29+
28class PreviewStack : public unity::shell::scopes::PreviewStackInterface
30class PreviewStack : public unity::shell::scopes::PreviewStackInterface
29{
31{
30 Q_OBJECT
32 Q_OBJECT
31
33
32public:
34public:
33− explicit PreviewStack(QObject* parent = 0);
35+ explicit PreviewStack(QObject* parent = 0, Scope* scope = 0);
34 virtual ~PreviewStack();
36 virtual ~PreviewStack();
35
37
36 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
38 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
tests/mocks/Unity/fake_previewwidgetmodel.cpp+1
@@ -57,6 +57,7 @@ void PreviewWidgetModel::populateWidgets()
57 QVariantMap attributes;
57 QVariantMap attributes;
58 QVariantMap buttonData;
58 QVariantMap buttonData;
59 buttonData["label"] = "Button";
59 buttonData["label"] = "Button";
60+ buttonData["id"] = "open_click";
60 QVariantList buttons;
61 QVariantList buttons;
61 buttons << buttonData << buttonData << buttonData;
62 buttons << buttonData << buttonData << buttonData;
62 attributes["actions"] = QVariant::fromValue(buttons);
63 attributes["actions"] = QVariant::fromValue(buttons);
tests/mocks/Unity/fake_scope.cpp+5−5
@@ -185,6 +185,7 @@ void Scope::activate(QVariant const& result)
185 if (result.toString() == "Result.2.2") {
185 if (result.toString() == "Result.2.2") {
186 Scopes *scopes = dynamic_cast<Scopes*>(parent());
186 Scopes *scopes = dynamic_cast<Scopes*>(parent());
187 m_openScope = scopes->getScopeFromAll("MockScope9");
187 m_openScope = scopes->getScopeFromAll("MockScope9");
188+ scopes->addTempScope(m_openScope);
188 Q_EMIT openScope(m_openScope);
189 Q_EMIT openScope(m_openScope);
189 }
190 }
190}
191}
@@ -198,7 +199,7 @@ PreviewStack* Scope::preview(QVariant const& result)
198 } else {
199 } else {
199 // This probably leaks, do we don't care
200 // This probably leaks, do we don't care
200 // it's a test after all
201 // it's a test after all
201− return new PreviewStack;
202+ return new PreviewStack(this, this);
202 }
203 }
203}
204}
204
205
@@ -208,11 +209,10 @@ void Scope::cancelActivation()
208
209
209void Scope::closeScope(unity::shell::scopes::ScopeInterface* scope)
210void Scope::closeScope(unity::shell::scopes::ScopeInterface* scope)
210{
211{
211− if (scope != m_openScope) {
212+ Scopes *scopes = dynamic_cast<Scopes*>(parent());
212− qDebug() << scope << m_openScope;
213+ if (scopes) {
213− qFatal("Scope::closeScope got wrong scope in closeScope");
214+ return scopes->closeScope(scope);
214 }
215 }
215− m_openScope = nullptr;
216}
216}
217
217
218QString Scope::currentNavigationId() const
218QString Scope::currentNavigationId() const
tests/mocks/Unity/fake_scopes.cpp+12
@@ -23,6 +23,7 @@
23// TODO: Implement remaining pieces, like Categories (i.e. LensView now gives warnings)
23// TODO: Implement remaining pieces, like Categories (i.e. LensView now gives warnings)
24
24
25// Qt
25// Qt
26+#include <QDebug>
26#include <QTimer>
27#include <QTimer>
27
28
28Scopes::Scopes(QObject *parent)
29Scopes::Scopes(QObject *parent)
@@ -177,6 +178,17 @@ unity::shell::scopes::ScopeInterface* Scopes::overviewScope() const
177 return m_scopesOverview;
178 return m_scopesOverview;
178}
179}
179
180
181+void Scopes::addTempScope(unity::shell::scopes::ScopeInterface* scope)
182+{
183+ m_tempScopes.insert(scope);
184+}
185+
186+void Scopes::closeScope(unity::shell::scopes::ScopeInterface* scope)
187+{
188+ Q_ASSERT(m_tempScopes.contains(scope));
189+ m_tempScopes.remove(scope);
190+}
191+
180void Scopes::setFavorite(const QString& scopeId, bool favorite)
192void Scopes::setFavorite(const QString& scopeId, bool favorite)
181{
193{
182 if (favorite) {
194 if (favorite) {
tests/mocks/Unity/fake_scopes.h+5
@@ -26,6 +26,7 @@
26
26
27// Qt
27// Qt
28#include <QList>
28#include <QList>
29+#include <QSet>
29#include <QTimer>
30#include <QTimer>
30
31
31class ScopesOverview;
32class ScopesOverview;
@@ -59,6 +60,9 @@ public:
59 Q_INVOKABLE void setFavorite(const QString& scopeId, bool favorite) override;
60 Q_INVOKABLE void setFavorite(const QString& scopeId, bool favorite) override;
60 Q_INVOKABLE void moveFavoriteTo(const QString& scopeId, int index) override;
61 Q_INVOKABLE void moveFavoriteTo(const QString& scopeId, int index) override;
61
62
63+ void addTempScope(unity::shell::scopes::ScopeInterface* scope);
64+ Q_INVOKABLE void closeScope(unity::shell::scopes::ScopeInterface* scope) override;
65+
62 // This is used as part of implementation of the other C++ code, not API
66 // This is used as part of implementation of the other C++ code, not API
63 QList<Scope*> favScopes() const;
67 QList<Scope*> favScopes() const;
64 QList<Scope*> nonFavScopes() const;
68 QList<Scope*> nonFavScopes() const;
@@ -70,6 +74,7 @@ private Q_SLOTS:
70private:
74private:
71 QList<Scope*> m_scopes; // the favorite ones
75 QList<Scope*> m_scopes; // the favorite ones
72 QList<Scope*> m_allScopes;
76 QList<Scope*> m_allScopes;
77+ QSet<unity::shell::scopes::ScopeInterface*> m_tempScopes;
73 ScopesOverview *m_scopesOverview;
78 ScopesOverview *m_scopesOverview;
74 bool m_loaded;
79 bool m_loaded;
75 QTimer timer;
80 QTimer timer;
tests/mocks/Unity/fake_scopesoverview.cpp+1
@@ -48,6 +48,7 @@ Q_INVOKABLE void ScopesOverview::activate(QVariant const& result)
48 Q_EMIT gotoScope(result.toString());
48 Q_EMIT gotoScope(result.toString());
49 } else {
49 } else {
50 m_openScope = scopes->getScopeFromAll(result.toString());
50 m_openScope = scopes->getScopeFromAll(result.toString());
51+ scopes->addTempScope(m_openScope);
51 Q_EMIT openScope(m_openScope);
52 Q_EMIT openScope(m_openScope);
52 }
53 }
53}
54}
tests/qmltests/Dash/tst_Dash.qml+69
@@ -428,5 +428,74 @@ Item {
428 tryCompare(bottomEdgeController, "progress", 0);
428 tryCompare(bottomEdgeController, "progress", 0);
429 tryCompare(dashContentList, "currentIndex", 1)
429 tryCompare(dashContentList, "currentIndex", 1)
430 }
430 }
431+
432+ function test_close_temp_scope_preview_opening_scope() {
433+ // Show the manage dash
434+ touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, units.gu(2));
435+ var bottomEdgeController = findInvisibleChild(dash, "bottomEdgeController");
436+ tryCompare(bottomEdgeController, "progress", 1);
437+
438+ // Make sure stuff is loaded
439+ var nonfavScopesListCategory = findChild(dash, "scopesListCategoryother");
440+ var nonfavScopesListCategoryList = findChild(nonfavScopesListCategory, "scopesListCategoryInnerList");
441+ tryCompare(nonfavScopesListCategoryList, "currentIndex", 0);
442+
443+ // Click on a non favorite scope
444+ mouseClick(nonfavScopesListCategoryList.currentItem);
445+
446+ // Check the bottom edge (manage dash) is disabled from temp scope
447+ var overviewDragHandle = findChild(dash, "overviewDragHandle");
448+ compare(overviewDragHandle.enabled, false);
449+
450+ // Check temp scope is there
451+ var dashTempScopeItem = findChild(dash, "dashTempScopeItem");
452+ tryCompare(dashTempScopeItem, "x", 0);
453+ tryCompare(dashTempScopeItem, "visible", true);
454+
455+ // Check the manage dash is gone
456+ tryCompare(bottomEdgeController, "progress", 0);
457+
458+ // Open preview
459+ var categoryListView = findChild(dashTempScopeItem, "categoryListView");
460+ categoryListView.positionAtBeginning();
461+ tryCompareFunction(function() {
462+ var cardGrid = findChild(dashTempScopeItem, "dashCategory0");
463+ if (cardGrid != null) {
464+ var tile = findChild(cardGrid, "delegate0");
465+ return tile != null;
466+ }
467+ return false;
468+ },
469+ true);
470+ var tile = findChild(findChild(dashTempScopeItem, "dashCategory0"), "delegate0");
471+ waitForRendering(tile);
472+ mouseClick(tile);
473+ var subPageLoader = findChild(dashTempScopeItem, "subPageLoader");
474+ tryCompare(subPageLoader, "open", true);
475+ tryCompare(subPageLoader, "x", 0);
476+ tryCompare(findChild(dashTempScopeItem, "categoryListView"), "visible", false);
477+ var previewListRow0 = findChild(subPageLoader, "previewListRow0");
478+ touchFlick(previewListRow0, previewListRow0.width / 2, units.gu(20), previewListRow0.width / 2, units.gu(1));
479+ tryCompare(previewListRow0, "atYEnd", true);
480+ tryCompare(previewListRow0, "moving", false);
481+ var widget = findChild(subPageLoader, "widget-21");
482+ var initialWidgetHeight = widget.height;
483+ var openButton = findChild(widget, "buttonopen_click");
484+ mouseClick(openButton);
485+
486+ tryCompare(subPageLoader, "open", false);
487+ tryCompare(subPageLoader, "x", subPageLoader.width);
488+
489+ compare(dashTempScopeItem.scope.id, "MockScope9");
490+
491+ // Go back
492+ var dashTempScopeItemHeader = findChild(dashTempScopeItem, "scopePageHeader");
493+ var backButton = findChild(findChild(dashTempScopeItemHeader, "innerPageHeader"), "customBackButton");
494+ mouseClick(backButton);
495+
496+ // Check temp scope is gone
497+ tryCompare(dashTempScopeItem, "x", dash.width);
498+ tryCompare(dashTempScopeItem, "visible", false);
499+ }
431 }
500 }
432}
501}