on xenial help sign in
Allow indicators to take up more space

The addition of application menus made it more difficult to hit the target area for the messages indicator. Prior to the application menu addition, the entire blank area of the panel could be used. After, only the 2 gu space taken up by the icon could be used. This was due to an implementation detail of the application menus... when the Shell has 60 gu or less width, both the application menus and the indicators are set to the full width of the panel. This meant that their drag handles, the area where they could be "pulled down" from, took the entire panel. Since the indicators were defined after the application menus in the file, the indicators' handle went over the application menus' and the menus were unusable. To solve this, the original author forced the indicators' handle to only use the space taken by the indicator items. This approach had two big problems. First, if the user had enough indicators to reach all the way across the screen, the application menus would be unusable. Second, it shrank the usable handle area for the leftmost indicator. This change adjusts the indicator bar to provide a 7 grid unit space to its left whenever the application menus are available. In case of space contention between the two (read: too many indicators are showing), the leftmost indicators will hide. Whenever the application menus are not available, the indicators (and, more importantly, their handle) take up the full width of the screen again. Additionally, I added a "down" icon to the panel. It shows up at any screen size, but only when application menus are available. This should help improve discoverability of the application menus, which were visually "silent" in Staged mode prior to this change. Finally, I've noticed that sometimes tests may not clean up properly after setting indicators to hidden. To fix this, I manually set the indicators hidden then visible again. Since I needed a test case for a smaller screen and didn't want to copy so much code, I refactored the test case into a new PanelUI file for the setup. Fixes https://github.com/ubports/ubuntu-touch/issues/1233

