Merge lp:~aacid/unity8/select_first_submenu_when_it_appears into lp:unity8

Proposed by Albert Astals Cid
Status: Superseded
Proposed branch: lp:~aacid/unity8/select_first_submenu_when_it_appears
Merge into: lp:unity8
Diff against target: 463 lines (+251/-38)
11 files modified
qml/ApplicationMenus/MenuBar.qml (+0/-4)
qml/ApplicationMenus/MenuPopup.qml (+9/-4)
tests/mocks/QMenuModel/unitymenumodel.cpp (+23/-4)
tests/mocks/QMenuModel/unitymenumodel.h (+7/-0)
tests/qmltests/ApplicationMenus/tst_MenuPopup.qml (+17/-14)
tools/CMakeLists.txt (+2/-12)
tools/menutool/CMakeLists.txt (+5/-0)
tools/menutool/README (+11/-0)
tools/menutool/menutool.cpp (+62/-0)
tools/menutool/menutool.qml (+103/-0)
tools/scopetool/CMakeLists.txt (+12/-0)
To merge this branch: bzr merge lp:~aacid/unity8/select_first_submenu_when_it_appears
Reviewer Review Type Date Requested Status
Unity8 CI Bot continuous-integration Approve
Michael Zanetti (community) Needs Fixing
Review via email: mp+317974@code.launchpad.net

This proposal has been superseded by a proposal from 2017-03-01.

Commit message

Fix real world submenus (e.g. kate) not getting their first item selected on open

MenuBar.qml: remove unused function
MenuPopup.qml: Select first item when one arrives if there's no currentItem instead of on completion
unitymenumodel.cpp: trick rowCount() to simulate "real world late" menus
tst_MenuPopup.qml: adapt to unitymenumodel.cpp changes (and make the Up test actually press Up and not Down)

Description of the change

* Are there any related MPs required for this MP to build/function as expected?
https://code.launchpad.net/~aacid/qmenumodel/batch_insert_remove_from_menu

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

 * If you changed the UI, has there been a design review?
N/A

To post a comment you must log in.
Revision history for this message
Michael Zanetti (mzanetti) wrote :

It does improve the situation but there is something odd:

again, using kate as an example, opening the Tools menu, navigate down to a submenu, enter it, navigate down to the third entry, press left, go to another submenu, enter it. Now the highlight will be at the third entry instead of starting at the first again.

also I managed to get into the situation where I lost keyboard focus altogether in the menu by navigating through the main menu entries. While I'm not 100% sure that is introduced by this branch, I haven't seen it in trunk so far.

review: Needs Fixing
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:2835
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3177/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4172
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/2456
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/2456
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4200
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4037
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4037/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4037
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4037/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4037
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4037/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4037
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4037/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4037
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4037/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4037
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4037/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3177/rebuild

review: Approve (continuous-integration)
2836. By Albert Astals Cid

Merge menutool branch

2837. By Albert Astals Cid

We want to select the first enabled, not necessarily 0

2838. By Albert Astals Cid

this is a bit clearer

2839. By Albert Astals Cid

Test++

2840. By Albert Astals Cid

only submenus select first, not first level menus

2841. By Albert Astals Cid

Merge

Unmerged revisions

2834. By Launchpad Translations on behalf of unity-team

