on xenial help sign in
merge version bump
9fc16bbMichał Sawicz
Bottombar/Bottombar.qml+81−16
@@ -34,15 +34,32 @@ Item {
34
34
35 state: "hidden"
35 state: "hidden"
36
36
37+ function hide() {
38+ dismissTimer.stop()
39+ bottombar.state = "hidden"
40+ }
41+
42+ onApplicationIsOnForegroundChanged: {
43+ if (!applicationIsOnForeground) {
44+ hide()
45+ }
46+ }
47+
37 onStateChanged: {
48 onStateChanged: {
38 if (state == "hidden") {
49 if (state == "hidden") {
39 dismissTimer.stop()
50 dismissTimer.stop()
51+ bottomBarVisibilityCommunicatorShell.forceHidden = false
40 } else {
52 } else {
41 dismissTimer.restart()
53 dismissTimer.restart()
42 }
54 }
43 }
55 }
44
56
45 onPreventHidingChanged: {
57 onPreventHidingChanged: {
58+ if (!preventHiding) {
59+ if (state == "hint" || state == "reveal")
60+ hide()
61+ }
62+
46 if (dismissTimer.running) {
63 if (dismissTimer.running) {
47 dismissTimer.restart();
64 dismissTimer.restart();
48 }
65 }
@@ -50,7 +67,7 @@ Item {
50
67
51 Timer {
68 Timer {
52 id: dismissTimer
69 id: dismissTimer
53− interval: 5000
70+ interval: 1000
54 onTriggered: {
71 onTriggered: {
55 if (!bottombar.preventHiding) {
72 if (!bottombar.preventHiding) {
56 bottombar.state = "hidden"
73 bottombar.state = "hidden"
@@ -103,24 +120,29 @@ Item {
103
120
104 EdgeDragArea {
121 EdgeDragArea {
105 id: dragArea
122 id: dragArea
123+ objectName: "hudDragArea"
106 width: parent.width
124 width: parent.width
107 height: distanceThreshold
125 height: distanceThreshold
108 anchors.bottom: parent.bottom
126 anchors.bottom: parent.bottom
109
127
110− distanceThreshold: units.gu(1)
128+ distanceThreshold: units.gu(8)
111 enabled: !theHud.shown && bottombar.enabled && applicationIsOnForeground
129 enabled: !theHud.shown && bottombar.enabled && applicationIsOnForeground
112 direction: Direction.Upwards
130 direction: Direction.Upwards
131+ maxSilenceTime: 2000
113
132
114 property int previousStatus: -1
133 property int previousStatus: -1
115 property real touchStartX: -1
134 property real touchStartX: -1
116
135
136+ readonly property real distanceFromThreshold: (-distance) - distanceThreshold // distance is negative
137+ readonly property real revealDistance: units.gu(2)
138+ readonly property real commitDistance: units.gu(6)
139+ readonly property real commitProgress: MathLocal.clamp(distanceFromThreshold / commitDistance, 0, 1)
140+
117 onStatusChanged: {
141 onStatusChanged: {
118 if (status === DirectionalDragArea.WaitingForTouch) {
142 if (status === DirectionalDragArea.WaitingForTouch) {
119 if (previousStatus == DirectionalDragArea.Recognized) {
143 if (previousStatus == DirectionalDragArea.Recognized) {
120 if (hudButton.mouseOver) {
144 if (hudButton.mouseOver) {
121 hudButton.clicked()
145 hudButton.clicked()
122− } else {
123− bottombar.state = "hidden"
124 }
146 }
125 }
147 }
126 } else if (status === DirectionalDragArea.Undecided) {
148 } else if (status === DirectionalDragArea.Undecided) {
@@ -128,35 +150,78 @@ Item {
128 touchStartX = touchX
150 touchStartX = touchX
129 }
151 }
130 } else if (status === DirectionalDragArea.Recognized) {
152 } else if (status === DirectionalDragArea.Recognized) {
131− bottombar.state = "shown"
153+ bottombar.state = "hint"
132 }
154 }
133 previousStatus = status
155 previousStatus = status
134 }
156 }
157+
158+ onDistanceChanged: {
159+ if (status === DirectionalDragArea.Recognized) {
160+ if (distanceFromThreshold > commitDistance)
161+ bottombar.state = "shown"
162+ else if (distanceFromThreshold > revealDistance)
163+ bottombar.state = "reveal"
164+ }
165+ }
166+ }
167+
168+ Item {
169+ id: dismissArea
170+ anchors {
171+ top: parent.top
172+ left: parent.left
173+ right: parent.right
174+ }
175+ height: parent.height - bottomBarVisibilityCommunicatorShell.position
176+
177+ MouseArea {
178+ anchors.fill: parent
179+ enabled: bottombar.state == "shown"
180+ onPressed: {
181+ bottomBarVisibilityCommunicatorShell.forceHidden = true
182+ bottombar.state = "hidden"
183+ }
184+ }
185+
186+ InputFilterArea {
187+ anchors.fill: parent
188+ blockInput: (hudButton.opacity == 1)
189+ }
135 }
190 }
136
191
137 MouseArea {
192 MouseArea {
138− anchors.fill: parent
193+ anchors {
194+ top: dismissArea.bottom
195+ left: parent.left
196+ right: parent.right
197+ bottom: parent.bottom
198+ }
139− enabled: bottombar.state == "shown"
199+ enabled: bottombar.state == "shown" && bottomBarVisibilityCommunicatorShell.position > 0
140 onPressed: {
200 onPressed: {
141 bottombar.state = "hidden"
201 bottombar.state = "hidden"
142 }
202 }
143 }
203 }
144
204
145− InputFilterArea {
146− anchors.fill: parent
147− blockInput: (hudButton.opacity == 1)
148− }
149−
150 states: [
205 states: [
151 State {
206 State {
152 name: "hidden"
207 name: "hidden"
153− PropertyChanges { target: hudButton; opacity: 0}
208+ PropertyChanges { target: hudButton; opacity: 0 }
154− PropertyChanges { target: hudButton; bottomMargin: units.gu(-1)}
209+ PropertyChanges { target: hudButton; bottomMargin: units.gu(-2) }
210+ },
211+ State {
212+ name: "hint"
213+ extend: "hidden"
214+ PropertyChanges { target: hudButton; opacity: 0.5 }
215+ },
216+ State {
217+ name: "reveal"
218+ extend: "hint"
219+ PropertyChanges { target: hudButton; bottomMargin: units.gu(-2) + units.gu(2) * dragArea.commitProgress }
155 },
220 },
156 State {
221 State {
157 name: "shown"
222 name: "shown"
158− PropertyChanges { target: hudButton; opacity: 1}
223+ PropertyChanges { target: hudButton; opacity: 1 }
159− PropertyChanges { target: hudButton; bottomMargin: units.gu(0)}
224+ PropertyChanges { target: hudButton; bottomMargin: units.gu(0) }
160 }
225 }
161 ]
226 ]
162}
227}
Dash/Apps/RunningApplicationsGrid.qml+17−2
@@ -22,6 +22,8 @@ ResponsiveFlowView {
22 clip: true
22 clip: true
23
23
24 signal updateScreenshots
24 signal updateScreenshots
25+ property alias enableHeightBehavior: heightBehaviour.enabled
26+ property bool enableHeightBehaviorOnNextCreation: firstModel.count + secondModel.count == 0
25
27
26 Connections {
28 Connections {
27 target: shell
29 target: shell
@@ -30,11 +32,24 @@ ResponsiveFlowView {
30 }
32 }
31
33
32 Behavior on height {
34 Behavior on height {
33− // FIXME Rethink how we pass down properties from the LVWPH to the interested parties
35+ id: heightBehaviour
34− enabled: culled === undefined || !culled;
36+ enabled: false
35 NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
37 NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
36 }
38 }
37
39
40+ Connections {
41+ target: root.firstModel
42+ onCountChanged: {
43+ heightBehaviour.enabled = true;
44+ }
45+ }
46+ Connections {
47+ target: root.secondModel
48+ onCountChanged: {
49+ heightBehaviour.enabled = true;
50+ }
51+ }
52+
38 property bool canEnableTerminationMode: true
53 property bool canEnableTerminationMode: true
39
54
40 onCanEnableTerminationModeChanged: {
55 onCanEnableTerminationModeChanged: {
Dash/DashApps.qml+1
@@ -52,5 +52,6 @@ GenericScopeView {
52
52
53 onScopeChanged: {
53 onScopeChanged: {
54 scopeView.scope.categories.overrideResults("recent", runningApplicationsModel);
54 scopeView.scope.categories.overrideResults("recent", runningApplicationsModel);
55+ enableHeightBehaviorOnNextCreation = (mainStageApplicationsModel.count + sideStageApplicationModel.count == 0)
55 }
56 }
56}
57}
Dash/GenericScopeView.qml+11
@@ -22,6 +22,7 @@ import "../Components/ListItems" as ListItems
22ScopeView {
22ScopeView {
23 id: scopeView
23 id: scopeView
24 readonly property alias previewShown: previewLoader.onScreen
24 readonly property alias previewShown: previewLoader.onScreen
25+ property bool enableHeightBehaviorOnNextCreation: false
25
26
26 onIsCurrentChanged: {
27 onIsCurrentChanged: {
27 pageHeader.resetSearch();
28 pageHeader.resetSearch();
@@ -88,6 +89,10 @@ ScopeView {
88 source: getRenderer(model.renderer, model.contentType)
89 source: getRenderer(model.renderer, model.contentType)
89
90
90 onLoaded: {
91 onLoaded: {
92+ if (item.enableHeightBehavior !== undefined && item.enableHeightBehaviorOnNextCreation !== undefined) {
93+ item.enableHeightBehavior = scopeView.enableHeightBehaviorOnNextCreation;
94+ scopeView.enableHeightBehaviorOnNextCreation = false;
95+ }
91 if (source.toString().indexOf("Apps/RunningApplicationsGrid.qml") != -1) {
96 if (source.toString().indexOf("Apps/RunningApplicationsGrid.qml") != -1) {
92 // TODO: the running apps grid doesn't support standard scope results model yet
97 // TODO: the running apps grid doesn't support standard scope results model yet
93 item.firstModel = Qt.binding(function() { return results.firstModel })
98 item.firstModel = Qt.binding(function() { return results.firstModel })
@@ -104,6 +109,12 @@ ScopeView {
104 }
109 }
105 }
110 }
106
111
112+ Component.onDestruction: {
113+ if (item.enableHeightBehavior !== undefined && item.enableHeightBehaviorOnNextCreation !== undefined) {
114+ scopeView.enableHeightBehaviorOnNextCreation = item.enableHeightBehaviorOnNextCreation;
115+ }
116+ }
117+
107 Connections {
118 Connections {
108 target: rendererLoader.item
119 target: rendererLoader.item
109 onClicked: {
120 onClicked: {
Shell.qml+2
@@ -623,6 +623,7 @@ FocusScope {
623 }
623 }
624
624
625 Bottombar {
625 Bottombar {
626+ id: bottombar
626 theHud: hud
627 theHud: hud
627 anchors.fill: parent
628 anchors.fill: parent
628 enabled: hud.available
629 enabled: hud.available
@@ -663,6 +664,7 @@ FocusScope {
663 if (shown) {
664 if (shown) {
664 panel.indicators.hide()
665 panel.indicators.hide()
665 hud.hide()
666 hud.hide()
667+ bottombar.hide()
666 }
668 }
667 }
669 }
668 }
670 }
debian/changelog+6
@@ -1,3 +1,9 @@
1+unity8 (7.82) UNRELEASED; urgency=low
2+
3+ * Bump to indicate support for extended snap decisions.
4+
5+ -- Michał Sawicz <michal.sawicz@canonical.com> Thu, 03 Oct 2013 14:20:23 +0200
6+
1unity8 (7.81.3+13.10.20130927.3-0ubuntu1) saucy; urgency=low
7unity8 (7.81.3+13.10.20130927.3-0ubuntu1) saucy; urgency=low
2
8
3 [ Michal Hruby ]
9 [ Michal Hruby ]
debian/control+1−1
@@ -72,7 +72,7 @@ Depends: gsettings-desktop-schemas,
72 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
72 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
73 qtdeclarative5-xmllistmodel-plugin,
73 qtdeclarative5-xmllistmodel-plugin,
74 unity-launcher-impl-3,
74 unity-launcher-impl-3,
75− unity-notifications-impl-1,
75+ unity-notifications-impl-2,
76 unity8-fake-env | qtubuntu-shell,
76 unity8-fake-env | qtubuntu-shell,
77 unity8-private (= ${binary:Version}),
77 unity8-private (= ${binary:Version}),
78 unity8-private | unity-launcher-impl,
78 unity8-private | unity-launcher-impl,
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp−4
@@ -139,9 +139,6 @@ void ListViewWithPageHeader::ListItem::setCulled(bool culled)
139 QQuickItemPrivate::get(m_item)->setCulled(culled);
139 QQuickItemPrivate::get(m_item)->setCulled(culled);
140 if (m_sectionItem)
140 if (m_sectionItem)
141 QQuickItemPrivate::get(m_sectionItem)->setCulled(culled);
141 QQuickItemPrivate::get(m_sectionItem)->setCulled(culled);
142−
143− QQmlContext *itemContext = QQmlEngine::contextForObject(m_item)->parentContext();
144− itemContext->setContextProperty(QLatin1String("culled"), QVariant::fromValue<bool>(culled));
145}
142}
146
143
147ListViewWithPageHeader::ListViewWithPageHeader()
144ListViewWithPageHeader::ListViewWithPageHeader()
@@ -855,7 +852,6 @@ void ListViewWithPageHeader::itemCreated(int modelIndex, QObject *object)
855 QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext();
852 QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext();
856 context->setContextProperty(QLatin1String("ListViewWithPageHeader"), this);
853 context->setContextProperty(QLatin1String("ListViewWithPageHeader"), this);
857 context->setContextProperty(QLatin1String("heightToClip"), QVariant::fromValue<int>(0));
854 context->setContextProperty(QLatin1String("heightToClip"), QVariant::fromValue<int>(0));
858− context->setContextProperty(QLatin1String("culled"), QVariant::fromValue<bool>(false));
859 if (modelIndex == m_asyncRequestedIndex) {
855 if (modelIndex == m_asyncRequestedIndex) {
860 createItem(modelIndex, false);
856 createItem(modelIndex, false);
861 refill();
857 refill();
plugins/Unity/Indicators/qml/SliderMenuItem.qml+1−1
@@ -71,7 +71,7 @@ FramedMenuItem {
71 leftMargin: leftImage.visible ? units.gu(0.5) : 0
71 leftMargin: leftImage.visible ? units.gu(0.5) : 0
72 rightMargin: rightImage.visible ? units.gu(0.5) : 0
72 rightMargin: rightImage.visible ? units.gu(0.5) : 0
73 }
73 }
74− live: false
74+ live: true
75
75
76 Component.onCompleted: {
76 Component.onCompleted: {
77 value = menuItem.value
77 value = menuItem.value
plugins/Unity/bottombarvisibilitycommunicatorshell.cpp+15−1
@@ -17,7 +17,8 @@
17#include "bottombarvisibilitycommunicatorshell.h"
17#include "bottombarvisibilitycommunicatorshell.h"
18
18
19BottomBarVisibilityCommunicatorShell::BottomBarVisibilityCommunicatorShell()
19BottomBarVisibilityCommunicatorShell::BottomBarVisibilityCommunicatorShell()
20− : m_forceHidden(false)
20+ : m_forceHidden(false),
21+ m_position(0)
21{
22{
22}
23}
23
24
@@ -26,6 +27,11 @@ bool BottomBarVisibilityCommunicatorShell::forceHidden() const
26 return m_forceHidden;
27 return m_forceHidden;
27}
28}
28
29
30+double BottomBarVisibilityCommunicatorShell::position() const
31+{
32+ return m_position;
33+}
34+
29void BottomBarVisibilityCommunicatorShell::setForceHidden(bool forceHidden)
35void BottomBarVisibilityCommunicatorShell::setForceHidden(bool forceHidden)
30{
36{
31 if (forceHidden != m_forceHidden) {
37 if (forceHidden != m_forceHidden) {
@@ -33,3 +39,11 @@ void BottomBarVisibilityCommunicatorShell::setForceHidden(bool forceHidden)
33 Q_EMIT forceHiddenChanged(forceHidden);
39 Q_EMIT forceHiddenChanged(forceHidden);
34 }
40 }
35}
41}
42+
43+void BottomBarVisibilityCommunicatorShell::setPosition(double position)
44+{
45+ if (position != m_position) {
46+ m_position = position;
47+ Q_EMIT positionChanged(position);
48+ }
49+}
plugins/Unity/bottombarvisibilitycommunicatorshell.h+6
@@ -30,6 +30,7 @@ class BottomBarVisibilityCommunicatorShell : public QObject
30{
30{
31 Q_OBJECT
31 Q_OBJECT
32 Q_PROPERTY(bool forceHidden READ forceHidden WRITE setForceHidden NOTIFY forceHiddenChanged)
32 Q_PROPERTY(bool forceHidden READ forceHidden WRITE setForceHidden NOTIFY forceHiddenChanged)
33+ Q_PROPERTY(double position READ position WRITE setPosition NOTIFY positionChanged)
33
34
34 Q_CLASSINFO("D-Bus Interface", "com.canonical.Shell.BottomBarVisibilityCommunicator")
35 Q_CLASSINFO("D-Bus Interface", "com.canonical.Shell.BottomBarVisibilityCommunicator")
35public:
36public:
@@ -41,13 +42,18 @@ public:
41 bool forceHidden() const;
42 bool forceHidden() const;
42 void setForceHidden(bool forceHidden);
43 void setForceHidden(bool forceHidden);
43
44
45+ double position() const;
46+ void setPosition(double position);
47+
44Q_SIGNALS:
48Q_SIGNALS:
45 void forceHiddenChanged(bool forceHidden);
49 void forceHiddenChanged(bool forceHidden);
50+ void positionChanged(double position);
46
51
47private:
52private:
48 BottomBarVisibilityCommunicatorShell();
53 BottomBarVisibilityCommunicatorShell();
49
54
50 bool m_forceHidden;
55 bool m_forceHidden;
56+ double m_position;
51};
57};
52
58
53#endif
59#endif
tests/autopilot/unity8/shell/__init__.py+14
@@ -19,6 +19,7 @@
19
19
20"""unity shell autopilot tests and emulators - sub level package."""
20"""unity shell autopilot tests and emulators - sub level package."""
21
21
22+from time import sleep
22from functools import wraps
23from functools import wraps
23import logging
24import logging
24
25
@@ -46,3 +47,16 @@ def disable_qml_mocking(fn):
46 tests_self._qml_mock_enabled = False
47 tests_self._qml_mock_enabled = False
47 return fn(*args, **kwargs)
48 return fn(*args, **kwargs)
48 return wrapper
49 return wrapper
50+
51+class DragMixin(object):
52+ def _drag(self, x1, y1, x2, y2):
53+ cur_x = x1
54+ cur_y = y1
55+ dx = 1.0 * (x2 - x1) / 100
56+ dy = 1.0 * (y2 - y1) / 100
57+ for i in range(0, 100):
58+ self.touch._finger_move(int(cur_x), int(cur_y))
59+ sleep(0.002)
60+ cur_x += dx
61+ cur_y += dy
62+ self.touch._finger_move(int(x2), int(y2))
tests/autopilot/unity8/shell/emulators/dash.py+15−6
@@ -18,17 +18,22 @@
18#
18#
19
19
20from unity8.shell.emulators import UnityEmulatorBase
20from unity8.shell.emulators import UnityEmulatorBase
21−
21+from time import sleep
22
22
23class Dash(UnityEmulatorBase):
23class Dash(UnityEmulatorBase):
24
24
25 """An emulator that understands the Dash."""
25 """An emulator that understands the Dash."""
26
26
27 def get_home_applications_grid(self):
27 def get_home_applications_grid(self):
28+ for i in range(1,10):
28− return self.get_scope('home').select_single(
29+ get_grid = self.get_scope('home').select_single(
29− "GenericFilterGrid",
30+ "GenericFilterGrid",
30− objectName="applications.scope"
31+ objectName="applications.scope"
31− )
32+ )
33+ if get_grid != None:
34+ break
35+ sleep(1)
36+ return get_grid
32
37
33 def get_application_icon(self, text):
38 def get_application_icon(self, text):
34 """Returns a 'Tile' icon that has the text 'text' from the application
39 """Returns a 'Tile' icon that has the text 'text' from the application
@@ -40,7 +45,11 @@ class Dash(UnityEmulatorBase):
40
45
41 """
46 """
42 app_grid = self.get_home_applications_grid()
47 app_grid = self.get_home_applications_grid()
48+ for i in range(1,10):
43− resp_grid = app_grid.select_single('ResponsiveGridView')
49+ resp_grid = app_grid.select_single('ResponsiveGridView')
50+ if resp_grid != None:
51+ break
52+ sleep(1)
44 return resp_grid.select_single('Tile', text=text)
53 return resp_grid.select_single('Tile', text=text)
45
54
46 def get_scope(self, scope_name='home'):
55 def get_scope(self, scope_name='home'):
tests/autopilot/unity8/shell/emulators/hud.py+8−9
@@ -21,36 +21,35 @@ from collections import namedtuple
21
21
22from unity8 import get_grid_size
22from unity8 import get_grid_size
23from unity8.shell.emulators import UnityEmulatorBase
23from unity8.shell.emulators import UnityEmulatorBase
24+from unity8.shell import DragMixin
24from autopilot.input import Touch
25from autopilot.input import Touch
25
26
26−
27SwipeCoords = namedtuple('SwipeCoords', 'start_x end_x start_y end_y')
27SwipeCoords = namedtuple('SwipeCoords', 'start_x end_x start_y end_y')
28
28
29−
30−class Hud(UnityEmulatorBase):
29+class Hud(UnityEmulatorBase, DragMixin):
31
30
32 """An emulator that understands the Hud."""
31 """An emulator that understands the Hud."""
33
32
34 def show(self):
33 def show(self):
35 """Swipes open the Hud."""
34 """Swipes open the Hud."""
36− touch = Touch.create()
35+ self.touch = Touch.create()
37
36
38 window = self.get_root_instance().select_single('QQuickView')
37 window = self.get_root_instance().select_single('QQuickView')
39 hud_show_button = window.select_single("HudButton")
38 hud_show_button = window.select_single("HudButton")
40
39
41 swipe_coords = self.get_button_swipe_coords(window, hud_show_button)
40 swipe_coords = self.get_button_swipe_coords(window, hud_show_button)
42
41
43− touch.press(swipe_coords.start_x, swipe_coords.start_y)
42+ self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
44− touch._finger_move(swipe_coords.end_x, swipe_coords.end_y)
43+ self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y)
45 try:
44 try:
46 hud_show_button.opacity.wait_for(1.0)
45 hud_show_button.opacity.wait_for(1.0)
47− touch.release()
46+ self.touch.release()
48 self.shown.wait_for(True)
47 self.shown.wait_for(True)
49 except AssertionError:
48 except AssertionError:
50 raise
49 raise
51 finally:
50 finally:
52− if touch._touch_finger is not None:
51+ if self.touch._touch_finger is not None:
53− touch.release()
52+ self.touch.release()
54
53
55 def dismiss(self):
54 def dismiss(self):
56 """Closes the open Hud."""
55 """Closes the open Hud."""
tests/autopilot/unity8/shell/emulators/main_window.py+3
@@ -58,6 +58,9 @@ class MainWindow(object):
58 def get_hud_show_button(self):
58 def get_hud_show_button(self):
59 return self.app.select_single("HudButton")
59 return self.app.select_single("HudButton")
60
60
61+ def get_hud_edge_drag_area(self):
62+ return self.app.select_single(objectName="hudDragArea")
63+
61 def get_dash(self):
64 def get_dash(self):
62 return self.app.select_single(Dash)
65 return self.app.select_single(Dash)
63
66
tests/autopilot/unity8/shell/tests/test_hud.py+43−9
@@ -19,29 +19,30 @@
19
19
20from __future__ import absolute_import
20from __future__ import absolute_import
21
21
22−from unity8.shell import with_lightdm_mock
22+from unity8.shell import with_lightdm_mock, DragMixin
23from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
23from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
24
24
25from testtools.matchers import Equals
25from testtools.matchers import Equals
26from autopilot.matchers import Eventually
26from autopilot.matchers import Eventually
27
27
28−
29−class TestHud(UnityTestCase):
28+class TestHud(UnityTestCase, DragMixin):
30
29
31 """Tests the Shell HUD."""
30 """Tests the Shell HUD."""
32
31
33 scenarios = _get_device_emulation_scenarios()
32 scenarios = _get_device_emulation_scenarios()
34
33
35 def test_show_hud_button_appears(self):
34 def test_show_hud_button_appears(self):
36− """Swiping up while an app is active must show the 'show hud' button.
35+ """Swiping up while an app is active must show the 'show hud' button, following some behaviours.
37 The button must disappear not opening the HUD when releasing the
36 The button must disappear not opening the HUD when releasing the
38− mouse again somewhere on the screen except on the button itself.
37+ mouse again somewhere on the screen except on the button itself following a timeout.
38+ The button must disappear when touching somewhere on the screen except the button itself.
39
39
40 """
40 """
41 self.launch_unity()
41 self.launch_unity()
42 self.main_window.get_greeter().swipe()
42 self.main_window.get_greeter().swipe()
43 window = self.main_window.get_qml_view()
43 window = self.main_window.get_qml_view()
44 hud_show_button = self.main_window.get_hud_show_button()
44 hud_show_button = self.main_window.get_hud_show_button()
45+ edge_drag_area = self.main_window.get_hud_edge_drag_area()
45 hud = self.main_window.get_hud()
46 hud = self.main_window.get_hud()
46
47
47 self._launch_test_app_from_app_screen()
48 self._launch_test_app_from_app_screen()
@@ -50,16 +51,33 @@ class TestHud(UnityTestCase):
50 window,
51 window,
51 hud_show_button
52 hud_show_button
52 )
53 )
54+ initialBottomMargin = int(hud_show_button.bottomMargin)
55+
53 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
56 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
54 self.addCleanup(self._maybe_release_finger)
57 self.addCleanup(self._maybe_release_finger)
55− self.touch._finger_move(swipe_coords.end_x, swipe_coords.end_y + hud_show_button.height);
58+ self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - 5)
59+ self.assertThat(hud_show_button.opacity, Eventually(Equals(0.5)))
60+ self.assertThat(hud_show_button.bottomMargin, Eventually(Equals(initialBottomMargin)))
61+ self._drag(swipe_coords.start_x, swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - 5, swipe_coords.end_x, swipe_coords.start_y - int(edge_drag_area.distanceThreshold) - int(edge_drag_area.commitDistance) - 5)
56 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
62 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
63+ self.assertThat(hud_show_button.bottomMargin, Eventually(Equals(0.0)))
57 self.touch.release();
64 self.touch.release();
65+ self.assertThat(hud.shown, Equals(False))
58 self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
66 self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
67+
68+ self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
69+ self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y - int(hud_show_button.height))
70+ self.assertThat(hud.shown, Equals(False))
71+ self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
72+ self.touch.release()
73+ self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
74+ self.touch.tap(swipe_coords.end_x, swipe_coords.end_y - int(hud_show_button.height))
59 self.assertThat(hud.shown, Equals(False))
75 self.assertThat(hud.shown, Equals(False))
76+ self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
60
77
61 def test_show_hud_appears(self):
78 def test_show_hud_appears(self):
62 """Releasing the touch on the 'show hud' button must display the hud.
79 """Releasing the touch on the 'show hud' button must display the hud.
80+ Test that the hud button stays on screen and tapping it opens the hud.
63
81
64 """
82 """
65 self.launch_unity()
83 self.launch_unity()
@@ -74,14 +92,28 @@ class TestHud(UnityTestCase):
74 window,
92 window,
75 hud_show_button
93 hud_show_button
76 )
94 )
95+
77 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
96 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
78 self.addCleanup(self._maybe_release_finger)
97 self.addCleanup(self._maybe_release_finger)
79− self.touch._finger_move(swipe_coords.end_x, swipe_coords.end_y)
98+ self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y)
80−
99+ self.assertThat(hud.shown, Eventually(Equals(False)))
100+ self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
101+ self.touch.release()
102+ self.assertThat(hud.shown, Eventually(Equals(True)))
103+ self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
104+ x, y = hud.get_close_button_coords()
105+ self.touch.tap(x, y)
81 self.assertThat(hud.shown, Eventually(Equals(False)))
106 self.assertThat(hud.shown, Eventually(Equals(False)))
107+
108+ self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
109+ self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y - int(hud_show_button.height))
110+ self.assertThat(hud.shown, Equals(False))
82 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
111 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
83 self.touch.release()
112 self.touch.release()
113+ self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
114+ self.touch.tap(swipe_coords.end_x, swipe_coords.end_y)
84 self.assertThat(hud.shown, Eventually(Equals(True)))
115 self.assertThat(hud.shown, Eventually(Equals(True)))
116+ self.assertThat(hud_show_button.opacity, Eventually(Equals(0.0)))
85
117
86 def test_hide_hud_click(self):
118 def test_hide_hud_click(self):
87 """Tapping the close button of the Hud must dismiss it."""
119 """Tapping the close button of the Hud must dismiss it."""
@@ -90,6 +122,7 @@ class TestHud(UnityTestCase):
90 hud = self.main_window.get_hud()
122 hud = self.main_window.get_hud()
91
123
92 self._launch_test_app_from_app_screen()
124 self._launch_test_app_from_app_screen()
125+
93 hud.show()
126 hud.show()
94
127
95 x, y = hud.get_close_button_coords()
128 x, y = hud.get_close_button_coords()
@@ -103,10 +136,11 @@ class TestHud(UnityTestCase):
103 """
136 """
104 self.launch_unity()
137 self.launch_unity()
105 self.main_window.get_greeter().swipe()
138 self.main_window.get_greeter().swipe()
106− hud = self.main_window.get_hud()
107 window = self.main_window.get_qml_view()
139 window = self.main_window.get_qml_view()
140+ hud = self.main_window.get_hud()
108
141
109 self._launch_test_app_from_app_screen()
142 self._launch_test_app_from_app_screen()
143+
110 hud.show()
144 hud.show()
111
145
112 start_x, start_y = hud.get_close_button_coords()
146 start_x, start_y = hud.get_close_button_coords()