on xenial help sign in
Merge the scope-isactive branch
22e43a1Michal Hruby
Dash/Dash.qml+3
@@ -22,6 +22,9 @@ import "../Components"
22
22
23Showable {
23Showable {
24 id: dash
24 id: dash
25+ objectName: "dash"
26+
27+ visible: shown
25
28
26 property alias contentProgress: dashContent.contentProgress
29 property alias contentProgress: dashContent.contentProgress
27 property string showScopeOnLoaded: "home.scope"
30 property string showScopeOnLoaded: "home.scope"
Dash/DashContent.qml+2−2
@@ -117,12 +117,12 @@ Item {
117
117
118 // these are needed for autopilot tests
118 // these are needed for autopilot tests
119 readonly property string scopeId: scope.id
119 readonly property string scopeId: scope.id
120− readonly property bool isCurrent: ListView.isCurrentItem
120+ readonly property bool isCurrent: visible && ListView.isCurrentItem
121 readonly property bool isLoaded: status == Loader.Ready
121 readonly property bool isLoaded: status == Loader.Ready
122
122
123 onLoaded: {
123 onLoaded: {
124 item.scope = Qt.binding(function() { return scope })
124 item.scope = Qt.binding(function() { return scope })
125− item.isCurrent = Qt.binding(function() { return ListView.isCurrentItem })
125+ item.isCurrent = Qt.binding(function() { return isCurrent })
126 item.searchHistory = Qt.binding(function() { return shell.searchHistory })
126 item.searchHistory = Qt.binding(function() { return shell.searchHistory })
127 dashContentList.movementStarted.connect(item.movementStarted)
127 dashContentList.movementStarted.connect(item.movementStarted)
128 dashContent.positionedAtBeginning.connect(item.positionedAtBeginning)
128 dashContent.positionedAtBeginning.connect(item.positionedAtBeginning)
Dash/ScopeView.qml+11−3
@@ -31,14 +31,22 @@ FocusScope {
31 // FIXME delay the search so that daemons have time to settle, note that
31 // FIXME delay the search so that daemons have time to settle, note that
32 // removing this will break ScopeView::test_changeScope
32 // removing this will break ScopeView::test_changeScope
33 onScopeChanged: {
33 onScopeChanged: {
34+ if (scope) {
34− timer.restart();
35+ timer.restart();
35− scope.activateApplication.connect(activateApp);
36+ scope.activateApplication.connect(activateApp);
37+ }
36 }
38 }
37
39
38 function activateApp(desktopFilePath) {
40 function activateApp(desktopFilePath) {
39 shell.activateApplication(desktopFilePath);
41 shell.activateApplication(desktopFilePath);
40 }
42 }
41
43
44+ Binding {
45+ target: scope
46+ property: "isActive"
47+ value: isCurrent
48+ }
49+
42 Timer {
50 Timer {
43 id: timer
51 id: timer
44 interval: 2000
52 interval: 2000
@@ -47,7 +55,7 @@ FocusScope {
47
55
48 SortFilterProxyModel {
56 SortFilterProxyModel {
49 id: categoryFilter
57 id: categoryFilter
50− model: scope.categories
58+ model: scope ? scope.categories : null
51 dynamicSortFilter: true
59 dynamicSortFilter: true
52 filterRole: Categories.RoleCount
60 filterRole: Categories.RoleCount
53 filterRegExp: /^0$/
61 filterRegExp: /^0$/
Panel/Panel.qml+1
@@ -73,6 +73,7 @@ Item {
73
73
74 Indicators {
74 Indicators {
75 id: indicatorsMenu
75 id: indicatorsMenu
76+ objectName: "indicators"
76
77
77 anchors.right: parent.right
78 anchors.right: parent.right
78 y: panelBackground.y
79 y: panelBackground.y
plugins/Unity/scope.cpp+12
@@ -110,6 +110,11 @@ QString Scope::formFactor() const
110 return m_formFactor;
110 return m_formFactor;
111}
111}
112
112
113+bool Scope::isActive() const
114+{
115+ return m_isActive;
116+}
117+
113Filters* Scope::filters() const
118Filters* Scope::filters() const
114{
119{
115 return m_filters.get();
120 return m_filters.get();
@@ -152,6 +157,13 @@ void Scope::setFormFactor(const QString& form_factor) {
152 }
157 }
153}
158}
154
159
160+void Scope::setActive(const bool active) {
161+ if (active != m_isActive) {
162+ m_isActive = active;
163+ Q_EMIT isActiveChanged(m_isActive);
164+ }
165+}
166+
155unity::dash::LocalResult Scope::createLocalResult(const QVariant &uri, const QVariant &icon_hint,
167unity::dash::LocalResult Scope::createLocalResult(const QVariant &uri, const QVariant &icon_hint,
156 const QVariant &category, const QVariant &result_type,
168 const QVariant &category, const QVariant &result_type,
157 const QVariant &mimetype, const QVariant &title,
169 const QVariant &mimetype, const QVariant &title,
plugins/Unity/scope.h+5
@@ -54,6 +54,7 @@ class Scope : public QObject
54 Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
54 Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
55 Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
55 Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
56 Q_PROPERTY(QString formFactor READ formFactor WRITE setFormFactor NOTIFY formFactorChanged)
56 Q_PROPERTY(QString formFactor READ formFactor WRITE setFormFactor NOTIFY formFactorChanged)
57+ Q_PROPERTY(bool isActive READ isActive WRITE setActive NOTIFY isActiveChanged)
57
58
58public:
59public:
59 explicit Scope(QObject *parent = 0);
60 explicit Scope(QObject *parent = 0);
@@ -73,11 +74,13 @@ public:
73 QString searchQuery() const;
74 QString searchQuery() const;
74 QString noResultsHint() const;
75 QString noResultsHint() const;
75 QString formFactor() const;
76 QString formFactor() const;
77+ bool isActive() const;
76
78
77 /* setters */
79 /* setters */
78 void setSearchQuery(const QString& search_query);
80 void setSearchQuery(const QString& search_query);
79 void setNoResultsHint(const QString& hint);
81 void setNoResultsHint(const QString& hint);
80 void setFormFactor(const QString& form_factor);
82 void setFormFactor(const QString& form_factor);
83+ void setActive(const bool);
81
84
82 Q_INVOKABLE void activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
85 Q_INVOKABLE void activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
83 const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
86 const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
@@ -104,6 +107,7 @@ Q_SIGNALS:
104 void searchQueryChanged();
107 void searchQueryChanged();
105 void noResultsHintChanged();
108 void noResultsHintChanged();
106 void formFactorChanged();
109 void formFactorChanged();
110+ void isActiveChanged(bool);
107 void filtersChanged();
111 void filtersChanged();
108
112
109 // signals triggered by activate(..) or preview(..) requests.
113 // signals triggered by activate(..) or preview(..) requests.
@@ -134,6 +138,7 @@ private:
134 QString m_searchQuery;
138 QString m_searchQuery;
135 QString m_noResultsHint;
139 QString m_noResultsHint;
136 QString m_formFactor;
140 QString m_formFactor;
141+ bool m_isActive;
137 bool m_searchInProgress;
142 bool m_searchInProgress;
138 unity::glib::Cancellable m_cancellable;
143 unity::glib::Cancellable m_cancellable;
139};
144};
tests/mocks/Unity/fake_scope.cpp+13
@@ -31,6 +31,7 @@ Scope::Scope(QObject* parent)
31 : QObject(parent)
31 : QObject(parent)
32 , m_visible(false)
32 , m_visible(false)
33 , m_searching(false)
33 , m_searching(false)
34+ , m_isActive(false)
34 , m_categories(new Categories(this))
35 , m_categories(new Categories(this))
35 , m_results(new DeeListModel(this))
36 , m_results(new DeeListModel(this))
36{
37{
@@ -46,6 +47,7 @@ Scope::Scope(QString const& id, QString const& name, bool visible, QObject* pare
46 , m_name(name)
47 , m_name(name)
47 , m_visible(visible)
48 , m_visible(visible)
48 , m_searching(false)
49 , m_searching(false)
50+ , m_isActive(false)
49 , m_categories(new Categories(this))
51 , m_categories(new Categories(this))
50 , m_results(new DeeListModel(this))
52 , m_results(new DeeListModel(this))
51{
53{
@@ -107,6 +109,10 @@ bool Scope::visible() const {
107 return m_visible;
109 return m_visible;
108}
110}
109
111
112+bool Scope::isActive() const {
113+ return m_isActive;
114+}
115+
110void Scope::setName(const QString &str) {
116void Scope::setName(const QString &str) {
111 if (str != m_name) {
117 if (str != m_name) {
112 m_name = str;
118 m_name = str;
@@ -128,6 +134,13 @@ void Scope::setFormFactor(const QString &str) {
128 }
134 }
129}
135}
130
136
137+void Scope::setActive(const bool active) {
138+ if (active != m_isActive) {
139+ m_isActive = active;
140+ Q_EMIT isActiveChanged();
141+ }
142+}
143+
131void Scope::setNoResultsHint(const QString& str) {
144void Scope::setNoResultsHint(const QString& str) {
132 if (str != m_noResultsHint) {
145 if (str != m_noResultsHint) {
133 m_noResultsHint = str;
146 m_noResultsHint = str;
tests/mocks/Unity/fake_scope.h+5
@@ -41,6 +41,7 @@ class Scope : public QObject
41 Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
41 Q_PROPERTY(QString searchQuery READ searchQuery WRITE setSearchQuery NOTIFY searchQueryChanged)
42 Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
42 Q_PROPERTY(QString noResultsHint READ noResultsHint WRITE setNoResultsHint NOTIFY noResultsHintChanged)
43 Q_PROPERTY(QString formFactor READ formFactor WRITE setFormFactor NOTIFY formFactorChanged)
43 Q_PROPERTY(QString formFactor READ formFactor WRITE setFormFactor NOTIFY formFactorChanged)
44+ Q_PROPERTY(bool isActive READ isActive WRITE setActive NOTIFY isActiveChanged)
44
45
45public:
46public:
46 Scope(QObject* parent = 0);
47 Scope(QObject* parent = 0);
@@ -60,12 +61,14 @@ public:
60 QString searchQuery() const;
61 QString searchQuery() const;
61 QString noResultsHint() const;
62 QString noResultsHint() const;
62 QString formFactor() const;
63 QString formFactor() const;
64+ bool isActive() const;
63
65
64 /* setters */
66 /* setters */
65 void setName(const QString& name);
67 void setName(const QString& name);
66 void setSearchQuery(const QString& search_query);
68 void setSearchQuery(const QString& search_query);
67 void setNoResultsHint(const QString& hint);
69 void setNoResultsHint(const QString& hint);
68 void setFormFactor(const QString& form_factor);
70 void setFormFactor(const QString& form_factor);
71+ void setActive(const bool);
69
72
70 Q_INVOKABLE void activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
73 Q_INVOKABLE void activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
71 const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
74 const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
@@ -88,6 +91,7 @@ Q_SIGNALS:
88 void searchQueryChanged();
91 void searchQueryChanged();
89 void noResultsHintChanged();
92 void noResultsHintChanged();
90 void formFactorChanged();
93 void formFactorChanged();
94+ void isActiveChanged();
91
95
92 // signals triggered by activate(..) or preview(..) requests.
96 // signals triggered by activate(..) or preview(..) requests.
93 void previewReady(Preview *preview);
97 void previewReady(Preview *preview);
@@ -104,6 +108,7 @@ protected:
104 QString m_formFactor;
108 QString m_formFactor;
105 bool m_visible;
109 bool m_visible;
106 bool m_searching;
110 bool m_searching;
111+ bool m_isActive;
107
112
108 Categories* m_categories;
113 Categories* m_categories;
109 DeeListModel* m_results;
114 DeeListModel* m_results;
tests/qmltests/CMakeLists.txt+1−1
@@ -43,7 +43,7 @@ add_qml_test(Components Tile)
43add_qml_test(Components PageHeader)
43add_qml_test(Components PageHeader)
44add_qml_test(Dash Dash IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
44add_qml_test(Dash Dash IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
45add_qml_test(Dash DashBar IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
45add_qml_test(Dash DashBar IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
46−add_qml_test(Dash DashContent IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS})
46+add_qml_test(Dash DashContent IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
47add_qml_test(Dash DashPreview)
47add_qml_test(Dash DashPreview)
48add_qml_test(Dash GenericScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
48add_qml_test(Dash GenericScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
49add_qml_test(Dash ScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
49add_qml_test(Dash ScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
tests/qmltests/Dash/qml/FakeScopeView.qml+3−9
@@ -17,16 +17,10 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Unity 0.1
18import Unity 0.1
19
19
20−FocusScope {
20+import "../../../../Dash"
21− id: fakeScopeView
22− property Scope scope : null
23− property bool isCurrent : false
24−
25− property ListModel searchHistory
26
21
27− signal endReached
22+ScopeView {
28− signal movementStarted
23+ id: fakeScopeView
29− signal positionedAtBeginning
30
24
31 property alias backColor : back.color
25 property alias backColor : back.color
32
26
tests/qmltests/Dash/tst_DashContent.qml+29−5
@@ -101,17 +101,21 @@ Item {
101 when: windowShown
101 when: windowShown
102
102
103 function init() {
103 function init() {
104+ scopesModel.load();
105+ }
106+
107+ function cleanup() {
104 scopeLoadedSpy.clear();
108 scopeLoadedSpy.clear();
105 movementStartedSpy.clear();
109 movementStartedSpy.clear();
106− contentEndReachedSpy.clear()
110+ contentEndReachedSpy.clear();
107 clear_scope_status();
111 clear_scope_status();
112+ dashContent.visible = true;
108
113
109− // clear, wait for dash to empty and load scopes.
110− var dashContentList = findChild(dashContent, "dashContentList");
111− verify(dashContentList != undefined)
112 scopesModel.clear();
114 scopesModel.clear();
115+ // wait for dash to empty scopes.
116+ var dashContentList = findChild(dashContent, "dashContentList");
117+ verify(dashContentList != undefined);
113 tryCompare(dashContentList, "count", 0);
118 tryCompare(dashContentList, "count", 0);
114− scopesModel.load();
115 }
119 }
116
120
117 function test_movement_started_signal() {
121 function test_movement_started_signal() {
@@ -205,5 +209,25 @@ Item {
205 tryCompareFunction(get_current_item_object_name, data.objectName)
209 tryCompareFunction(get_current_item_object_name, data.objectName)
206 }
210 }
207
211
212+ function test_is_active_data() {
213+ return [
214+ {tag: "select 0", select: 0, visible: true, active0: true, active1: false, active2: false, active3: false},
215+ {tag: "select 2", select: 2, visible: true, active0: false, active1: false, active2: true, active3: false},
216+ {tag: "invisible", select: 0, visible: false, active0: false, active1: false, active2: false, active3: false},
217+ ]
218+ }
219+
220+ function test_is_active(data) {
221+ var dashContentList = findChild(dashContent, "dashContentList");
222+
223+ tryCompare(scopeLoadedSpy, "count", 5);
224+
225+ dashContent.setCurrentScopeAtIndex(data.select, true, false);
226+ dashContent.visible = data.visible;
227+
228+ tryCompare(scopesModel.get(0), "isActive", data.active0);
229+ tryCompare(scopesModel.get(1), "isActive", data.active1);
230+ tryCompare(scopesModel.get(2), "isActive", data.active2);
231+ }
208 }
232 }
209}
233}
tests/qmltests/tst_Shell.qml+50
@@ -70,6 +70,8 @@ Item {
70
70
71 var dashHome = findChild(shell, "DashHome");
71 var dashHome = findChild(shell, "DashHome");
72 swipeUntilScopeViewIsReached(dashHome);
72 swipeUntilScopeViewIsReached(dashHome);
73+
74+ hideIndicators();
73 }
75 }
74
76
75 function killApps(apps) {
77 function killApps(apps) {
@@ -268,6 +270,19 @@ Item {
268 mouseClick(appIcon, appIcon.width / 2, appIcon.height / 2);
270 mouseClick(appIcon, appIcon.width / 2, appIcon.height / 2);
269 }
271 }
270
272
273+ function showIndicators() {
274+ var indicators = findChild(shell, "indicators");
275+ indicators.show();
276+ tryCompare(indicators, "fullyOpened", true);
277+ }
278+
279+ function hideIndicators() {
280+ var indicators = findChild(shell, "indicators");
281+ if (indicators.fullyOpened) {
282+ indicators.hide();
283+ }
284+ }
285+
271 function waitUntilApplicationWindowIsFullyVisible() {
286 function waitUntilApplicationWindowIsFullyVisible() {
272 var underlay = findChild(shell, "underlay");
287 var underlay = findChild(shell, "underlay");
273 tryCompare(underlay, "visible", false);
288 tryCompare(underlay, "visible", false);
@@ -360,5 +375,40 @@ Item {
360 tryCompareFunction(function() { return backgroundImage.source.toString().indexOf(data.expectedUrl) !== -1; }, true)
375 tryCompareFunction(function() { return backgroundImage.source.toString().indexOf(data.expectedUrl) !== -1; }, true)
361 tryCompare(backgroundImage, "status", Image.Ready)
376 tryCompare(backgroundImage, "status", Image.Ready)
362 }
377 }
378+
379+ function test_DashShown_data() {
380+ return [
381+ {tag: "in focus", greeter: false, app: false, launcher: false, indicators: false, expectedShown: true},
382+ {tag: "under greeter", greeter: true, app: false, launcher: false, indicators: false, expectedShown: false},
383+ {tag: "under app", greeter: false, app: true, launcher: false, indicators: false, expectedShown: false},
384+ {tag: "under launcher", greeter: false, app: false, launcher: true, indicators: false, expectedShown: true},
385+ {tag: "under indicators", greeter: false, app: false, launcher: false, indicators: true, expectedShown: true},
386+ ]
387+ }
388+
389+ function test_DashShown(data) {
390+ if (data.greeter) {
391+ // Swipe the greeter in
392+ var greeter = findChild(shell, "greeter");
393+ Powerd.displayPowerStateChange(Powerd.Off, 0);
394+ tryCompare(greeter, "showProgress", 1);
395+ }
396+
397+ if (data.app) {
398+ dragLauncherIntoView();
399+ tapOnAppIconInLauncher();
400+ }
401+
402+ if (data.launcher) {
403+ dragLauncherIntoView();
404+ }
405+
406+ if (data.indicators) {
407+ showIndicators();
408+ }
409+
410+ var dash = findChild(shell, "dash");
411+ tryCompare(dash, "shown", data.expectedShown);
412+ }
363 }
413 }
364}
414}