Launchpad automatic translations update.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'qml/ApplicationMenus/MenuBar.qml'
--- qml/ApplicationMenus/MenuBar.qml 2017-02-16 13:43:18 +0000
+++ qml/ApplicationMenus/MenuBar.qml 2017-03-01 14:27:32 +0000
@@ -36,10 +36,6 @@
36 implicitWidth: row.width36 implicitWidth: row.width
37 height: parent.height37 height: parent.height
3838
39 function select(index) {
40 d.select(index);
41 }
42
43 function dismiss() {39 function dismiss() {
44 d.dismissAll();40 d.dismissAll();
45 }41 }
4642
=== modified file 'qml/ApplicationMenus/MenuPopup.qml'
--- qml/ApplicationMenus/MenuPopup.qml 2017-01-31 15:24:06 +0000
+++ qml/ApplicationMenus/MenuPopup.qml 2017-03-01 14:27:32 +0000
@@ -73,8 +73,8 @@
73 d.currentItem = null;73 d.currentItem = null;
74 }74 }
7575
76 function select(index) {76 function selectFirstIndex() {
77 d.select(index)77 d.selectNext(-1);
78 }78 }
7979
80 function reset() {80 function reset() {
@@ -285,6 +285,12 @@
285 Repeater {285 Repeater {
286 id: repeater286 id: repeater
287287
288 onCountChanged: {
289 if (!d.currentItem && count > 0) {
290 root.selectFirstIndex();
291 }
292 }
293
288 Loader {294 Loader {
289 id: loader295 id: loader
290 objectName: root.objectName + "-item" + __ownIndex296 objectName: root.objectName + "-item" + __ownIndex
@@ -483,8 +489,7 @@
483 onChildActivated: childActivated();489 onChildActivated: childActivated();
484 }490 }
485491
486 Component.onCompleted: item.select(0);492 onVisibleChanged: if (visible) { item.selectFirstIndex(); }
487 onVisibleChanged: if (visible) { item.select(0); }
488 }493 }
489 }494 }
490 }495 }
491496
=== modified file 'tests/mocks/QMenuModel/unitymenumodel.cpp'
--- tests/mocks/QMenuModel/unitymenumodel.cpp 2017-01-10 14:46:09 +0000
+++ tests/mocks/QMenuModel/unitymenumodel.cpp 2017-03-01 14:27:32 +0000
@@ -18,6 +18,8 @@
1818
19#include "unitymenumodel.h"19#include "unitymenumodel.h"
2020
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 @@
35};37};
3638
37UnityMenuModel::UnityMenuModel(QObject *parent)39UnityMenuModel::UnityMenuModel(QObject *parent)
38: QAbstractListModel(parent)40 : QAbstractListModel(parent)
41 , m_rowCountStatus(NoRequestMade)
39{42{
40}43}
4144
@@ -60,7 +63,7 @@
6063
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());
6467
65 beginInsertRows(QModelIndex(), row, row);68 beginInsertRows(QModelIndex(), row, row);
6669
@@ -71,12 +74,12 @@
7174
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}
7679
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 }
8285
@@ -133,6 +136,22 @@
133136
134int UnityMenuModel::rowCount(const QModelIndex&) const137int 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}
138157
139158
=== modified file 'tests/mocks/QMenuModel/unitymenumodel.h'
--- tests/mocks/QMenuModel/unitymenumodel.h 2016-09-29 09:15:04 +0000
+++ tests/mocks/QMenuModel/unitymenumodel.h 2017-03-01 14:27:32 +0000
@@ -101,6 +101,13 @@
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};
105112
106#endif // MOCK_UNITYMENUMODEL_H113#endif // MOCK_UNITYMENUMODEL_H
107114
=== modified file 'tests/qmltests/ApplicationMenus/tst_MenuPopup.qml'
--- tests/qmltests/ApplicationMenus/tst_MenuPopup.qml 2017-01-25 14:10:44 +0000
+++ tests/qmltests/ApplicationMenus/tst_MenuPopup.qml 2017-03-01 14:27:32 +0000
@@ -160,9 +160,6 @@
160 var priv = findInvisibleChild(menu, "d");160 var priv = findInvisibleChild(menu, "d");
161161
162 keyClick(Qt.Key_Down, Qt.NoModifier);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);
166 compare(priv.currentItem, item1, "CurrentItem should have moved to item 1");163 compare(priv.currentItem, item1, "CurrentItem should have moved to item 1");
167164
168 keyClick(Qt.Key_Down, Qt.NoModifier);165 keyClick(Qt.Key_Down, Qt.NoModifier);
@@ -170,6 +167,9 @@
170167
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 }
174174
175 function test_keyboardNavigation_UpKeySelectsAndOpensPreviousMenuItemAndRotates() {175 function test_keyboardNavigation_UpKeySelectsAndOpensPreviousMenuItemAndRotates() {
@@ -181,17 +181,17 @@
181181
182 var priv = findInvisibleChild(menu, "d");182 var priv = findInvisibleChild(menu, "d");
183183
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");
186186
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");
189189
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");
192192
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 }
196196
197 function test_keyboardNavigation_RightKeyEntersSubMenu() {197 function test_keyboardNavigation_RightKeyEntersSubMenu() {
@@ -217,7 +217,7 @@
217217
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);
221221
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 @@
245245
246 menu.unityMenuModel.modelData = differentSizesMenu;246 menu.unityMenuModel.modelData = differentSizesMenu;
247247
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;
252255
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 }
256259
257 function test_minimumWidth() {260 function test_minimumWidth() {
258261
=== modified file 'tools/CMakeLists.txt'
--- tools/CMakeLists.txt 2016-05-09 12:38:10 +0000
+++ tools/CMakeLists.txt 2017-03-01 14:27:32 +0000
@@ -1,14 +1,4 @@
1add_executable(${SCOPE_TOOL}1add_subdirectory(menutool)
2 scopetool.cpp2add_subdirectory(scopetool)
3 registry-tracker.cpp
4 ../src/UnixSignalHandler.cpp
5 )
6
7qt5_use_modules(${SCOPE_TOOL} Qml Quick)
8
9# install binaries
10install(TARGETS ${SCOPE_TOOL}
11 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
12 )
133
14install(FILES unlock-device DESTINATION ${SHELL_APP_DIR})4install(FILES unlock-device DESTINATION ${SHELL_APP_DIR})
155
=== added directory 'tools/menutool'
=== added file 'tools/menutool/CMakeLists.txt'
--- tools/menutool/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tools/menutool/CMakeLists.txt 2017-03-01 14:27:32 +0000
@@ -0,0 +1,5 @@
1add_executable(menutool
2 menutool.cpp
3 )
4
5qt5_use_modules(menutool Qml Quick)
06
=== added file 'tools/menutool/README'
--- tools/menutool/README 1970-01-01 00:00:00 +0000
+++ tools/menutool/README 2017-03-01 14:27:32 +0000
@@ -0,0 +1,11 @@
1This tool can be used to browse the menus of another application
2
3How to use:
4 * Start application that exports menus
5 e.g. QT_QPA_PLATFORMTHEME=ubuntuappmenu kate
6 * Figure out which is the dbus address
7 * This is a bit tricky, but using qdbusviewer to see the addresses
8 that appear when starting the app and looking for one that
9 contains com/Ubuntu/Menu/0 should be enough
10 * Start tool passing the dbus address
11 builddir/menutool/menutool :1.293
012
=== added file 'tools/menutool/menutool.cpp'
--- tools/menutool/menutool.cpp 1970-01-01 00:00:00 +0000
+++ tools/menutool/menutool.cpp 2017-03-01 14:27:32 +0000
@@ -0,0 +1,62 @@
1/*
2 * Copyright (C) 2017 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17// Qt
18#include <QDebug>
19#include <QCommandLineParser>
20#include <QGuiApplication>
21#include <QQmlContext>
22#include <QQmlEngine>
23#include <QQuickView>
24
25// local
26#include <paths.h>
27
28int main(int argc, char *argv[])
29{
30 QGuiApplication::setApplicationName("Menu Test Tool");
31 QGuiApplication *application = new QGuiApplication(argc, argv);
32
33 QCommandLineParser parser;
34 parser.parse(application->arguments());
35 const QStringList args = parser.positionalArguments();
36
37 if (args.count() != 1) {
38 qWarning() << "You need to pass the dbus address";
39 return 1;
40 }
41
42 QQuickView* view = new QQuickView();
43 view->setResizeMode(QQuickView::SizeRootObjectToView);
44 view->setTitle(QGuiApplication::applicationName());
45 view->engine()->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
46 view->rootContext()->setContextProperty("contextBusName", args[0]);
47
48 QUrl source(::sourceDirectory() + "/tools/menutool/menutool.qml");
49 prependImportPaths(view->engine(), ::overrideImportPaths());
50 prependImportPaths(view->engine(), ::nonMirImportPaths());
51
52 view->setSource(source);
53
54 view->show();
55
56 int result = application->exec();
57
58 delete view;
59 delete application;
60
61 return result;
62}
063
=== added file 'tools/menutool/menutool.qml'
--- tools/menutool/menutool.qml 1970-01-01 00:00:00 +0000
+++ tools/menutool/menutool.qml 2017-03-01 14:27:32 +0000
@@ -0,0 +1,103 @@
1/*
2* Copyright (C) 2017 Canonical, Ltd.
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; version 3.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17import QtQuick 2.4
18import Ubuntu.Components 1.3
19
20import "../../qml/ApplicationMenus"
21import "../../qml/Panel"
22import "../../qml/Components/PanelState"
23
24import QMenuModel 0.1
25import Unity.Indicators 0.1 as Indicators
26
27Item {
28 width: units.gu(180)
29 height: units.gu(120)
30
31 UnityMenuModel {
32 id: menuModel
33 busName: contextBusName
34 menuObjectPath: "/com/ubuntu/Menu/0"
35 actions: { "unity": "/com/ubuntu/Menu/0" }
36 }
37
38 Panel {
39 id: panel
40
41 height: parent.height
42 width: parent.width / 2
43 minimizedPanelHeight: units.gu(6)
44
45 mode: "windowed"
46
47 applicationMenus {
48 model: menuModel
49 }
50
51 Rectangle {
52 width: 50
53 height: 50
54 anchors.centerIn: parent
55 color: "gray"
56 rotation: 45
57 Timer {
58 interval: 20
59 running: true
60 repeat: true
61 onTriggered: parent.rotation = parent.rotation+1
62 }
63 }
64
65 Rectangle {
66 color: "green"
67 anchors.bottom: parent.bottom
68 anchors.right: parent.right
69 Label {
70 id: label
71 anchors.centerIn: parent
72 text: "Click here to open touch menu manually"
73 }
74 width: label.width + units.gu(2)
75 height: label.height + units.gu(2)
76 MouseArea {
77 anchors.fill: parent
78 onClicked: panel.applicationMenus.show();
79 }
80 visible: !panel.applicationMenus.shown
81 }
82 }
83
84 Rectangle {
85 color: "blue"
86 height: parent.height
87 width: parent.width / 2
88 x: width
89
90 MenuBar {
91 id: menuBar
92 height: units.gu(3)
93 width: parent.width
94 enableKeyFilter: true
95 unityMenuModel: menuModel
96 }
97 }
98
99 Component.onCompleted: {
100 theme.name = "Ubuntu.Components.Themes.SuruDark";
101 PanelState.title = "Drag here to open touch menu";
102 }
103}
0104
=== added directory 'tools/scopetool'
=== added file 'tools/scopetool/CMakeLists.txt'
--- tools/scopetool/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tools/scopetool/CMakeLists.txt 2017-03-01 14:27:32 +0000
@@ -0,0 +1,12 @@
1add_executable(${SCOPE_TOOL}
2 scopetool.cpp
3 registry-tracker.cpp
4 ../../src/UnixSignalHandler.cpp
5 )
6
7qt5_use_modules(${SCOPE_TOOL} Qml Quick)
8
9# install binaries
10install(TARGETS ${SCOPE_TOOL}
11 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
12 )
013
=== renamed file 'tools/registry-tracker.cpp' => 'tools/scopetool/registry-tracker.cpp'
=== renamed file 'tools/registry-tracker.h' => 'tools/scopetool/registry-tracker.h'
=== renamed file 'tools/scopetool.cpp' => 'tools/scopetool/scopetool.cpp'

Subscribers

People subscribed via source and target branches