on xenial help sign in
Fix real world submenus (e.g. kate) not getting their first item selected on open
ac33d0aAlbert Astals Cid
qml/ApplicationMenus/MenuBar.qml−4
@@ -36,10 +36,6 @@ Item {
36 implicitWidth: row.width
36 implicitWidth: row.width
37 height: parent.height
37 height: parent.height
38
38
39− function select(index) {
40− d.select(index);
41− }
42−
43 function dismiss() {
39 function dismiss() {
44 d.dismissAll();
40 d.dismissAll();
45 }
41 }
qml/ApplicationMenus/MenuPopup.qml+6−1
@@ -285,6 +285,12 @@ UbuntuShape {
285 Repeater {
285 Repeater {
286 id: repeater
286 id: repeater
287
287
288+ onCountChanged: {
289+ if (!d.currentItem && count > 0) {
290+ root.select(0);
291+ }
292+ }
293+
288 Loader {
294 Loader {
289 id: loader
295 id: loader
290 objectName: root.objectName + "-item" + __ownIndex
296 objectName: root.objectName + "-item" + __ownIndex
@@ -483,7 +489,6 @@ UbuntuShape {
483 onChildActivated: childActivated();
489 onChildActivated: childActivated();
484 }
490 }
485
491
486− Component.onCompleted: item.select(0);
487 onVisibleChanged: if (visible) { item.select(0); }
492 onVisibleChanged: if (visible) { item.select(0); }
488 }
493 }
489 }
494 }
tests/mocks/QMenuModel/unitymenumodel.cpp+23−4
@@ -18,6 +18,8 @@
18
18
19#include "unitymenumodel.h"
19#include "unitymenumodel.h"
20
20
21+#include <QTimer>
22+
21enum MenuRoles {
23enum MenuRoles {
22 LabelRole = Qt::DisplayRole + 1,
24 LabelRole = Qt::DisplayRole + 1,
23 SensitiveRole,
25 SensitiveRole,
@@ -35,7 +37,8 @@ enum MenuRoles {
35};
37};
36
38
37UnityMenuModel::UnityMenuModel(QObject *parent)
39UnityMenuModel::UnityMenuModel(QObject *parent)
38−: QAbstractListModel(parent)
40+ : QAbstractListModel(parent)
41+ , m_rowCountStatus(NoRequestMade)
39{
42{
40}
43}
41
44
@@ -60,7 +63,7 @@ void UnityMenuModel::setModelData(const QVariant& data)
60
63
61void UnityMenuModel::insertRow(int row, const QVariant& data)
64void UnityMenuModel::insertRow(int row, const QVariant& data)
62{
65{
63− row = qMin(row, rowCount());
66+ row = qMin(row, m_modelData.count());
64
67
65 beginInsertRows(QModelIndex(), row, row);
68 beginInsertRows(QModelIndex(), row, row);
66
69
@@ -71,12 +74,12 @@ void UnityMenuModel::insertRow(int row, const QVariant& data)
71
74
72void UnityMenuModel::appendRow(const QVariant& data)
75void UnityMenuModel::appendRow(const QVariant& data)
73{
76{
74− insertRow(rowCount(), data);
77+ insertRow(m_modelData.count(), data);
75}
78}
76
79
77void UnityMenuModel::removeRow(int row)
80void UnityMenuModel::removeRow(int row)
78{
81{
79− if (row < 0 || rowCount() <= row) {
82+ if (row < 0 || m_modelData.count() <= row) {
80 return;
83 return;
81 }
84 }
82
85
@@ -133,6 +136,22 @@ QString UnityMenuModel::nameOwner() const
133
136
134int UnityMenuModel::rowCount(const QModelIndex&) const
137int UnityMenuModel::rowCount(const QModelIndex&) const
135{
138{
139+ // Fake the rowCount to be 0 for a while (100ms)
140+ // This emulates menus in real world that don't load immediately
141+ if (m_rowCountStatus == TimerRunning)
142+ return 0;
143+
144+ if (m_rowCountStatus == NoRequestMade) {
145+ UnityMenuModel *that = const_cast<UnityMenuModel*>(this);
146+ that->m_rowCountStatus = TimerRunning;
147+ QTimer::singleShot(100, that, [that] {
148+ that->beginInsertRows(QModelIndex(), 0, that->m_modelData.count() - 1);
149+ that->m_rowCountStatus = TimerFinished;
150+ that->endInsertRows();
151+ });
152+ return 0;
153+ }
154+
136 return m_modelData.count();
155 return m_modelData.count();
137}
156}
138
157
tests/mocks/QMenuModel/unitymenumodel.h+7
@@ -101,6 +101,13 @@ private:
101 QByteArray m_busName;
101 QByteArray m_busName;
102 QVariantMap m_actions;
102 QVariantMap m_actions;
103 QByteArray m_menuObjectPath;
103 QByteArray m_menuObjectPath;
104+
105+ enum RowCountStatus {
106+ NoRequestMade,
107+ TimerRunning,
108+ TimerFinished
109+ };
110+ RowCountStatus m_rowCountStatus;
104};
111};
105
112
106#endif // MOCK_UNITYMENUMODEL_H
113#endif // MOCK_UNITYMENUMODEL_H
tests/qmltests/ApplicationMenus/tst_MenuPopup.qml+17−14
@@ -159,9 +159,6 @@ Item {
159
159
160 var priv = findInvisibleChild(menu, "d");
160 var priv = findInvisibleChild(menu, "d");
161
161
162− keyClick(Qt.Key_Down, Qt.NoModifier);
163− compare(priv.currentItem, item0, "CurrentItem should have moved to item 0");
164−
165 keyClick(Qt.Key_Down, Qt.NoModifier);
162 keyClick(Qt.Key_Down, Qt.NoModifier);
166 compare(priv.currentItem, item1, "CurrentItem should have moved to item 1");
163 compare(priv.currentItem, item1, "CurrentItem should have moved to item 1");
167
164
@@ -170,6 +167,9 @@ Item {
170
167
171 keyClick(Qt.Key_Down, Qt.NoModifier);
168 keyClick(Qt.Key_Down, Qt.NoModifier);
172 compare(priv.currentItem, item0, "CurrentItem should have moved to item 0");
169 compare(priv.currentItem, item0, "CurrentItem should have moved to item 0");
170+
171+ keyClick(Qt.Key_Down, Qt.NoModifier);
172+ compare(priv.currentItem, item1, "CurrentItem should have moved to item 1");
173 }
173 }
174
174
175 function test_keyboardNavigation_UpKeySelectsAndOpensPreviousMenuItemAndRotates() {
175 function test_keyboardNavigation_UpKeySelectsAndOpensPreviousMenuItemAndRotates() {
@@ -181,17 +181,17 @@ Item {
181
181
182 var priv = findInvisibleChild(menu, "d");
182 var priv = findInvisibleChild(menu, "d");
183
183
184− keyClick(Qt.Key_Down, Qt.NoModifier);
184+ keyClick(Qt.Key_Up, Qt.NoModifier);
185− compare(priv.currentItem, item0, "CurrentItem should have moved to item 2");
185+ compare(priv.currentItem, item2, "CurrentItem should have moved to item 2");
186
186
187− keyClick(Qt.Key_Down, Qt.NoModifier);
187+ keyClick(Qt.Key_Up, Qt.NoModifier);
188 compare(priv.currentItem, item1, "CurrentItem should have moved to item 1");
188 compare(priv.currentItem, item1, "CurrentItem should have moved to item 1");
189
189
190− keyClick(Qt.Key_Down, Qt.NoModifier);
190+ keyClick(Qt.Key_Up, Qt.NoModifier);
191− compare(priv.currentItem, item2, "CurrentItem should have moved to item 0");
191+ compare(priv.currentItem, item0, "CurrentItem should have moved to item 0");
192
192
193− keyClick(Qt.Key_Down, Qt.NoModifier);
193+ keyClick(Qt.Key_Up, Qt.NoModifier);
194− compare(priv.currentItem, item0, "CurrentItem should have moved to item 2");
194+ compare(priv.currentItem, item2, "CurrentItem should have moved to item 2");
195 }
195 }
196
196
197 function test_keyboardNavigation_RightKeyEntersSubMenu() {
197 function test_keyboardNavigation_RightKeyEntersSubMenu() {
@@ -217,7 +217,7 @@ Item {
217
217
218 var menuItem = findChild(menu, "menu-item0"); verify(menuItem);
218 var menuItem = findChild(menu, "menu-item0"); verify(menuItem);
219 mouseClick(menuItem, menuItem.width/2, menuItem.height/2);
219 mouseClick(menuItem, menuItem.width/2, menuItem.height/2);
220− tryCompareFunction(function() { return menuItem.popup !== null && menuItem.popup.visible }, true);
220+ tryCompareFunction(function() { return menuItem.popup !== null && findInvisibleChild(menuItem.popup, "d").currentItem !== null }, true);
221
221
222 keyClick(Qt.Key_Left, Qt.NoModifier);
222 keyClick(Qt.Key_Left, Qt.NoModifier);
223 tryCompareFunction(function() { return menuItem.popup !== null && menuItem.popup.visible }, false);
223 tryCompareFunction(function() { return menuItem.popup !== null && menuItem.popup.visible }, false);
@@ -245,13 +245,16 @@ Item {
245
245
246 menu.unityMenuModel.modelData = differentSizesMenu;
246 menu.unityMenuModel.modelData = differentSizesMenu;
247
247
248− waitForRendering(menu);
248+ // Wait for the two items to be there
249+ tryCompareFunction(function() { return findChild(menu, "menu-item1") !== null; }, true);
249 var longWidth = menu.width;
250 var longWidth = menu.width;
251+
252+ // Now pop one item and make sure it's smaller
250 differentSizesMenu.pop();
253 differentSizesMenu.pop();
251 menu.unityMenuModel.modelData = differentSizesMenu;
254 menu.unityMenuModel.modelData = differentSizesMenu;
252
255
253− waitForRendering(menu);
256+ tryCompareFunction(function() { return findChild(menu, "menu-item0") !== null; }, true);
254− verify(menu.width < longWidth);
257+ tryCompareFunction(function() { return menu.width < longWidth; }, true);
255 }
258 }
256
259
257 function test_minimumWidth() {
260 function test_minimumWidth() {