on xenial help sign in
Improve Launcher ←→ touch menu interaction
e1dd3c7Albert Astals Cid
qml/Panel/Panel.qml+26−2
@@ -38,6 +38,7 @@ Item {
38 property real expandedPanelHeight: units.gu(7)
38 property real expandedPanelHeight: units.gu(7)
39 property real indicatorMenuWidth: width
39 property real indicatorMenuWidth: width
40 property real applicationMenuWidth: width
40 property real applicationMenuWidth: width
41+ property alias applicationMenuContentX: __applicationMenus.menuContentX
41
42
42 property alias applicationMenus: __applicationMenus
43 property alias applicationMenus: __applicationMenus
43 property alias indicators: __indicators
44 property alias indicators: __indicators
@@ -256,6 +257,7 @@ Item {
256 PanelMenu {
257 PanelMenu {
257 id: __applicationMenus
258 id: __applicationMenus
258
259
260+ x: menuContentX
259 model: registeredMenuModel.model
261 model: registeredMenuModel.model
260 width: root.applicationMenuWidth
262 width: root.applicationMenuWidth
261 minimizedPanelHeight: root.minimizedPanelHeight
263 minimizedPanelHeight: root.minimizedPanelHeight
@@ -264,6 +266,7 @@ Item {
264 alignment: Qt.AlignLeft
266 alignment: Qt.AlignLeft
265 enableHint: !callHint.active && !fullscreenMode
267 enableHint: !callHint.active && !fullscreenMode
266 showOnClick: false
268 showOnClick: false
269+ adjustDragHandleSizeToContents: false
267 panelColor: panelAreaBackground.color
270 panelColor: panelAreaBackground.color
268
271
269 onShowTapped: {
272 onShowTapped: {
@@ -272,8 +275,7 @@ Item {
272 }
275 }
273 }
276 }
274
277
275− showRowTitle: !expanded
278+ hideRow: !expanded
276− rowTitle: PanelState.title
277 rowItemDelegate: ActionItem {
279 rowItemDelegate: ActionItem {
278 id: actionItem
280 id: actionItem
279 property int ownIndex: index
281 property int ownIndex: index
@@ -322,6 +324,28 @@ Item {
322 }
324 }
323 }
325 }
324
326
327+ Label {
328+ id: rowLabel
329+ objectName: "panelTitle"
330+ anchors {
331+ left: parent.left
332+ leftMargin: units.gu(1)
333+ right: __indicators.left
334+ rightMargin: units.gu(1)
335+ }
336+ height: root.minimizedPanelHeight
337+ verticalAlignment: Text.AlignVCenter
338+ elide: Text.ElideRight
339+ maximumLineCount: 1
340+ fontSize: "medium"
341+ font.weight: Font.Medium
342+ color: Theme.palette.selected.backgroundText
343+ opacity: __applicationMenus.visible && !__applicationMenus.expanded ? 1 : 0
344+ visible: opacity != 0
345+ Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
346+ text: PanelState.title
347+ }
348+
325 PanelMenu {
349 PanelMenu {
326 id: __indicators
350 id: __indicators
327 objectName: "indicators"
351 objectName: "indicators"
qml/Panel/PanelBar.qml+1−2
@@ -30,8 +30,7 @@ Item {
30 property real lateralPosition: -1
30 property real lateralPosition: -1
31 property int alignment: Qt.AlignRight
31 property int alignment: Qt.AlignRight
32
32
33− property alias showRowTitle: row.showRowTitle
33+ property alias hideRow: row.hideRow
34− property alias rowTitle: row.rowTitle
35 property alias rowItemDelegate: row.delegate
34 property alias rowItemDelegate: row.delegate
36
35
37 implicitWidth: flickable.contentWidth
36 implicitWidth: flickable.contentWidth
qml/Panel/PanelItemRow.qml+3−23
@@ -20,11 +20,10 @@ import "../Components"
20
20
21Item {
21Item {
22 id: root
22 id: root
23− implicitWidth: showRowTitle && !expanded ? rowTitle != "" ? rowLabel.width : 0 : row.width
23+ implicitWidth: row.width
24 implicitHeight: units.gu(3)
24 implicitHeight: units.gu(3)
25
25
26− property bool showRowTitle: false
26+ property bool hideRow: false
27− property alias rowTitle: rowLabel.text
28 property QtObject model: null
27 property QtObject model: null
29 property real overFlowWidth: width
28 property real overFlowWidth: width
30 property bool expanded: false
29 property bool expanded: false
@@ -164,31 +163,12 @@ Item {
164 d.previousItem = currentItem;
163 d.previousItem = currentItem;
165 }
164 }
166
165
167− Label {
168− id: rowLabel
169− objectName: "panelTitle"
170− anchors {
171− left: parent.left
172− leftMargin: units.gu(1)
173− verticalCenter: parent.verticalCenter
174− }
175− width: implicitWidth + units.gu(2)
176− elide: Text.ElideRight
177− maximumLineCount: 1
178− fontSize: "medium"
179− font.weight: Font.Medium
180− color: Theme.palette.selected.backgroundText
181− opacity: showRowTitle ? 1 : 0
182− visible: opacity != 0
183− Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
184− }
185−
186 ListView {
166 ListView {
187 id: row
167 id: row
188 objectName: "panelRow"
168 objectName: "panelRow"
189 orientation: ListView.Horizontal
169 orientation: ListView.Horizontal
190 model: root.model
170 model: root.model
191− opacity: showRowTitle ? 0 : 1
171+ opacity: hideRow ? 0 : 1
192 // dont set visible on basis of opacity; otherwise width will not be calculated correctly
172 // dont set visible on basis of opacity; otherwise width will not be calculated correctly
193 anchors {
173 anchors {
194 top: parent.top
174 top: parent.top
qml/Panel/PanelMenu.qml+34−23
@@ -32,11 +32,12 @@ Showable {
32 property real openedHeight: units.gu(71)
32 property real openedHeight: units.gu(71)
33 property bool enableHint: true
33 property bool enableHint: true
34 property bool showOnClick: true
34 property bool showOnClick: true
35+ property bool adjustDragHandleSizeToContents: true
35 property color panelColor: theme.palette.normal.background
36 property color panelColor: theme.palette.normal.background
37+ property real menuContentX: 0
36
38
37 property alias alignment: bar.alignment
39 property alias alignment: bar.alignment
38− property alias rowTitle: bar.rowTitle
40+ property alias hideRow: bar.hideRow
39− property alias showRowTitle: bar.showRowTitle
40 property alias rowItemDelegate: bar.rowItemDelegate
41 property alias rowItemDelegate: bar.rowItemDelegate
41 property alias pageDelegate: content.pageDelegate
42 property alias pageDelegate: content.pageDelegate
42
43
@@ -45,7 +46,7 @@ Showable {
45 readonly property bool partiallyOpened: unitProgress > 0 && unitProgress < 1.0
46 readonly property bool partiallyOpened: unitProgress > 0 && unitProgress < 1.0
46 readonly property bool fullyClosed: unitProgress == 0
47 readonly property bool fullyClosed: unitProgress == 0
47 readonly property alias expanded: bar.expanded
48 readonly property alias expanded: bar.expanded
48− readonly property int barWidth: Math.min(bar.width, bar.implicitWidth)
49+ readonly property int barWidth: adjustDragHandleSizeToContents ? Math.min(bar.width, bar.implicitWidth) : bar.width
49 readonly property alias currentMenuIndex: bar.currentItemIndex
50 readonly property alias currentMenuIndex: bar.currentItemIndex
50
51
51 signal showTapped()
52 signal showTapped()
@@ -78,33 +79,42 @@ Showable {
78
79
79 shown: false
80 shown: false
80 height: minimizedPanelHeight
81 height: minimizedPanelHeight
81− clip: root.partiallyOpened
82
82
83 onUnitProgressChanged: d.updateState()
83 onUnitProgressChanged: d.updateState()
84
84
85− // eater
85+ Item {
86− MouseArea {
87− anchors.fill: content
88− hoverEnabled: true
89− acceptedButtons: Qt.AllButtons
90− onWheel: wheel.accepted = true;
91− enabled: root.state != "initial"
92− visible: content.visible
93− }
94−
95− MenuContent {
96− id: content
97− objectName: "menuContent"
98−
99 anchors {
86 anchors {
100 left: parent.left
87 left: parent.left
101 right: parent.right
88 right: parent.right
102 top: bar.bottom
89 top: bar.bottom
90+ bottom: parent.bottom
91+ }
92+ clip: root.partiallyOpened
93+
94+ // eater
95+ MouseArea {
96+ anchors.fill: content
97+ hoverEnabled: true
98+ acceptedButtons: Qt.AllButtons
99+ onWheel: wheel.accepted = true;
100+ enabled: root.state != "initial"
101+ visible: content.visible
102+ }
103+
104+ MenuContent {
105+ id: content
106+ objectName: "menuContent"
107+
108+ anchors {
109+ left: parent.left
110+ right: parent.right
111+ top: parent.top
112+ }
113+ height: openedHeight - bar.height - handle.height
114+ model: root.model
115+ visible: root.unitProgress > 0
116+ currentMenuIndex: bar.currentItemIndex
103 }
117 }
104− height: openedHeight - bar.height - handle.height
105− model: root.model
106− visible: root.unitProgress > 0
107− currentMenuIndex: bar.currentItemIndex
108 }
118 }
109
119
110 Handle {
120 Handle {
@@ -218,8 +228,9 @@ Showable {
218 objectName: "showDragHandle"
228 objectName: "showDragHandle"
219 anchors.bottom: parent.bottom
229 anchors.bottom: parent.bottom
220 anchors.left: alignment == Qt.AlignLeft ? parent.left : undefined
230 anchors.left: alignment == Qt.AlignLeft ? parent.left : undefined
231+ anchors.leftMargin: -root.menuContentX
221 anchors.right: alignment == Qt.AlignRight ? parent.right : undefined
232 anchors.right: alignment == Qt.AlignRight ? parent.right : undefined
222− width: root.barWidth // show handle should only cover panel items.
233+ width: root.barWidth + root.menuContentX // show handle should only cover panel items.
223 height: minimizedPanelHeight
234 height: minimizedPanelHeight
224 direction: Direction.Downwards
235 direction: Direction.Downwards
225 enabled: !root.shown && root.available
236 enabled: !root.shown && root.available
qml/Shell.qml+9−1
@@ -502,6 +502,7 @@ StyledItem {
502 expandedPanelHeight: units.gu(7)
502 expandedPanelHeight: units.gu(7)
503 indicatorMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
503 indicatorMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
504 applicationMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
504 applicationMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
505+ applicationMenuContentX: launcher.lockedVisible ? launcher.panelWidth : 0
505
506
506 indicators {
507 indicators {
507 hides: [launcher]
508 hides: [launcher]
@@ -570,7 +571,14 @@ StyledItem {
570 }
571 }
571 onShownChanged: {
572 onShownChanged: {
572 if (shown) {
573 if (shown) {
573− panel.indicators.hide()
574+ panel.indicators.hide();
575+ panel.applicationMenus.hide();
576+ }
577+ }
578+ onDrawerShownChanged: {
579+ if (drawerShown) {
580+ panel.indicators.hide();
581+ panel.applicationMenus.hide();
574 }
582 }
575 }
583 }
576 onFocusChanged: {
584 onFocusChanged: {
tests/qmltests/Panel/tst_Panel.qml+10−7
@@ -320,12 +320,15 @@ PanelTest {
320 tryCompare(panel.indicators, "fullyOpened", true);
320 tryCompare(panel.indicators, "fullyOpened", true);
321 }
321 }
322
322
323− function pullDownApplicationsMenu() {
323+ function pullDownApplicationsMenu(xPos) {
324 var showDragHandle = findChild(panel.applicationMenus, "showDragHandle");
324 var showDragHandle = findChild(panel.applicationMenus, "showDragHandle");
325+ if (xPos === undefined) {
326+ xPos = showDragHandle.width / 2;
327+ }
325 touchFlick(showDragHandle,
328 touchFlick(showDragHandle,
326− showDragHandle.width / 2,
329+ xPos,
327 showDragHandle.height / 2,
330 showDragHandle.height / 2,
328− showDragHandle.width / 2,
331+ xPos,
329 showDragHandle.height / 2 + (showDragHandle.autoCompleteDragThreshold * 1.1));
332 showDragHandle.height / 2 + (showDragHandle.autoCompleteDragThreshold * 1.1));
330 tryCompare(panel.applicationMenus, "fullyOpened", true);
333 tryCompare(panel.applicationMenus, "fullyOpened", true);
331 }
334 }
@@ -774,7 +777,7 @@ PanelTest {
774 panel.mode = "staged";
777 panel.mode = "staged";
775 mouseEmulation.checked = false;
778 mouseEmulation.checked = false;
776
779
777− var appTitle = findChild(panel.applicationMenus, "panelTitle"); verify(appTitle);
780+ var appTitle = findChild(panel, "panelTitle"); verify(appTitle);
778 var appMenuRow = findChild(panel.applicationMenus, "panelRow"); verify(appMenuRow);
781 var appMenuRow = findChild(panel.applicationMenus, "panelRow"); verify(appMenuRow);
779 var appMenuBar = findChild(panel, "menuBar"); verify(appMenuBar);
782 var appMenuBar = findChild(panel, "menuBar"); verify(appMenuBar);
780
783
@@ -792,7 +795,7 @@ PanelTest {
792 panel.mode = "windowed";
795 panel.mode = "windowed";
793 mouseEmulation.checked = false;
796 mouseEmulation.checked = false;
794
797
795− var appTitle = findChild(panel.applicationMenus, "panelTitle"); verify(appTitle);
798+ var appTitle = findChild(panel, "panelTitle"); verify(appTitle);
796 var appMenuRow = findChild(panel.applicationMenus, "panelRow"); verify(appMenuRow);
799 var appMenuRow = findChild(panel.applicationMenus, "panelRow"); verify(appMenuRow);
797 var appMenuBar = findChild(panel, "menuBar"); verify(appMenuBar);
800 var appMenuBar = findChild(panel, "menuBar"); verify(appMenuBar);
798
801
@@ -853,7 +856,7 @@ PanelTest {
853 var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar");
856 var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar");
854
857
855 PanelState.title = "Fake Title"
858 PanelState.title = "Fake Title"
856− pullDownApplicationsMenu();
859+ pullDownApplicationsMenu(0 /*xPos*/);
857 compare(aboutToShowCalledSpy.count, 1);
860 compare(aboutToShowCalledSpy.count, 1);
858
861
859 keyClick(Qt.Key_Right);
862 keyClick(Qt.Key_Right);
@@ -886,7 +889,7 @@ PanelTest {
886 var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar");
889 var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar");
887
890
888 PanelState.title = "Fake Title"
891 PanelState.title = "Fake Title"
889− pullDownApplicationsMenu();
892+ pullDownApplicationsMenu(0 /*xPos*/);
890
893
891 tryCompare(indicatorsBar, "currentItemIndex", 0);
894 tryCompare(indicatorsBar, "currentItemIndex", 0);
892
895
tests/qmltests/tst_Shell.qml+56−1
@@ -2865,7 +2865,7 @@ Rectangle {
2865 loadShell(data.tag);
2865 loadShell(data.tag);
2866
2866
2867 var panel = findChild(shell, "panel"); verify(panel);
2867 var panel = findChild(shell, "panel"); verify(panel);
2868− var panelTitle = findChild(panel.applicationMenus, "panelTitle"); verify(panelTitle);
2868+ var panelTitle = findChild(panel, "panelTitle"); verify(panelTitle);
2869 compare(panelTitle.visible, false, "Panel title should not be visible when greeter is shown");
2869 compare(panelTitle.visible, false, "Panel title should not be visible when greeter is shown");
2870
2870
2871 swipeAwayGreeter();
2871 swipeAwayGreeter();
@@ -3038,6 +3038,61 @@ Rectangle {
3038 tryCompare(topLevelSurfaceList.applicationAt(0), "appId", "dialer-app");
3038 tryCompare(topLevelSurfaceList.applicationAt(0), "appId", "dialer-app");
3039 }
3039 }
3040
3040
3041+ function test_touchMenuPosition_data() {
3042+ return [
3043+ { tag: "launcher locked", lockLauncher: true },
3044+ { tag: "launcher not locked", lockLauncher: false }
3045+ ];
3046+ }
3047+
3048+ function test_touchMenuPosition(data) {
3049+ loadShell("desktop");
3050+ shell.usageScenario = "desktop";
3051+ waitForRendering(shell);
3052+ swipeAwayGreeter();
3053+
3054+ var panel = findChild(shell, "panel");
3055+ var launcher = testCase.findChild(shell, "launcher");
3056+ launcher.lockedVisible = data.lockLauncher;
3057+ if (data.lockLauncher) {
3058+ compare(panel.applicationMenus.x, launcher.panelWidth);
3059+ } else {
3060+ compare(panel.applicationMenus.x, 0);
3061+ }
3062+ }
3063+
3064+ function test_touchMenuHidesOnLauncherAppDrawer_data() {
3065+ return [
3066+ { tag: "launcher locked", lockLauncher: true },
3067+ { tag: "launcher not locked", lockLauncher: false }
3068+ ];
3069+ }
3070+
3071+ function test_touchMenuHidesOnLauncherAppDrawer(data) {
3072+ loadShell("desktop");
3073+ shell.usageScenario = "desktop";
3074+ waitForRendering(shell);
3075+ swipeAwayGreeter();
3076+
3077+ var panel = findChild(shell, "panel");
3078+ var launcher = testCase.findChild(shell, "launcher");
3079+ launcher.lockedVisible = data.lockLauncher;
3080+
3081+ waitForRendering(panel.applicationMenus);
3082+
3083+ if (data.lockLauncher) {
3084+ panel.applicationMenus.show();
3085+ tryCompare(panel.applicationMenus, "fullyOpened", true);
3086+ launcher.openDrawer();
3087+ } else {
3088+ tryCompare(launcher, "shown", false);
3089+ panel.applicationMenus.show();
3090+ tryCompare(panel.applicationMenus, "fullyOpened", true);
3091+ launcher.switchToNextState("visible");
3092+ }
3093+ tryCompare(panel.applicationMenus, "fullyClosed", true);
3094+ }
3095+
3041 function test_doubleClickPanelRestoresWindow() {
3096 function test_doubleClickPanelRestoresWindow() {
3042 loadShell("desktop");
3097 loadShell("desktop");
3043 shell.usageScenario = "desktop";
3098 shell.usageScenario = "desktop";