commitae0a2472fcab37b9b7c5d1e158215629ffda8811 authorDalton Durst <dalton@ubports.com> dateTue 25 Feb 2020, 20:50 (7 years ago) parentc36c2dc
7 files changed+488−249
qml/Panel/Panel.qml+54−19 qml/Panel/PanelMenu.qml+5−6 qml/Shell.qml+1−7 tests/qmltests/CMakeLists.txt+1 tests/qmltests/Panel/PanelUI.qml+274 tests/qmltests/Panel/tst_Panel.qml+20−217 tests/qmltests/Panel/tst_PanelSmallScreen.qml+133
qml/Panel/Panel.qml+54−19
@@ -1,5 +1,6 @@
11/*
22 * Copyright (C) 2013-2017 Canonical, Ltd.
3+ * Copyright (C) 2020 UBports Foundation
34 *
45 * This program is free software; you can redistribute it and/or modify
56 * it under the terms of the GNU General Public License as published by
@@ -37,8 +38,7 @@ Item {
3738
3839 property real minimizedPanelHeight: units.gu(3)
3940 property real expandedPanelHeight: units.gu(7)
40− property real indicatorMenuWidth: width
41− property real applicationMenuWidth: width
41+ property real menuWidth: partialWidth ? units.gu(40) : width
4242 property alias applicationMenuContentX: __applicationMenus.menuContentX
4343
4444 property alias applicationMenus: __applicationMenus
@@ -48,6 +48,9 @@ Item {
4848 property bool greeterShown: false
4949 property bool hasKeyboard: false
5050
51+ // Whether our expanded menus should take up the full width of the panel
52+ property bool partialWidth: width > units.gu(60)
53+
5154 property string mode: "staged"
5255
5356 MouseArea {
@@ -260,14 +263,14 @@ Item {
260263
261264 x: menuContentX
262265 model: registeredMenuModel.model
263− width: root.applicationMenuWidth
266+ width: root.menuWidth
267+ overFlowWidth: width
264268 minimizedPanelHeight: root.minimizedPanelHeight
265269 expandedPanelHeight: root.expandedPanelHeight
266270 openedHeight: root.height
267271 alignment: Qt.AlignLeft
268272 enableHint: !callHint.active && !fullscreenMode
269273 showOnClick: false
270− adjustDragHandleSizeToContents: false
271274 panelColor: panelAreaBackground.color
272275
273276 onShowTapped: {
@@ -325,9 +328,8 @@ Item {
325328 }
326329 }
327330
328− Label {
329− id: rowLabel
330− objectName: "panelTitle"
331+ Item {
332+ id: panelTitleHolder
331333 anchors {
332334 left: parent.left
333335 leftMargin: units.gu(1)
@@ -335,16 +337,44 @@ Item {
335337 rightMargin: units.gu(1)
336338 }
337339 height: root.minimizedPanelHeight
338− verticalAlignment: Text.AlignVCenter
339− elide: Text.ElideRight
340− maximumLineCount: 1
341− fontSize: "medium"
342− font.weight: Font.Medium
343− color: theme.palette.selected.backgroundText
344− opacity: __applicationMenus.visible && !__applicationMenus.expanded ? 1 : 0
345− visible: opacity != 0
346− Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
347− text: PanelState.title
340+
341+ Label {
342+ id: rowLabel
343+ anchors {
344+ left: parent.left
345+ }
346+ objectName: "panelTitle"
347+ width: root.width - __indicators.maxDragHandleSize - touchMenuIcon.width
348+ height: root.minimizedPanelHeight
349+ verticalAlignment: Text.AlignVCenter
350+ elide: Text.ElideRight
351+ maximumLineCount: 1
352+ fontSize: "medium"
353+ font.weight: Font.Medium
354+ color: theme.palette.selected.backgroundText
355+ text: (root.partialWidth && !callHint.visible) ? PanelState.title : ""
356+ opacity: __applicationMenus.visible && !__applicationMenus.expanded
357+ Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
358+ visible: opacity !== 0
359+ readonly property var implicitWidthWithMargin: implicitWidth === 0 ? 0 : implicitWidth + units.gu(1)
360+ }
361+
362+ Icon {
363+ id: touchMenuIcon
364+ objectName: "touchMenuIcon"
365+ anchors {
366+ right: parent.right
367+ rightMargin: parent.width - rowLabel.implicitWidthWithMargin - width
368+ verticalCenter: parent.verticalCenter
369+ }
370+ width: units.gu(2)
371+ height: units.gu(2)
372+ name: "down"
373+ color: theme.palette.normal.backgroundText
374+ opacity: !__applicationMenus.expanded && d.enableTouchMenus && !callHint.visible
375+ Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
376+ visible: opacity !== 0
377+ }
348378 }
349379
350380 PanelMenu {
@@ -355,16 +385,21 @@ Item {
355385 top: parent.top
356386 right: parent.right
357387 }
358− width: root.indicatorMenuWidth
388+ width: root.menuWidth
359389 minimizedPanelHeight: root.minimizedPanelHeight
360390 expandedPanelHeight: root.expandedPanelHeight
361391 openedHeight: root.height
362392
363− overFlowWidth: root.width
393+ overFlowWidth: width - appMenuClear
364394 enableHint: !callHint.active && !fullscreenMode
365395 showOnClick: !callHint.visible
366396 panelColor: panelAreaBackground.color
367397
398+ // On small screens, the Indicators' handle area is the entire top
399+ // bar unless there is an application menu. In that case, our handle
400+ // needs to allow for some room to clear the application menu.
401+ property var appMenuClear: (d.enableTouchMenus && !partialWidth) ? units.gu(7) : 0
402+
368403 onShowTapped: {
369404 if (callHint.active) {
370405 callHint.showLiveCall();
qml/Panel/PanelMenu.qml+5−6
@@ -1,5 +1,6 @@
11/*
22 * Copyright (C) 2014-2016 Canonical, Ltd.
3+ * Copyright (C) 2020 UBports Foundation
34 *
45 * This program is free software; you can redistribute it and/or modify
56 * it under the terms of the GNU General Public License as published by
@@ -32,7 +33,6 @@ Showable {
3233 property real openedHeight: units.gu(71)
3334 property bool enableHint: true
3435 property bool showOnClick: true
35− property bool adjustDragHandleSizeToContents: true
3636 property color panelColor: theme.palette.normal.background
3737 property real menuContentX: 0
3838
@@ -46,7 +46,7 @@ Showable {
4646 readonly property bool partiallyOpened: unitProgress > 0 && unitProgress < 1.0
4747 readonly property bool fullyClosed: unitProgress == 0
4848 readonly property alias expanded: bar.expanded
49− readonly property int barWidth: adjustDragHandleSizeToContents ? Math.min(bar.width, bar.implicitWidth) : bar.width
49+ readonly property int barWidth: bar.width
5050 readonly property alias currentMenuIndex: bar.currentItemIndex
5151
5252 // The user tapped the panel and did not move.
@@ -213,9 +213,8 @@ Showable {
213213
214214 MouseArea {
215215 anchors.bottom: parent.bottom
216− anchors.left: alignment == Qt.AlignLeft ? parent.left : undefined
217− anchors.right: alignment == Qt.AlignRight ? parent.right : undefined
218− width: root.barWidth // show handle should only cover panel items.
216+ anchors.left: alignment == Qt.AlignLeft ? parent.left : __showDragHandle.left
217+ anchors.right: alignment == Qt.AlignRight ? parent.right : __showDragHandle.right
219218 height: minimizedPanelHeight
220219 enabled: __showDragHandle.enabled && showOnClick
221220 onClicked: {
@@ -232,7 +231,7 @@ Showable {
232231 anchors.left: alignment == Qt.AlignLeft ? parent.left : undefined
233232 anchors.leftMargin: -root.menuContentX
234233 anchors.right: alignment == Qt.AlignRight ? parent.right : undefined
235− width: root.barWidth + root.menuContentX // show handle should only cover panel items.
234+ width: root.overFlowWidth + root.menuContentX
236235 height: minimizedPanelHeight
237236 direction: Direction.Downwards
238237 enabled: !root.shown && root.available && !hideAnimation.running && !showAnimation.running
qml/Shell.qml+1−7
@@ -1,6 +1,6 @@
11/*
22 * Copyright (C) 2013-2016 Canonical, Ltd.
3− * Copyright (C) 2019 UBports Foundation
3+ * Copyright (C) 2019-2020 UBports Foundation
44 *
55 * This program is free software; you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
@@ -517,14 +517,8 @@ StyledItem {
517517 mode: shell.usageScenario == "desktop" ? "windowed" : "staged"
518518 minimizedPanelHeight: units.gu(3)
519519 expandedPanelHeight: units.gu(7)
520− indicatorMenuWidth: menuWidth
521− applicationMenuWidth: menuWidth
522520 applicationMenuContentX: launcher.lockedVisible ? launcher.panelWidth : 0
523521
524− // Whether the menus should take up the full screen or not
525− readonly property bool partialWidth: parent.width > units.gu(60)
526− readonly property double menuWidth: partialWidth ? units.gu(40) : parent.width
527−
528522 indicators {
529523 hides: [launcher]
530524 available: tutorial.panelEnabled
tests/qmltests/CMakeLists.txt+1
@@ -46,6 +46,7 @@ add_unity8_qmltest(Panel PanelBar)
4646add_unity8_qmltest(Panel PanelMenu)
4747add_unity8_qmltest(Panel MenuContent)
4848add_unity8_qmltest(Panel Panel)
49+add_unity8_qmltest(Panel PanelSmallScreen)
4950add_unity8_qmltest_data(Panel PanelTest)
5051add_unity8_qmltest(Panel/Indicators IndicatorItem)
5152add_unity8_qmltest(Panel/Indicators IndicatorsLight)
tests/qmltests/Panel/PanelUI.qmlnew file+274
@@ -0,0 +1,274 @@
1+/*
2+ * Copyright 2013-2015 Canonical Ltd.
3+ * Copyright 2020 UBports Foundation
4+ *
5+ * This program is free software; you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation; version 3.
8+ *
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16+ */
17+
18+import QtQuick 2.4
19+import QtQuick.Layouts 1.1
20+import QtTest 1.0
21+import Unity.Test 0.1
22+import Ubuntu.Components 1.3
23+import Ubuntu.Components.ListItems 1.3 as ListItem
24+import Unity.Application 0.1
25+import QMenuModel 0.1
26+import Ubuntu.Telephony 0.1 as Telephony
27+import AccountsService 0.1
28+import Unity.InputInfo 0.1
29+import "../../../qml/Panel"
30+import "../../../qml/Components/PanelState"
31+import "../Stage"
32+import ".."
33+
34+PanelTest {
35+ id: root
36+ width: units.gu(120)
37+ height: units.gu(71)
38+ color: "black"
39+
40+ property alias panel: panel
41+ property alias mouseEmulation: mouseEmulation
42+ property alias appMenuData: appMenuData
43+ property alias aboutToShowCalledSpy: aboutToShowCalledSpy
44+ property alias itemArea: itemArea
45+ property alias backgroundMouseArea: backgroundMouseArea
46+ property alias phoneCall: phoneCall
47+
48+ Binding {
49+ target: QuickUtils
50+ property: "keyboardAttached"
51+ value: keyboardAttached.checked
52+ }
53+
54+ SurfaceManager { id: sMgr }
55+ ApplicationMenuDataLoader {
56+ id: appMenuData
57+ surfaceManager: sMgr
58+ }
59+
60+ Component.onCompleted: {
61+ theme.name = "Ubuntu.Components.Themes.SuruDark"
62+ }
63+
64+ Rectangle {
65+ anchors.fill: parent
66+ color: "darkgrey"
67+ }
68+
69+ SignalSpy {
70+ id: aboutToShowCalledSpy
71+ signalName: "aboutToShowCalled"
72+ }
73+
74+ RowLayout {
75+ anchors.fill: parent
76+ anchors.margins: units.gu(1)
77+ clip: true
78+
79+ Rectangle {
80+ Layout.fillWidth: true
81+ Layout.fillHeight: true
82+
83+ id: itemArea
84+ color: backgroundMouseArea.pressed ? "black" : "gray"
85+
86+ MouseArea {
87+ id: backgroundMouseArea
88+ anchors.fill: parent
89+ hoverEnabled: true
90+
91+ Panel {
92+ id: panel
93+ anchors.fill: parent
94+ mode: modeSelector.model[modeSelector.selectedIndex]
95+
96+ applicationMenus {
97+ model: menuData.checked ? menuModel : null
98+
99+ readonly property var menuModel: UnityMenuModel {
100+ modelData: appMenuData.generateTestData(10, 4, 2, 3, "menu")
101+ }
102+
103+ hides: [ panel.indicators ]
104+ }
105+
106+ indicators {
107+ model: root.indicatorsModel
108+ hides: [ panel.applicationMenus ]
109+ }
110+ }
111+ }
112+ }
113+
114+ ColumnLayout {
115+ Layout.alignment: Qt.AlignTop
116+ Layout.fillWidth: false
117+
118+ ListItem.ItemSelector {
119+ id: modeSelector
120+ anchors { left: parent.left; right: parent.right }
121+ activeFocusOnPress: false
122+ text: "Mode"
123+ model: ["staged", "windowed" ]
124+ onSelectedIndexChanged: {
125+ panel.mode = model[selectedIndex];
126+ keyboardAttached.checked = panel.mode == "windowed"
127+ windowControlsCB.checked = panel.mode == "windowed"
128+ }
129+ }
130+
131+ Button {
132+ Layout.fillWidth: true
133+ text: panel.indicators.shown ? "Hide Indicators" : "Show Indicators"
134+ onClicked: {
135+ if (panel.indicators.shown) {
136+ panel.indicators.hide();
137+ } else {
138+ panel.indicators.show();
139+ }
140+ }
141+ }
142+
143+ Button {
144+ Layout.fillWidth: true
145+ text: callManager.hasCalls ? "Remove call" : "Add call"
146+ onClicked: {
147+ if (callManager.foregroundCall) {
148+ callManager.foregroundCall = null;
149+ } else {
150+ callManager.foregroundCall = phoneCall;
151+ }
152+ }
153+ }
154+
155+ RowLayout {
156+ Layout.fillWidth: true
157+ CheckBox {
158+ id: fullscreenCB
159+ checked: false
160+ }
161+ Label {
162+ text: "Main app is fullscreen"
163+ color: "white"
164+ }
165+ }
166+
167+ Binding {
168+ target: panel
169+ property: "fullscreenMode"
170+ value: fullscreenCB.checked
171+ }
172+
173+ RowLayout {
174+ Layout.fillWidth: true
175+ CheckBox {
176+ id: menuData
177+ checked: true
178+ }
179+ Label {
180+ text: "Application Menu has data"
181+ color: "white"
182+ }
183+ }
184+
185+ Binding {
186+ target: PanelState
187+ property: "decorationsVisible"
188+ value: windowControlsCB.checked
189+ }
190+
191+ Binding {
192+ target: PanelState
193+ property: "title"
194+ value: "Fake window title"
195+ }
196+
197+ RowLayout {
198+ Layout.fillWidth: true
199+ CheckBox {
200+ id: windowControlsCB
201+ onClicked: PanelState.decorationsVisible = checked
202+ }
203+ Label {
204+ text: "Show window decorations"
205+ color: "white"
206+ }
207+ }
208+
209+ Rectangle {
210+ Layout.preferredHeight: units.dp(1);
211+ Layout.fillWidth: true;
212+ color: "black"
213+ }
214+
215+ Rectangle {
216+ Layout.preferredHeight: units.dp(1);
217+ Layout.fillWidth: true;
218+ color: "black"
219+ }
220+
221+ Repeater {
222+ model: root.originalModelData
223+ RowLayout {
224+ CheckBox {
225+ checked: true
226+ onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index);
227+ }
228+ Label {
229+ Layout.fillWidth: true
230+ text: modelData["identifier"]
231+ color: "white"
232+ }
233+
234+ CheckBox {
235+ checked: true
236+ onCheckedChanged: setIndicatorVisible(index, checked);
237+ }
238+ Label {
239+ text: "visible"
240+ color: "white"
241+ }
242+ }
243+ }
244+
245+ Rectangle {
246+ Layout.preferredHeight: units.dp(1);
247+ Layout.fillWidth: true;
248+ color: "black"
249+ }
250+
251+ MouseTouchEmulationCheckbox {
252+ id: mouseEmulation
253+ color: "white"
254+ checked: panel.mode == "staged"
255+ }
256+
257+ RowLayout {
258+ Layout.fillWidth: true
259+ CheckBox {
260+ id: keyboardAttached
261+ }
262+ Label {
263+ text: "Keyboard Attached"
264+ color: "white"
265+ }
266+ }
267+ }
268+ }
269+
270+ Telephony.CallEntry {
271+ id: phoneCall
272+ phoneNumber: "+447812221111"
273+ }
274+}
tests/qmltests/Panel/tst_Panel.qml+20−217
@@ -1,5 +1,6 @@
11/*
22 * Copyright 2013-2015 Canonical Ltd.
3+ * Copyright 2020 UBports Foundation
34 *
45 * This program is free software; you can redistribute it and/or modify
56 * it under the terms of the GNU General Public License as published by
@@ -30,213 +31,9 @@ import "../../../qml/Components/PanelState"
3031import "../Stage"
3132import ".."
3233
33−PanelTest {
34+PanelUI {
3435 id: root
3536 width: units.gu(120)
36− height: units.gu(71)
37− color: "black"
38−
39− Binding {
40− target: QuickUtils
41− property: "keyboardAttached"
42− value: keyboardAttached.checked
43− }
44−
45− SurfaceManager { id: sMgr }
46− ApplicationMenuDataLoader {
47− id: appMenuData
48− surfaceManager: sMgr
49− }
50−
51− Component.onCompleted: {
52− theme.name = "Ubuntu.Components.Themes.SuruDark"
53− }
54−
55− Rectangle {
56− anchors.fill: parent
57− color: "darkgrey"
58− }
59−
60− SignalSpy {
61− id: aboutToShowCalledSpy
62− signalName: "aboutToShowCalled"
63− }
64−
65− RowLayout {
66− anchors.fill: parent
67− anchors.margins: units.gu(1)
68− clip: true
69−
70− Rectangle {
71− Layout.fillWidth: true
72− Layout.fillHeight: true
73−
74− id: itemArea
75− color: backgroundMouseArea.pressed ? "red" : "blue"
76−
77− MouseArea {
78− id: backgroundMouseArea
79− anchors.fill: parent
80− hoverEnabled: true
81−
82− Panel {
83− id: panel
84− anchors.fill: parent
85− mode: modeSelector.model[modeSelector.selectedIndex]
86−
87− indicatorMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
88− applicationMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
89−
90− applicationMenus {
91− model: UnityMenuModel {
92− modelData: appMenuData.generateTestData(5, 4, 2, 3, "menu")
93− }
94−
95− hides: [ panel.indicators ]
96− }
97−
98− indicators {
99− model: root.indicatorsModel
100− hides: [ panel.applicationMenus ]
101− }
102− }
103− }
104− }
105−
106− ColumnLayout {
107− Layout.alignment: Qt.AlignTop
108− Layout.fillWidth: false
109−
110− ListItem.ItemSelector {
111− id: modeSelector
112− anchors { left: parent.left; right: parent.right }
113− activeFocusOnPress: false
114− text: "Mode"
115− model: ["staged", "windowed" ]
116− onSelectedIndexChanged: {
117− panel.mode = model[selectedIndex];
118− keyboardAttached.checked = panel.mode == "windowed"
119− }
120− }
121−
122− Button {
123− Layout.fillWidth: true
124− text: panel.indicators.shown ? "Hide" : "Show"
125− onClicked: {
126− if (panel.indicators.shown) {
127− panel.indicators.hide();
128− } else {
129− panel.indicators.show();
130− }
131− }
132− }
133−
134− Button {
135− text: panel.fullscreenMode ? "Maximize" : "FullScreen"
136− Layout.fillWidth: true
137− onClicked: panel.fullscreenMode = !panel.fullscreenMode
138− }
139−
140− Button {
141− Layout.fillWidth: true
142− text: callManager.hasCalls ? "Called" : "No Calls"
143− onClicked: {
144− if (callManager.foregroundCall) {
145− callManager.foregroundCall = null;
146− } else {
147− callManager.foregroundCall = phoneCall;
148− }
149− }
150− }
151−
152− RowLayout {
153− Layout.fillWidth: true
154− CheckBox {
155− id: windowControlsCB
156− onClicked: PanelState.decorationsVisible = checked
157− }
158− Label {
159− text: "Show window decorations"
160− color: "white"
161− }
162− }
163−
164− RowLayout {
165− Layout.fillWidth: true
166− CheckBox {
167− onClicked: PanelState.title = checked ? "Fake window title" : ""
168− }
169− Label {
170− text: "Show fake window title"
171− color: "white"
172− }
173− }
174−
175− Rectangle {
176− Layout.preferredHeight: units.dp(1);
177− Layout.fillWidth: true;
178− color: "black"
179− }
180−
181− Rectangle {
182− Layout.preferredHeight: units.dp(1);
183− Layout.fillWidth: true;
184− color: "black"
185− }
186−
187− Repeater {
188− model: root.originalModelData
189− RowLayout {
190− CheckBox {
191− checked: true
192− onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index);
193− }
194− Label {
195− Layout.fillWidth: true
196− text: modelData["identifier"]
197− color: "white"
198− }
199−
200− CheckBox {
201− checked: true
202− onCheckedChanged: setIndicatorVisible(index, checked);
203− }
204− Label {
205− text: "visible"
206− color: "white"
207− }
208− }
209− }
210−
211− Rectangle {
212− Layout.preferredHeight: units.dp(1);
213− Layout.fillWidth: true;
214− color: "black"
215− }
216−
217− MouseTouchEmulationCheckbox {
218− id: mouseEmulation
219− color: "white"
220− checked: panel.mode == "staged"
221− }
222−
223− RowLayout {
224− Layout.fillWidth: true
225− CheckBox {
226− id: keyboardAttached
227− }
228− Label {
229− text: "Keyboard Attached"
230− color: "white"
231− }
232− }
233− }
234− }
235−
236− Telephony.CallEntry {
237− id: phoneCall
238− phoneNumber: "+447812221111"
239− }
24037
24138 UnityTestCase {
24239 name: "Panel"
@@ -255,12 +52,18 @@ PanelTest {
25552 }
25653
25754 function init() {
55+ var messagingMenu = findChild(panel, "fake-indicator-messages-panelItem");
56+ // Make all indicators visible again
57+ for (var i = 0; i < originalModelData.length; i++) {
58+ root.setIndicatorVisible(i, false);
59+ root.setIndicatorVisible(i, true);
60+ }
25861 panel.mode = "staged";
25962 mouseEmulation.checked = true;
26063 panel.fullscreenMode = false;
26164 callManager.foregroundCall = null;
26265
263− PanelState.title = "";
66+ PanelState.title = "Fake Window Title"
26467 PanelState.decorationsVisible = false;
26568
26669 // Put the mouse somewhere neutral so it doesn't hover over things
@@ -278,6 +81,8 @@ PanelTest {
27881 compare(windowControlButtonsSpy.valid, true);
27982
28083 waitForRendering(panel);
84+ // Wait for indicators to fade in all the way using a sample
85+ tryCompare(messagingMenu, "opacity", 1);
28186 }
28287
28388 function cleanup() {
@@ -353,8 +158,6 @@ PanelTest {
353158 // expose more of the panel, binding it to the selected indicator and opening it's menu.
354159 // Tested from first Y pixel to check for swipe from offscreen.
355160 function test_drag_indicator_item_down_shows_menu(data) {
356− skip("Unstable test; panel expansion refactor may be required");
357−
358161 panel.fullscreenMode = data.fullscreen;
359162 callManager.foregroundCall = data.call;
360163
@@ -376,12 +179,18 @@ PanelTest {
376179
377180 var indicatorItem = get_indicator_item(i);
378181
182+ if (indicatorItem.hidden) {
183+ // Getting to this item would require swiping left after
184+ // pulling down
185+ continue;
186+ }
187+
379188 var startXPosition = panel.mapFromItem(indicatorItem, indicatorItem.width / 2, 0).x;
380189
381190 touchFlick(panel,
382191 startXPosition, 0,
383192 startXPosition, panel.height,
384− true /* beginTouch */, false /* endTouch */, 1, 15);
193+ true /* beginTouch */, false /* endTouch */);
385194
386195 // Indicators height should follow the drag, and therefore increase accordingly.
387196 // They should be at least half-way through the screen
@@ -435,7 +244,7 @@ PanelTest {
435244 touchFlick(data.section,
436245 data.section.width / 2, panel.height,
437246 data.section.width / 2, 0,
438− true /* beginTouch */, false /* endTouch */, units.gu(5), 15);
247+ true /* beginTouch */, false /* endTouch */);
439248
440249 // Indicators height should follow the drag, and therefore increase accordingly.
441250 // They should be at least half-way through the screen
@@ -462,7 +271,6 @@ PanelTest {
462271 }
463272
464273 function test_hint(data) {
465− PanelState.title = "Fake Title"
466274 panel.fullscreenMode = data.fullscreen;
467275 callManager.foregroundCall = data.call;
468276
@@ -504,7 +312,6 @@ PanelTest {
504312 // menus, first by running the hint animation, then after dragging down will
505313 // expose more of the panel. Releasing the touch will complete the show.
506314 function test_drag_applicationMenu_down_shows_menu(data) {
507− PanelState.title = "Fake Title";
508315 panel.fullscreenMode = data.fullscreen;
509316 callManager.foregroundCall = data.call;
510317
@@ -524,7 +331,7 @@ PanelTest {
524331 touchFlick(panel,
525332 units.gu(1), 0,
526333 units.gu(1), panel.height,
527− true /* beginTouch */, false /* endTouch */, units.gu(5), 15);
334+ true /* beginTouch */, false /* endTouch */);
528335
529336 // Indicators height should follow the drag, and therefore increase accordingly.
530337 // They should be at least half-way through the screen
@@ -596,7 +403,6 @@ PanelTest {
596403 }
597404
598405 function test_darkenedAreaEatsAllApplicationMenuEvents() {
599− PanelState.title = "Fake Title"
600406
601407 // The center of the area not covered by the indicators menu
602408 // Ie, the visible darkened area behind the menu
@@ -780,7 +586,6 @@ PanelTest {
780586 }
781587
782588 function test_windowedApplicationMenuBarShowOnMouseHover() {
783− PanelState.title = "Fake Title";
784589 panel.mode = "windowed";
785590 mouseEmulation.checked = false;
786591
@@ -844,7 +649,6 @@ PanelTest {
844649
845650 var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar");
846651
847− PanelState.title = "Fake Title";
848652 waitForRendering(panel);
849653 pullDownApplicationsMenu(0 /*xPos*/);
850654 compare(aboutToShowCalledSpy.count, 1);
@@ -878,7 +682,6 @@ PanelTest {
878682
879683 var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar");
880684
881− PanelState.title = "Fake Title"
882685 pullDownApplicationsMenu(0 /*xPos*/);
883686
884687 tryCompare(indicatorsBar, "currentItemIndex", 0);
tests/qmltests/Panel/tst_PanelSmallScreen.qmlnew file+133
@@ -0,0 +1,133 @@
1+/*
2+ * Copyright 2013-2015 Canonical Ltd.
3+ * Copyright 2020 UBports Foundation
4+ *
5+ * This program is free software; you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation; version 3.
8+ *
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16+ */
17+
18+import QtQuick 2.4
19+import QtQuick.Layouts 1.1
20+import QtTest 1.0
21+import Unity.Test 0.1
22+import Ubuntu.Components 1.3
23+import Ubuntu.Components.ListItems 1.3 as ListItem
24+import Unity.Application 0.1
25+import QMenuModel 0.1
26+import Ubuntu.Telephony 0.1 as Telephony
27+import AccountsService 0.1
28+import Unity.InputInfo 0.1
29+import "../../../qml/Panel"
30+import "../../../qml/Components/PanelState"
31+import "../Stage"
32+import ".."
33+
34+PanelUI {
35+ id: root
36+ width: units.gu(71)
37+
38+ UnityTestCase {
39+ name: "PanelSmallScreen"
40+ when: windowShown
41+
42+ function init() {
43+ panel.mode = "staged";
44+ mouseEmulation.checked = true;
45+ panel.fullscreenMode = false;
46+ callManager.foregroundCall = null;
47+
48+ PanelState.title = "Fake Window Title"
49+ PanelState.decorationsVisible = false;
50+
51+ // Put the mouse somewhere neutral so it doesn't hover over things
52+ // and mess up the test
53+ mouseMove(root, 0, 0);
54+
55+ // Wait for the indicators to get into position.
56+ // (switches between normal and fullscreen modes are animated)
57+ var panelArea = findChild(panel, "panelArea");
58+ tryCompare(panelArea, "y", 0);
59+
60+ waitForRendering(panel);
61+ }
62+
63+ function cleanup() {
64+ var messagingMenu = findChild(panel, "fake-indicator-messages-panelItem");
65+ // Make all indicators visible again
66+ for (var i = 0; i < originalModelData.length; i++) {
67+ root.setIndicatorVisible(i, true);
68+ }
69+ panel.hasKeyboard = false;
70+ panel.indicators.hide();
71+ panel.applicationMenus.hide();
72+ waitForAllAnimationToComplete("initial");
73+ tryCompare(panel.indicators, "fullyClosed", true);
74+ tryCompare(panel.applicationMenus, "fullyClosed", true);
75+ // Wait for indicators to fade in all the way
76+ tryCompare(messagingMenu, "opacity", 1);
77+ }
78+
79+ function get_indicator_item(index) {
80+ var indicatorItem = findChild(panel, root.originalModelData[index]["identifier"]+"-panelItem");
81+ verify(indicatorItem);
82+
83+ return indicatorItem;
84+ }
85+
86+ function waitForAllAnimationToComplete(state) {
87+
88+ waitUntilTransitionsEnd(panel);
89+ tryCompare(panel.indicators.hideAnimation, "running", false);
90+ tryCompare(panel.indicators.showAnimation, "running", false);
91+ tryCompare(panel.indicators, "state", state);
92+
93+ for (var i = 0; i < root.originalModelData.length; i++) {
94+ var indicatorItem = get_indicator_item(i);
95+
96+ var itemState = findInvisibleChild(indicatorItem, "indicatorItemState");
97+ verify(itemState);
98+
99+ waitUntilTransitionsEnd(itemState);
100+ }
101+
102+ tryCompare(panel.applicationMenus.hideAnimation, "running", false);
103+ tryCompare(panel.applicationMenus, "state", state);
104+ }
105+
106+
107+ /*
108+ Ensures that things the Shell assumes to be true at a phone size
109+ are, indeed, true:
110+
111+ * The PanelTitle is empty
112+ * The "down" icon is shown
113+ * Pulling down from just left of the Indicators pulls the
114+ Application Menus
115+ */
116+ function test_assumptions() {
117+ var rowTitle = findChild(panel, "panelTitle");
118+ var touchMenuIcon = findChild(panel, "touchMenuIcon");
119+ var indicatorDragHandle = findChild(panel.indicators, "showDragHandle");
120+ var showDragHandle = findChild(panel.applicationMenus, "showDragHandle");
121+
122+ compare(rowTitle.text, "");
123+ compare(touchMenuIcon.visible, true);
124+
125+ touchFlick(indicatorDragHandle,
126+ -1,
127+ showDragHandle.height / 2,
128+ -1,
129+ showDragHandle.height / 2 + (showDragHandle.autoCompleteDragThreshold * 1.1));
130+ tryCompare(panel.applicationMenus, "fullyOpened", true);
131+ }
132+ }
133+}