on xenial help sign in
Indicators convergence: use the "phone" profile everywhere Fixes: #1520492
67aa798Lukáš Tinkl
plugins/Unity/Indicators/CMakeLists.txt+2−1
@@ -29,6 +29,7 @@ set(IndicatorsQML_SOURCES
29 sharedunitymenumodel.cpp
29 sharedunitymenumodel.cpp
30 unitymenumodelcache.cpp
30 unitymenumodelcache.cpp
31 unitymenumodelstack.cpp
31 unitymenumodelstack.cpp
32+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Platform/platform.cpp
32)
33)
33add_definitions(-DUNITYINDICATORS_LIBRARY)
34add_definitions(-DUNITYINDICATORS_LIBRARY)
34
35
@@ -42,6 +43,6 @@ target_link_libraries(IndicatorsQml
42 ${QMENUMODEL_LDFLAGS}
43 ${QMENUMODEL_LDFLAGS}
43)
44)
44
45
45−qt5_use_modules(IndicatorsQml Core Qml Quick)
46+qt5_use_modules(IndicatorsQml Core Qml Quick DBus)
46
47
47add_unity8_plugin(Unity.Indicators 0.1 Unity/Indicators TARGETS IndicatorsQml)
48add_unity8_plugin(Unity.Indicators 0.1 Unity/Indicators TARGETS IndicatorsQml)
plugins/Unity/Indicators/actionrootstate.h+1−1
@@ -30,7 +30,7 @@ class UNITYINDICATORS_EXPORT ActionRootState : public RootStateObject
30 Q_PROPERTY(QString actionName READ actionName WRITE setActionName NOTIFY actionNameChanged)
30 Q_PROPERTY(QString actionName READ actionName WRITE setActionName NOTIFY actionNameChanged)
31
31
32public:
32public:
33− ActionRootState(QObject *parent = 0);
33+ ActionRootState(QObject *parent = nullptr);
34
34
35 QDBusActionGroup *actionGroup() const;
35 QDBusActionGroup *actionGroup() const;
36 void setActionGroup(QDBusActionGroup *actionGroup);
36 void setActionGroup(QDBusActionGroup *actionGroup);
plugins/Unity/Indicators/indicator.cpp+2−3
@@ -44,10 +44,9 @@ void Indicator::init(const QString& busName, const QSettings& settings)
44
44
45 setId(settings.value(QStringLiteral("Indicator Service/Name")).toString());
45 setId(settings.value(QStringLiteral("Indicator Service/Name")).toString());
46
46
47− QString actionObjectPath = settings.value(QStringLiteral("Indicator Service/ObjectPath")).toString();
47+ const QString actionObjectPath = settings.value(QStringLiteral("Indicator Service/ObjectPath")).toString();
48
48
49 QVariantMap properties;
49 QVariantMap properties;
50− properties.clear();
51 properties.insert(QStringLiteral("busType"), 1);
50 properties.insert(QStringLiteral("busType"), 1);
52 properties.insert(QStringLiteral("busName"), busName);
51 properties.insert(QStringLiteral("busName"), busName);
53 properties.insert(QStringLiteral("actionsObjectPath"), actionObjectPath);
52 properties.insert(QStringLiteral("actionsObjectPath"), actionObjectPath);
@@ -87,7 +86,7 @@ void Indicator::setProfile(const QString& profile)
87 pos = m_settings.value(QStringLiteral("Indicator Service/Position"), QVariant::fromValue(0));
86 pos = m_settings.value(QStringLiteral("Indicator Service/Position"), QVariant::fromValue(0));
88 setPosition(pos.toInt());
87 setPosition(pos.toInt());
89
88
90− QString menuObjectPath = m_settings.value(profile + "/ObjectPath").toString();
89+ const QString menuObjectPath = m_settings.value(profile + "/ObjectPath").toString();
91 QVariantMap map = m_properties.toMap();
90 QVariantMap map = m_properties.toMap();
92 map.insert(QStringLiteral("menuObjectPath"), menuObjectPath);
91 map.insert(QStringLiteral("menuObjectPath"), menuObjectPath);
93 setIndicatorProperties(map);
92 setIndicatorProperties(map);
plugins/Unity/Indicators/indicator.h+1−1
@@ -32,7 +32,7 @@ class UNITYINDICATORS_EXPORT Indicator : public QObject
32public:
32public:
33 typedef QSharedPointer<Indicator> Ptr;
33 typedef QSharedPointer<Indicator> Ptr;
34
34
35− Indicator(QObject *parent = 0);
35+ Indicator(QObject *parent = nullptr);
36 virtual ~Indicator();
36 virtual ~Indicator();
37
37
38 void init(const QString& busName, const QSettings& settings);
38 void init(const QString& busName, const QSettings& settings);
plugins/Unity/Indicators/indicatorsmanager.cpp+30−14
@@ -51,20 +51,19 @@ IndicatorsManager::IndicatorsManager(QObject* parent)
51IndicatorsManager::~IndicatorsManager()
51IndicatorsManager::~IndicatorsManager()
52{
52{
53 unload();
53 unload();
54−
55}
54}
56
55
57void IndicatorsManager::load()
56void IndicatorsManager::load()
58{
57{
59 unload();
58 unload();
60
59
61− QStringList xdgLocations = shellDataDirs();//QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
60+ const QStringList xdgLocations = shellDataDirs();
62
61
63 m_fsWatcher.reset(new QFileSystemWatcher(this));
62 m_fsWatcher.reset(new QFileSystemWatcher(this));
64
63
65 Q_FOREACH(const QString& xdgLocation, xdgLocations)
64 Q_FOREACH(const QString& xdgLocation, xdgLocations)
66 {
65 {
67− QString indicator_path = QDir::cleanPath(xdgLocation + "/unity/indicators");
66+ const QString indicator_path = QDir::cleanPath(xdgLocation + "/unity/indicators");
68 QDir indicator_dir(indicator_path);
67 QDir indicator_dir(indicator_path);
69 if (indicator_dir.exists())
68 if (indicator_dir.exists())
70 {
69 {
@@ -103,7 +102,7 @@ void IndicatorsManager::loadDir(const QDir& dir)
103{
102{
104 startVerify(dir.canonicalPath());
103 startVerify(dir.canonicalPath());
105
104
106− QFileInfoList indicator_files = dir.entryInfoList(QStringList(), QDir::Files|QDir::NoDotAndDotDot);
105+ const QFileInfoList indicator_files = dir.entryInfoList(QStringList(), QDir::Files|QDir::NoDotAndDotDot);
107 Q_FOREACH(const QFileInfo& indicator_file, indicator_files)
106 Q_FOREACH(const QFileInfo& indicator_file, indicator_files)
108 {
107 {
109 loadFile(indicator_file);
108 loadFile(indicator_file);
@@ -115,26 +114,30 @@ void IndicatorsManager::loadDir(const QDir& dir)
115void IndicatorsManager::loadFile(const QFileInfo& file_info)
114void IndicatorsManager::loadFile(const QFileInfo& file_info)
116{
115{
117 QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this);
116 QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this);
118− QString name = indicator_settings.value(QStringLiteral("Indicator Service/Name")).toString();
117+ const QString name = indicator_settings.value(QStringLiteral("Indicator Service/Name")).toString();
118+
119+ if (m_platform.isPC() && name == "indicator-keyboard") {
120+ return; // convergence: skip this indicator until it works in Mir
121+ }
119
122
120− auto iter = m_indicatorsData.find(name);
123+ auto iter = m_indicatorsData.constFind(name);
121− if (iter != m_indicatorsData.end())
124+ if (iter != m_indicatorsData.constEnd())
122 {
125 {
123− QString newFileInfoDir = QDir::cleanPath(file_info.canonicalPath());
126+ const QString newFileInfoDir = QDir::cleanPath(file_info.canonicalPath());
124 IndicatorData* currentData = (*iter);
127 IndicatorData* currentData = (*iter);
125 currentData->m_verified = true;
128 currentData->m_verified = true;
126
129
127 int file_info_location = -1;
130 int file_info_location = -1;
128 int current_data_location = -1;
131 int current_data_location = -1;
129
132
130− QString currentDataDir = QDir::cleanPath(currentData->m_fileInfo.canonicalPath());
133+ const QString currentDataDir = QDir::cleanPath(currentData->m_fileInfo.canonicalPath());
131
134
132 // if we've already got this indicator, we need to make sure we're not overwriting data which is
135 // if we've already got this indicator, we need to make sure we're not overwriting data which is
133 // from a lower priority standard path
136 // from a lower priority standard path
134 QStringList xdgLocations = shellDataDirs();
137 QStringList xdgLocations = shellDataDirs();
135 for (int i = 0; i < xdgLocations.size(); i++)
138 for (int i = 0; i < xdgLocations.size(); i++)
136 {
139 {
137− QString indicatorDir = QDir::cleanPath(xdgLocations[i] + "/unity/indicators");
140+ const QString indicatorDir = QDir::cleanPath(xdgLocations[i] + "/unity/indicators");
138
141
139 if (newFileInfoDir == indicatorDir)
142 if (newFileInfoDir == indicatorDir)
140 {
143 {
@@ -194,7 +197,7 @@ void IndicatorsManager::unloadFile(const QFileInfo& file)
194 {
197 {
195 if (!data->m_verified)
198 if (!data->m_verified)
196 {
199 {
197− QString name = data->m_name;
200+ const QString name = data->m_name;
198 Q_EMIT indicatorAboutToBeUnloaded(name);
201 Q_EMIT indicatorAboutToBeUnloaded(name);
199
202
200 delete data;
203 delete data;
@@ -253,7 +256,7 @@ void IndicatorsManager::endVerify(const QString& path)
253 {
256 {
254 if (!data->m_verified)
257 if (!data->m_verified)
255 {
258 {
256− QString name = data->m_name;
259+ const QString name = data->m_name;
257 Q_EMIT indicatorAboutToBeUnloaded(name);
260 Q_EMIT indicatorAboutToBeUnloaded(name);
258
261
259 delete data;
262 delete data;
@@ -271,7 +274,7 @@ Indicator::Ptr IndicatorsManager::indicator(const QString& indicator_name)
271 return Indicator::Ptr();
274 return Indicator::Ptr();
272 }
275 }
273
276
274− IndicatorData *data = m_indicatorsData[indicator_name];
277+ IndicatorData *data = m_indicatorsData.value(indicator_name);
275 if (data->m_indicator)
278 if (data->m_indicator)
276 {
279 {
277 return data->m_indicator;
280 return data->m_indicator;
@@ -281,7 +284,20 @@ Indicator::Ptr IndicatorsManager::indicator(const QString& indicator_name)
281 data->m_indicator = new_indicator;
284 data->m_indicator = new_indicator;
282 QSettings settings(data->m_fileInfo.absoluteFilePath(), QSettings::IniFormat, this);
285 QSettings settings(data->m_fileInfo.absoluteFilePath(), QSettings::IniFormat, this);
283 new_indicator->init(data->m_fileInfo.fileName(), settings);
286 new_indicator->init(data->m_fileInfo.fileName(), settings);
287+
288+ // convergence:
289+ // 1) enable session indicator conditionally, typically when running in a multisession/multiuser environment
290+ // 2) on a PC, switch the battery/power indicator to desktop mode,
291+ // can't control brightness for now and phone-on-desktop broken (FIXME)
292+ //
293+ // The rest of the indicators respect their default profile (which is "phone", even on desktop PCs)
294+ if ((new_indicator->identifier() == QStringLiteral("indicator-session") && m_platform.isMultiSession())
295+ || (new_indicator->identifier() == QStringLiteral("indicator-power") && m_platform.isPC())) {
296+ new_indicator->setProfile("desktop");
297+ } else {
284− new_indicator->setProfile(m_profile);
298+ new_indicator->setProfile(m_profile);
299+ }
300+
285 QObject::connect(this, &IndicatorsManager::profileChanged, new_indicator.data(), &Indicator::setProfile);
301 QObject::connect(this, &IndicatorsManager::profileChanged, new_indicator.data(), &Indicator::setProfile);
286 return new_indicator;
302 return new_indicator;
287}
303}
plugins/Unity/Indicators/indicatorsmanager.h+4−1
@@ -21,6 +21,7 @@
21
21
22#include "indicator.h"
22#include "indicator.h"
23#include "unityindicatorsglobal.h"
23#include "unityindicatorsglobal.h"
24+#include "../Platform/platform.h"
24
25
25#include <QObject>
26#include <QObject>
26#include <QFileSystemWatcher>
27#include <QFileSystemWatcher>
@@ -34,7 +35,7 @@ class UNITYINDICATORS_EXPORT IndicatorsManager : public QObject
34 Q_PROPERTY(bool loaded READ isLoaded NOTIFY loadedChanged)
35 Q_PROPERTY(bool loaded READ isLoaded NOTIFY loadedChanged)
35 Q_PROPERTY(QString profile READ profile WRITE setProfile NOTIFY profileChanged)
36 Q_PROPERTY(QString profile READ profile WRITE setProfile NOTIFY profileChanged)
36public:
37public:
37− explicit IndicatorsManager(QObject* parent = 0);
38+ explicit IndicatorsManager(QObject* parent = nullptr);
38 ~IndicatorsManager();
39 ~IndicatorsManager();
39
40
40 Q_INVOKABLE void load();
41 Q_INVOKABLE void load();
@@ -75,6 +76,8 @@ private:
75 QSharedPointer<QFileSystemWatcher> m_fsWatcher;
76 QSharedPointer<QFileSystemWatcher> m_fsWatcher;
76 bool m_loaded;
77 bool m_loaded;
77 QString m_profile;
78 QString m_profile;
79+
80+ Platform m_platform;
78};
81};
79
82
80#endif // INDICATORS_MANAGER_H
83#endif // INDICATORS_MANAGER_H
plugins/Unity/Indicators/indicatorsmodel.cpp+5−5
@@ -236,7 +236,7 @@ int IndicatorsModel::columnCount(const QModelIndex &) const
236 return 1;
236 return 1;
237}
237}
238
238
239−Q_INVOKABLE QVariant IndicatorsModel::data(int row, int role) const
239+QVariant IndicatorsModel::data(int row, int role) const
240{
240{
241 return data(index(row, 0), role);
241 return data(index(row, 0), role);
242}
242}
@@ -247,26 +247,26 @@ QVariant IndicatorsModel::data(const QModelIndex &index, int role) const
247 if (!index.isValid() || index.row() >= m_indicators.size())
247 if (!index.isValid() || index.row() >= m_indicators.size())
248 return QVariant();
248 return QVariant();
249
249
250− Indicator::Ptr indicator = m_indicators[index.row()];
250+ Indicator::Ptr indicator = m_indicators.at(index.row());
251
251
252 switch (role)
252 switch (role)
253 {
253 {
254 case IndicatorsModelRole::Identifier:
254 case IndicatorsModelRole::Identifier:
255 if (indicator)
255 if (indicator)
256 {
256 {
257− return QVariant(indicator->identifier());
257+ return indicator->identifier();
258 }
258 }
259 break;
259 break;
260 case IndicatorsModelRole::Position:
260 case IndicatorsModelRole::Position:
261 if (indicator)
261 if (indicator)
262 {
262 {
263− return QVariant(indicator->position());
263+ return indicator->position();
264 }
264 }
265 break;
265 break;
266 case IndicatorsModelRole::IndicatorProperties:
266 case IndicatorsModelRole::IndicatorProperties:
267 if (indicator)
267 if (indicator)
268 {
268 {
269− return QVariant(indicator->indicatorProperties());
269+ return indicator->indicatorProperties();
270 }
270 }
271 break;
271 break;
272 default:
272 default:
plugins/Unity/Indicators/indicatorsmodel.h+1−1
@@ -38,7 +38,7 @@ class UNITYINDICATORS_EXPORT IndicatorsModel : public QAbstractListModel
38
38
39public:
39public:
40
40
41− IndicatorsModel(QObject *parent=0);
41+ IndicatorsModel(QObject *parent=nullptr);
42 ~IndicatorsModel();
42 ~IndicatorsModel();
43
43
44 Q_INVOKABLE void load();
44 Q_INVOKABLE void load();
plugins/Unity/Indicators/menucontentactivator.h+1−1
@@ -34,7 +34,7 @@ public:
34 AbstractTimer(QObject *parent) : QObject(parent), m_isRunning(false) {}
34 AbstractTimer(QObject *parent) : QObject(parent), m_isRunning(false) {}
35 virtual int interval() const = 0;
35 virtual int interval() const = 0;
36 virtual void setInterval(int msecs) = 0;
36 virtual void setInterval(int msecs) = 0;
37− virtual void start() { m_isRunning = true; };
37+ virtual void start() { m_isRunning = true; }
38 virtual void stop() { m_isRunning = false; }
38 virtual void stop() { m_isRunning = false; }
39 bool isRunning() const { return m_isRunning; }
39 bool isRunning() const { return m_isRunning; }
40Q_SIGNALS:
40Q_SIGNALS:
plugins/Unity/Indicators/modelprinter.h+1−1
@@ -32,7 +32,7 @@ class ModelPrinter : public QObject
32 Q_PROPERTY(UnityMenuModel* model READ sourceModel WRITE setSourceModel NOTIFY modelChanged)
32 Q_PROPERTY(UnityMenuModel* model READ sourceModel WRITE setSourceModel NOTIFY modelChanged)
33 Q_PROPERTY(QString text READ text NOTIFY textChanged)
33 Q_PROPERTY(QString text READ text NOTIFY textChanged)
34public:
34public:
35− ModelPrinter(QObject* parent=0);
35+ ModelPrinter(QObject* parent=nullptr);
36
36
37 void setSourceModel(UnityMenuModel* sourceModel);
37 void setSourceModel(UnityMenuModel* sourceModel);
38 UnityMenuModel* sourceModel() const;
38 UnityMenuModel* sourceModel() const;
plugins/Unity/Platform/CMakeLists.txt+2
@@ -1,3 +1,5 @@
1+find_package(Qt5DBus REQUIRED)
2+
1set(platformplugin_SRCS
3set(platformplugin_SRCS
2 platform.cpp
4 platform.cpp
3 plugin.cpp)
5 plugin.cpp)
plugins/Unity/Platform/platform.cpp+13−4
@@ -20,16 +20,20 @@
20
20
21Platform::Platform(QObject *parent)
21Platform::Platform(QObject *parent)
22 : QObject(parent)
22 : QObject(parent)
23− , m_iface(QStringLiteral("org.freedesktop.hostname1"), QStringLiteral("/org/freedesktop/hostname1"), QStringLiteral("org.freedesktop.hostname1"),
24− QDBusConnection::systemBus(), this)
25{
23{
26 QMetaObject::invokeMethod(this, "init");
24 QMetaObject::invokeMethod(this, "init");
27}
25}
28
26
29void Platform::init()
27void Platform::init()
30{
28{
29+ QDBusInterface iface("org.freedesktop.hostname1", "/org/freedesktop/hostname1", "org.freedesktop.hostname1",
30+ QDBusConnection::systemBus(), this);
31+ QDBusInterface seatIface("org.freedesktop.login1", "/org/freedesktop/login1/seat/self", "org.freedesktop.login1.Seat",
32+ QDBusConnection::systemBus(), this);
33+
31− m_chassis = m_iface.property("Chassis").toString();
34+ m_chassis = iface.property("Chassis").toString();
32− m_isPC = (m_chassis == QLatin1String("desktop") || m_chassis == QLatin1String("laptop") || m_chassis == QLatin1String("server"));
35+ m_isPC = (m_chassis == "desktop" || m_chassis == "laptop" || m_chassis == "server");
36+ m_isMultiSession = seatIface.property("CanMultiSession").toBool() && seatIface.property("CanGraphical").toBool();
33}
37}
34
38
35QString Platform::chassis() const
39QString Platform::chassis() const
@@ -41,3 +45,8 @@ bool Platform::isPC() const
41{
45{
42 return m_isPC;
46 return m_isPC;
43}
47}
48+
49+bool Platform::isMultiSession() const
50+{
51+ return m_isMultiSession;
52+}
plugins/Unity/Platform/platform.h+7−1
@@ -38,6 +38,10 @@ class Platform: public QObject
38 * Whether the machine is an ordinary PC (desktop, laptop or server)
38 * Whether the machine is an ordinary PC (desktop, laptop or server)
39 */
39 */
40 Q_PROPERTY(bool isPC READ isPC CONSTANT)
40 Q_PROPERTY(bool isPC READ isPC CONSTANT)
41+ /**
42+ * Whether the system is capable of running multiple (graphical) sessions
43+ */
44+ Q_PROPERTY(bool isMultiSession READ isMultiSession CONSTANT)
41
45
42public:
46public:
43 Platform(QObject *parent = nullptr);
47 Platform(QObject *parent = nullptr);
@@ -46,13 +50,15 @@ public:
46 QString chassis() const;
50 QString chassis() const;
47 bool isPC() const;
51 bool isPC() const;
48
52
53+ bool isMultiSession() const;
54+
49private Q_SLOTS:
55private Q_SLOTS:
50 void init();
56 void init();
51
57
52private:
58private:
53− QDBusInterface m_iface;
54 QString m_chassis;
59 QString m_chassis;
55 bool m_isPC;
60 bool m_isPC;
61+ bool m_isMultiSession;
56};
62};
57
63
58#endif // PLATFORM_H
64#endif // PLATFORM_H
qml/Components/VolumeControl.qml+2−2
@@ -36,7 +36,7 @@ Item {
36 GlobalShortcut {
36 GlobalShortcut {
37 id: muteShortcut
37 id: muteShortcut
38 shortcut: Qt.Key_VolumeMute
38 shortcut: Qt.Key_VolumeMute
39− Keys.onPressed: toggleMute()
39+ onTriggered: toggleMute()
40 }
40 }
41
41
42 QMenuModel.QDBusActionGroup {
42 QMenuModel.QDBusActionGroup {
@@ -46,7 +46,7 @@ Item {
46 objectPath: "/com/canonical/indicator/sound"
46 objectPath: "/com/canonical/indicator/sound"
47
47
48 property variant actionObject: action("volume")
48 property variant actionObject: action("volume")
49− property variant muteActionObject: action("mute")
49+ property variant muteActionObject: indicators.indicatorsModel.profile === "desktop" ? action("mute") : action("silent-mode")
50 property variant indicatorsAction: action("indicator-shown")
50 property variant indicatorsAction: action("indicator-shown")
51 }
51 }
52
52
qml/Shell.qml+2−2
@@ -516,7 +516,7 @@ Item {
516
516
517 indicatorsModel: Indicators.IndicatorsModel {
517 indicatorsModel: Indicators.IndicatorsModel {
518 // tablet and phone both use the same profile
518 // tablet and phone both use the same profile
519− profile: shell.usageScenario === "desktop" ? "desktop" : "phone"
519+ profile: "phone"
520 Component.onCompleted: load();
520 Component.onCompleted: load();
521 }
521 }
522 }
522 }
@@ -525,7 +525,7 @@ Item {
525 greeterShown: greeter.shown
525 greeterShown: greeter.shown
526 }
526 }
527
527
528− property bool topmostApplicationIsFullscreen:
528+ readonly property bool topmostApplicationIsFullscreen:
529 ApplicationManager.focusedApplicationId &&
529 ApplicationManager.focusedApplicationId &&
530 ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
530 ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
531
531
tests/plugins/Unity/Indicators/CMakeLists.txt+1−1
@@ -21,7 +21,7 @@ macro(indicator_test TEST)
21 ${TEST}Test.cpp
21 ${TEST}Test.cpp
22 ${test_ADDITIONAL_CPPS}
22 ${test_ADDITIONAL_CPPS}
23 )
23 )
24− qt5_use_modules(${TEST}Exec Test Core Qml)
24+ qt5_use_modules(${TEST}Exec Test Core Qml DBus)
25 target_link_libraries(${TEST}Exec
25 target_link_libraries(${TEST}Exec
26 ${test_ADDITIONAL_LIBS}
26 ${test_ADDITIONAL_LIBS}
27 ${GLIB_LIBRARIES}
27 ${GLIB_LIBRARIES}