on xenial help sign in
Merge lp:~aacid/unity8/disabledMenus
commit9a85331c163371458a7b005d70343562c5f7f2ba authorAlbert Astals Cid <albert.astals@canonical.com> dateThu 16 Mar 2017, 17:07 (10 years ago) parentf2c72ace52e226
14 files changed+236−23
debian/control+1−1 qml/ApplicationMenus/MenuBar.qml+3−1 qml/ApplicationMenus/MenuPopup.qml+3−1 qml/Panel/MenuContent.qml+2−2 qml/Panel/Panel.qml+8 qml/Panel/PanelBar.qml+16 qml/Panel/PanelItemRow.qml+32−6 qml/Panel/PanelMenu.qml+3−2 qml/Panel/PanelMenuPage.qml+2−1 tests/mocks/QMenuModel/unitymenumodel.cpp+5 tests/mocks/QMenuModel/unitymenumodel.h+2 tests/qmltests/ApplicationMenus/tst_MenuBar.qml+67 tests/qmltests/ApplicationMenus/tst_MenuPopup.qml+34−9 tests/qmltests/Panel/tst_Panel.qml+58
debian/control+1−1
@@ -28,7 +28,7 @@ Build-Depends: cmake,
2828 liblightdm-qt5-3-dev,
2929 libpam0g-dev,
3030 libpulse-dev,
31− libqmenumodel-dev (>= 0.2.11),
31+ libqmenumodel-dev (>= 0.2.12),
3232 libqt5svg5-dev,
3333 libqt5xmlpatterns5-dev,
3434 libsystemsettings-dev,
qml/ApplicationMenus/MenuBar.qml+3−1
@@ -132,6 +132,7 @@ Item {
132132
133133 function show() {
134134 if (!__popup) {
135+ root.unityMenuModel.aboutToShow(visualItem.__ownIndex);
135136 __popup = menuComponent.createObject(root,
136137 {
137138 objectName: visualItem.objectName + "-menu",
@@ -142,7 +143,8 @@ Item {
142143 __popup.reset();
143144 __popup.childActivated.connect(dismiss);
144145 // force the current item to be the newly popped up menu
145− } else {
146+ } else if (!__popup.visible) {
147+ root.unityMenuModel.aboutToShow(visualItem.__ownIndex);
146148 __popup.show();
147149 }
148150 d.currentItem = visualItem;
qml/ApplicationMenus/MenuPopup.qml+3−1
@@ -302,6 +302,7 @@ UbuntuShape {
302302
303303 if (hasSubmenu) {
304304 if (!popup) {
305+ root.unityMenuModel.aboutToShow(__ownIndex);
305306 var model = root.unityMenuModel.submenu(__ownIndex);
306307 popup = submenuComponent.createObject(focusScope, {
307308 objectName: parent.objectName + "-",
@@ -323,7 +324,8 @@ UbuntuShape {
323324 popup = null;
324325 root.childActivated();
325326 });
326− } else if (popup) {
327+ } else if (!popup.visible) {
328+ root.unityMenuModel.aboutToShow(__ownIndex);
327329 popup.visible = true;
328330 }
329331 } else {
qml/Panel/MenuContent.qml+2−2
@@ -44,9 +44,9 @@ Rectangle {
4444 anchors.fill: parent
4545 model: content.model
4646
47− highlightFollowsCurrentItem: true
47+ highlightFollowsCurrentItem: false
48+ contentX: currentIndex * width
4849 interactive: false
49− highlightMoveDuration: 0
5050 orientation: ListView.Horizontal
5151 // Load all the indicator menus (a big number)
5252 cacheBuffer: 1073741823
qml/Panel/Panel.qml+8
@@ -274,6 +274,7 @@ Item {
274274 id: actionItem
275275 property int ownIndex: index
276276 objectName: "appMenuItem"+index
277+ enabled: model.sensitive
277278
278279 width: _title.width + units.gu(2)
279280 height: parent.height
@@ -292,6 +293,13 @@ Item {
292293 }
293294
294295 pageDelegate: PanelMenuPage {
296+ readonly property bool isCurrent: modelIndex == __applicationMenus.currentMenuIndex
297+ onIsCurrentChanged: {
298+ if (isCurrent && menuModel) {
299+ menuModel.aboutToShow(modelIndex);
300+ }
301+ }
302+
295303 menuModel: __applicationMenus.model
296304 submenuIndex: modelIndex
297305
qml/Panel/PanelBar.qml+16
@@ -43,6 +43,22 @@ Item {
4343 row.selectItemAt(mapped.x);
4444 }
4545
46+ function selectPreviousItem() {
47+ if (!expanded) {
48+ row.resetCurrentItem();
49+ }
50+ row.selectPreviousItem();
51+ d.alignIndicators();
52+ }
53+
54+ function selectNextItem() {
55+ if (!expanded) {
56+ row.resetCurrentItem();
57+ }
58+ row.selectNextItem();
59+ d.alignIndicators();
60+ }
61+
4662 function setCurrentItemIndex(index) {
4763 if (!expanded) {
4864 row.resetCurrentItem();
qml/Panel/PanelItemRow.qml+32−6
@@ -95,31 +95,57 @@ Item {
9595 row.currentIndex = -1;
9696 }
9797
98+ function selectPreviousItem() {
99+ var indexToSelect = currentItemIndex - 1;
100+ while (indexToSelect >= 0) {
101+ if (setCurrentItemIndex(indexToSelect))
102+ return;
103+ indexToSelect = indexToSelect - 1;
104+ }
105+ }
106+
107+ function selectNextItem() {
108+ var indexToSelect = currentItemIndex + 1;
109+ while (indexToSelect < row.contentItem.children.length) {
110+ if (setCurrentItemIndex(indexToSelect))
111+ return;
112+ indexToSelect = indexToSelect + 1;
113+ }
114+ }
115+
98116 function setCurrentItemIndex(index) {
99117 for (var i = 0; i < row.contentItem.children.length; i++) {
100118 var item = row.contentItem.children[i];
101− if (item.hasOwnProperty("ownIndex") && item.ownIndex === index) {
102− if (currentItem !== item) row.currentIndex = index;
103− break;
119+ if (item.hasOwnProperty("ownIndex") && item.ownIndex === index && item.enabled) {
120+ if (currentItem !== item) {
121+ row.currentIndex = index;
122+ }
123+ return true;
104124 }
105125 }
126+ return false;
106127 }
107128
108129 function selectItemAt(lateralPosition) {
109130 var item = indicatorAt(lateralPosition, 0);
110− if (item && item.opacity > 0) {
131+ if (item && item.opacity > 0 && item.enabled) {
111132 row.currentIndex = item.ownIndex;
112133 } else {
113134 // Select default item.
114135 var searchIndex = lateralPosition >= width ? row.count - 1 : 0;
115136
116137 for (var i = 0; i < row.contentItem.children.length; i++) {
117− if (row.contentItem.children[i].hasOwnProperty("ownIndex") && row.contentItem.children[i].ownIndex === searchIndex) {
138+ if (row.contentItem.children[i].hasOwnProperty("ownIndex") &&
139+ row.contentItem.children[i].ownIndex === searchIndex &&
140+ row.contentItem.children[i].enabled)
141+ {
118142 item = row.contentItem.children[i];
119143 break;
120144 }
121145 }
122− if (currentItem !== item) row.currentIndex = item ? item.ownIndex : -1;
146+ if (item && currentItem !== item) {
147+ row.currentIndex = item.ownIndex;
148+ }
123149 }
124150 }
125151
qml/Panel/PanelMenu.qml+3−2
@@ -47,6 +47,7 @@ Showable {
4747 readonly property bool fullyClosed: unitProgress == 0
4848 readonly property alias expanded: bar.expanded
4949 readonly property int barWidth: adjustDragHandleSizeToContents ? Math.min(bar.width, bar.implicitWidth) : bar.width
50+ readonly property alias currentMenuIndex: bar.currentItemIndex
5051
5152 signal showTapped()
5253
@@ -152,10 +153,10 @@ Showable {
152153
153154 Keys.onPressed: {
154155 if (event.key === Qt.Key_Left) {
155− bar.setCurrentItemIndex(bar.currentItemIndex - 1);
156+ bar.selectPreviousItem();
156157 event.accepted = true;
157158 } else if (event.key === Qt.Key_Right) {
158− bar.setCurrentItemIndex(bar.currentItemIndex + 1);
159+ bar.selectNextItem();
159160 event.accepted = true;
160161 } else if (event.key === Qt.Key_Escape) {
161162 root.hide();
qml/Panel/PanelMenuPage.qml+2−1
@@ -63,7 +63,7 @@ PageStack {
6363 if (model) {
6464 push(pageComponent, { "menuModel": model });
6565 }
66− } else {
66+ } else if (root.currentPage) {
6767 root.currentPage.reset();
6868 }
6969 }
@@ -192,6 +192,7 @@ PageStack {
192192 if (item.hasOwnProperty("clicked")) {
193193 item.clicked.connect(function() {
194194 if (model.hasSubmenu) {
195+ page.menuModel.aboutToShow(modelIndex);
195196 root.push(pageComponent, {
196197 "isSubmenu": true,
197198 "title": model.label.replace(/_|&/, ""),
tests/mocks/QMenuModel/unitymenumodel.cpp+5
@@ -273,6 +273,11 @@ void UnityMenuModel::activate(int row, const QVariant&)
273273 Q_EMIT activated(rd[roleNames()[ActionRole]].toString());
274274}
275275
276+void UnityMenuModel::aboutToShow(int index)
277+{
278+ Q_EMIT aboutToShowCalled(index);
279+}
280+
276281void UnityMenuModel::changeState(int, const QVariant&)
277282{
278283}
tests/mocks/QMenuModel/unitymenumodel.h+2
@@ -73,6 +73,7 @@ public:
7373 Q_INVOKABLE QVariant get(int row, const QByteArray &role);
7474
7575 Q_INVOKABLE void activate(int index, const QVariant& parameter = QVariant());
76+ Q_INVOKABLE void aboutToShow(int index);
7677 Q_INVOKABLE void changeState(int index, const QVariant& parameter);
7778
7879 void registerAction(UnityMenuAction* action);
@@ -87,6 +88,7 @@ Q_SIGNALS:
8788
8889 // Internal mock usage
8990 void modelDataChanged();
91+ void aboutToShowCalled(int index);
9092
9193 void activated(const QString& action);
9294
tests/qmltests/ApplicationMenus/tst_MenuBar.qml+67
@@ -76,6 +76,12 @@ Item {
7676 signalName: "activated"
7777 }
7878
79+ SignalSpy {
80+ id: aboutToShowCalledSpy
81+ target: menuBackend
82+ signalName: "aboutToShowCalled"
83+ }
84+
7985 UnityTestCase {
8086 id: testCase
8187 name: "MenuBar"
@@ -115,6 +121,43 @@ Item {
115121 compare(menuItem0.popupVisible, true, "Popup should be visible");
116122 }
117123
124+ function test_aboutToShow() {
125+ menuBackend.modelData = appMenuData.generateTestData(3,3,0,0, "menu");
126+ wait(50) // wait for row to build
127+ var priv = findInvisibleChild(menuBar, "d");
128+
129+ var menuItem0 = findChild(menuBar, "menuBar-item0");
130+ var menuItem1 = findChild(menuBar, "menuBar-item1");
131+
132+ aboutToShowCalledSpy.clear();
133+ menuItem0.show();
134+ compare(aboutToShowCalledSpy.count, 1);
135+
136+ menuItem0.show();
137+ // It's already shown so nothing happens
138+ compare(aboutToShowCalledSpy.count, 1);
139+
140+ menuItem0.hide();
141+ menuItem0.show();
142+ compare(aboutToShowCalledSpy.count, 2);
143+
144+ menuItem0.dismiss();
145+ menuItem0.show();
146+ compare(aboutToShowCalledSpy.count, 3);
147+
148+ menuItem1.show();
149+ compare(aboutToShowCalledSpy.count, 4);
150+
151+ menuItem0.show();
152+ compare(aboutToShowCalledSpy.count, 5);
153+
154+ compare(aboutToShowCalledSpy.signalArguments[0][0], 0);
155+ compare(aboutToShowCalledSpy.signalArguments[1][0], 0);
156+ compare(aboutToShowCalledSpy.signalArguments[2][0], 0);
157+ compare(aboutToShowCalledSpy.signalArguments[3][0], 1);
158+ compare(aboutToShowCalledSpy.signalArguments[4][0], 0);
159+ }
160+
118161 function test_keyboardNavigation_RightKeySelectsNextMenuItem(data) {
119162 menuBackend.modelData = appMenuData.generateTestData(3,3,0,0, "menu");
120163 var priv = findInvisibleChild(menuBar, "d");
@@ -183,6 +226,30 @@ Item {
183226 keyRelease(data.tag, Qt.AltModifier, 100);
184227 }
185228
229+ function test_disabledTopLevel() {
230+ var modelData = appMenuData.generateTestData(3,3,0,0,"menu");
231+ modelData[1].rowData.sensitive = false;
232+ menuBackend.modelData = modelData;
233+
234+ var priv = findInvisibleChild(menuBar, "d");
235+
236+ var menuItem0 = findChild(menuBar, "menuBar-item0"); verify(menuItem0);
237+ var menuItem2 = findChild(menuBar, "menuBar-item2"); verify(menuItem2);
238+
239+ menuItem0.show();
240+ compare(menuItem0.popupVisible, true, "Popup should be visible");
241+
242+ keyClick(Qt.Key_Right);
243+ compare(priv.currentItem, menuItem2);
244+ compare(menuItem2.popupVisible, true);
245+ compare(menuItem0.popupVisible, false);
246+
247+ keyClick(Qt.Key_Left);
248+ compare(priv.currentItem, menuItem0);
249+ compare(menuItem2.popupVisible, false);
250+ compare(menuItem0.popupVisible, true);
251+ }
252+
186253 function test_menuActivateClosesMenu() {
187254 menuBackend.modelData = appMenuData.generateTestData(3,3,0,0,"menu");
188255 var priv = findInvisibleChild(menuBar, "d");
tests/qmltests/ApplicationMenus/tst_MenuPopup.qml+34−9
@@ -59,18 +59,13 @@ Item {
5959 }}
6060 ]
6161 }
62−
63− Binding {
64− target: activatedSpy
65− property: "target"
66− value: unityMenuModel
67− }
6862 }
6963 }
7064
7165 SignalSpy {
72− id: activatedSpy
73− signalName: "activated"
66+ id: aboutToShowCalledSpy
67+ target: loader.item ? loader.item.unityMenuModel : undefined
68+ signalName: "aboutToShowCalled"
7469 }
7570
7671 UnityTestCase {
@@ -88,7 +83,6 @@ Item {
8883 function cleanup() {
8984 menu.reset();
9085 wait(100); // let the page dismiss
91− activatedSpy.clear();
9286
9387 loader.active = false;
9488 tryCompare(loader, "item", null);
@@ -194,6 +188,37 @@ Item {
194188 compare(priv.currentItem, item0, "CurrentItem should have moved to item 2");
195189 }
196190
191+ function test_aboutToShow() {
192+ menu.unityMenuModel.modelData = appMenuData.generateTestData(3,3,1,0,"menu",false);
193+
194+ var item0 = findChild(menu, "menu-item0");
195+ var item1 = findChild(menu, "menu-item1");
196+ var item2 = findChild(menu, "menu-item2");
197+
198+ aboutToShowCalledSpy.clear();
199+
200+ mouseMove(item0, item0.width/2, item0.height/2);
201+ tryCompare(aboutToShowCalledSpy, "count", 1);
202+
203+ mouseMove(item1, item0.width/2, item0.height/2);
204+ tryCompare(aboutToShowCalledSpy, "count", 2);
205+
206+ mouseMove(item2, item0.width/2, item0.height/2);
207+ tryCompare(aboutToShowCalledSpy, "count", 3);
208+
209+ mouseMove(item0, item0.width/2, item0.height/2);
210+ tryCompare(aboutToShowCalledSpy, "count", 4);
211+
212+ item0.item.trigger();
213+ // it's already visible
214+ tryCompare(aboutToShowCalledSpy, "count", 4);
215+
216+ compare(aboutToShowCalledSpy.signalArguments[0][0], 0);
217+ compare(aboutToShowCalledSpy.signalArguments[1][0], 1);
218+ compare(aboutToShowCalledSpy.signalArguments[2][0], 2);
219+ compare(aboutToShowCalledSpy.signalArguments[3][0], 0);
220+ }
221+
197222 function test_keyboardNavigation_RightKeyEntersSubMenu() {
198223 menu.unityMenuModel.modelData = appMenuData.generateTestData(3,3,1,0,"menu",false);
199224
tests/qmltests/Panel/tst_Panel.qml+58
@@ -57,6 +57,11 @@ PanelTest {
5757 color: "darkgrey"
5858 }
5959
60+ SignalSpy {
61+ id: aboutToShowCalledSpy
62+ signalName: "aboutToShowCalled"
63+ }
64+
6065 RowLayout {
6166 anchors.fill: parent
6267 anchors.margins: units.gu(1)
@@ -838,5 +843,58 @@ PanelTest {
838843 keyClick(Qt.Key_Escape);
839844 tryCompare(panel.indicators, "fullyClosed", true);
840845 }
846+
847+ function test_aboutToShowMenu() {
848+ waitForRendering(panel);
849+
850+ aboutToShowCalledSpy.target = panel.applicationMenus.model
851+ aboutToShowCalledSpy.clear();
852+
853+ var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar");
854+
855+ PanelState.title = "Fake Title"
856+ pullDownApplicationsMenu();
857+ compare(aboutToShowCalledSpy.count, 1);
858+
859+ keyClick(Qt.Key_Right);
860+ tryCompare(indicatorsBar, "currentItemIndex", 1);
861+ compare(aboutToShowCalledSpy.count, 2);
862+
863+ compare(aboutToShowCalledSpy.signalArguments[0][0], 0);
864+ compare(aboutToShowCalledSpy.signalArguments[1][0], 1);
865+
866+ keyClick(Qt.Key_Tab);
867+ keyClick(Qt.Key_Tab);
868+
869+ aboutToShowCalledSpy.target = panel.applicationMenus.model.submenu(1);
870+ aboutToShowCalledSpy.clear();
871+
872+ keyClick(Qt.Key_Enter);
873+ compare(aboutToShowCalledSpy.count, 1);
874+ }
875+
876+ function test_disabledTopLevel() {
877+ var modelData = appMenuData.generateTestData(3,3,0,0,"menu");
878+ modelData[1].rowData.sensitive = false;
879+ panel.applicationMenus.model.modelData = modelData;
880+
881+ waitForRendering(panel);
882+
883+ aboutToShowCalledSpy.target = panel.applicationMenus.model
884+ aboutToShowCalledSpy.clear();
885+
886+ var indicatorsBar = findChild(panel.applicationMenus, "indicatorsBar");
887+
888+ PanelState.title = "Fake Title"
889+ pullDownApplicationsMenu();
890+
891+ tryCompare(indicatorsBar, "currentItemIndex", 0);
892+
893+ keyClick(Qt.Key_Right);
894+ tryCompare(indicatorsBar, "currentItemIndex", 2);
895+
896+ keyClick(Qt.Key_Left);
897+ tryCompare(indicatorsBar, "currentItemIndex", 0);
898+ }
841899 }
842900}